• 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_info_filter.h"
22 #include "form_instance.h"
23 #include "form_instances_filter.h"
24 #include "form_callback_interface.h"
25 #include "form_host_client.h"
26 #include "form_mgr.h"
27 #include "form_mgr_errors.h"
28 #include "ipc_skeleton.h"
29 #include "js_runtime.h"
30 #include "js_runtime_utils.h"
31 #include "napi_common_data.h"
32 #include "napi_form_util.h"
33 #include "napi/native_api.h"
34 #include "napi/native_node_api.h"
35 #include "napi_common_util.h"
36 #include "napi_common_want.h"
37 #include "runtime.h"
38 #include "tokenid_kit.h"
39 
40 namespace OHOS {
41 namespace AbilityRuntime {
42 using namespace OHOS;
43 using namespace OHOS::AAFwk;
44 using namespace OHOS::AppExecFwk;
45 
46 namespace {
47     constexpr int REF_COUNT = 1;
48     // NANOSECONDS mean 10^9 nano second
49     constexpr int64_t NANOSECONDS = 1000000000;
50     // MICROSECONDS mean 10^6 millias second
51     constexpr int64_t MICROSECONDS = 1000000;
52     constexpr int32_t INVALID_FORM_LOCATION = -2;
53     constexpr int32_t INVALID_FORM_RESULT_ERRCODE = -2;
54     const std::string FORM_UNINSTALL = "formUninstall";
55     const std::string FORM_OVERFLOW = "formOverflow";
56     const std::string CHANGE_SCENE_ANIMATION_STATE = "changeSceneAnimationState";
57     const std::string GET_FORM_RECT = "getFormRect";
58     const std::string GET_LIVE_FORM_STATUS = "getLiveFormStatus";
59     const std::set<std::string> FORM_LISTENER_TYPE = {
60         FORM_UNINSTALL, FORM_OVERFLOW, CHANGE_SCENE_ANIMATION_STATE, GET_FORM_RECT, GET_LIVE_FORM_STATUS
61     };
62     constexpr int32_t CALL_INRTERFACE_TIMEOUT_MILLS = 10;
63 }
64 
SystemTimeMillis()65 int64_t SystemTimeMillis() noexcept
66 {
67     struct timespec t;
68     t.tv_sec = 0;
69     t.tv_nsec = 0;
70     clock_gettime(CLOCK_MONOTONIC, &t);
71     return static_cast<int64_t>(((t.tv_sec) * NANOSECONDS + t.tv_nsec) / MICROSECONDS);
72 }
73 
74 class ShareFormCallBackClient : public ShareFormCallBack,
75                                 public std::enable_shared_from_this<ShareFormCallBackClient> {
76 public:
77     using ShareFormTask = std::function<void(int32_t)>;
ShareFormCallBackClient(ShareFormTask && task)78     explicit ShareFormCallBackClient(ShareFormTask &&task) : task_(std::move(task))
79     {
80         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
81     }
82 
83     virtual ~ShareFormCallBackClient() = default;
84 
ProcessShareFormResponse(int32_t result)85     void ProcessShareFormResponse(int32_t result) override
86     {
87         if (handler_) {
88             handler_->PostSyncTask([client = shared_from_this(), result] () {
89                 client->task_(result);
90             });
91         }
92     }
93 
94 private:
95     ShareFormTask task_;
96     std::shared_ptr<AppExecFwk::EventHandler> handler_;
97 };
98 
99 class FormUninstallCallbackClient : public std::enable_shared_from_this<FormUninstallCallbackClient> {
100 public:
FormUninstallCallbackClient(napi_env env,napi_ref callbackRef)101     FormUninstallCallbackClient(napi_env env, napi_ref callbackRef) : callbackRef_(callbackRef), env_(env)
102     {
103         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
104     }
105 
~FormUninstallCallbackClient()106     virtual ~FormUninstallCallbackClient()
107     {
108         napi_delete_reference(env_, callbackRef_);
109     }
110 
ProcessFormUninstall(const int64_t formId)111     void ProcessFormUninstall(const int64_t formId)
112     {
113         if (handler_ == nullptr) {
114             HILOG_INFO("null handler");
115             return;
116         }
117         handler_->PostSyncTask([thisWeakPtr = weak_from_this(), formId]() {
118             auto sharedThis = thisWeakPtr.lock();
119             if (sharedThis == nullptr) {
120                 HILOG_ERROR("null sharedThis");
121                 return;
122             }
123             HILOG_DEBUG("task complete formId:%{public}" PRId64 ".", formId);
124             std::string formIdString = std::to_string(formId);
125             napi_value callbackValues;
126             napi_create_string_utf8(sharedThis->env_, formIdString.c_str(), NAPI_AUTO_LENGTH, &callbackValues);
127             napi_value callResult;
128             napi_value myCallback = nullptr;
129             napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
130             if (myCallback != nullptr) {
131                 napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_ONE, &callbackValues, &callResult);
132             }
133         });
134     }
135 
IsStrictEqual(napi_value callback)136     bool IsStrictEqual(napi_value callback)
137     {
138         bool isEqual = false;
139         napi_value myCallback = nullptr;
140         napi_get_reference_value(env_, callbackRef_, &myCallback);
141         napi_strict_equals(env_, myCallback, callback, &isEqual);
142         HILOG_INFO("isStrictEqual = %{public}d", isEqual);
143         return isEqual;
144     }
145 
146 private:
147     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
148     napi_ref callbackRef_ {};
149     napi_env env_;
150 };
151 
152 class JsFormStateCallbackClient : public FormStateCallbackInterface,
153                                   public std::enable_shared_from_this<JsFormStateCallbackClient> {
154 public:
155     using AcquireFormStateTask = std::function<void(int32_t, Want)>;
JsFormStateCallbackClient(AcquireFormStateTask && task)156     explicit JsFormStateCallbackClient(AcquireFormStateTask &&task) : task_(std::move(task))
157     {
158         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
159     }
160 
161     virtual ~JsFormStateCallbackClient() = default;
162 
ProcessAcquireState(FormState state)163     void ProcessAcquireState(FormState state) override
164     {
165         if (handler_) {
166             handler_->PostSyncTask([client = shared_from_this(), state] () {
167                 client->task_(static_cast<int32_t>(state), client->want_);
168             });
169         }
170     }
171 
SetWant(const Want want)172     void SetWant(const Want want)
173     {
174         want_ = want;
175     }
176 private:
177     Want want_;
178     AcquireFormStateTask task_;
179     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
180 };
181 
182 class JsFormDataCallbackClient : public FormDataCallbackInterface,
183                                  public std::enable_shared_from_this<JsFormDataCallbackClient> {
184 public:
185     using AcquireFormDataTask = std::function<void(AAFwk::WantParams data)>;
JsFormDataCallbackClient(AcquireFormDataTask && task)186     explicit JsFormDataCallbackClient(AcquireFormDataTask &&task) : task_(std::move(task))
187     {
188         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
189     }
190 
191     virtual ~JsFormDataCallbackClient() = default;
192 
ProcessAcquireFormData(AAFwk::WantParams data)193     void ProcessAcquireFormData(AAFwk::WantParams data) override
194     {
195         if (handler_) {
196             handler_->PostSyncTask([client = shared_from_this(), data] () {
197                 client->task_(data);
198             });
199         }
200     }
201 private:
202     AcquireFormDataTask task_;
203     std::shared_ptr<AppExecFwk::EventHandler> handler_ = nullptr;
204 };
205 
206 std::map<napi_ref, std::shared_ptr<FormUninstallCallbackClient>> g_formUninstallCallbackMap {};
207 std::mutex g_formUninstallCallbackMapMutex_;
208 
FormUninstallCallback(const std::vector<int64_t> & formIds)209 void FormUninstallCallback(const std::vector<int64_t> &formIds)
210 {
211     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
212     for (auto &iter : g_formUninstallCallbackMap) {
213         for (int64_t formId : formIds) {
214             iter.second->ProcessFormUninstall(formId);
215         }
216     }
217 }
218 
AddFormUninstallCallback(napi_env env,napi_value callback)219 bool AddFormUninstallCallback(napi_env env, napi_value callback)
220 {
221     HILOG_DEBUG("start");
222     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
223     for (auto &iter : g_formUninstallCallbackMap) {
224         if (iter.second->IsStrictEqual(callback)) {
225             HILOG_ERROR("found equal callback");
226             return false;
227         }
228     }
229 
230     napi_ref callbackRef;
231     napi_create_reference(env, callback, REF_COUNT, &callbackRef);
232     std::shared_ptr<FormUninstallCallbackClient> callbackClient = std::make_shared<FormUninstallCallbackClient>(env,
233         callbackRef);
234 
235     auto ret = g_formUninstallCallbackMap.emplace(callbackRef, callbackClient);
236     if (!ret.second) {
237         HILOG_ERROR("fail emplace callback");
238         return false;
239     }
240     return true;
241 }
242 
DelFormUninstallCallback(napi_value callback)243 bool DelFormUninstallCallback(napi_value callback)
244 {
245     HILOG_DEBUG("start");
246     int32_t count = 0;
247     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
248     for (auto iter = g_formUninstallCallbackMap.begin(); iter != g_formUninstallCallbackMap.end();) {
249         if (iter->second->IsStrictEqual(callback)) {
250             HILOG_INFO("found equal callback");
251             iter = g_formUninstallCallbackMap.erase(iter);
252             count++;
253         } else {
254             iter++;
255         }
256     }
257     HILOG_INFO("%{public}d form uninstall callback canceled.", count);
258     return true;
259 }
260 
ClearFormUninstallCallback()261 bool ClearFormUninstallCallback()
262 {
263     std::lock_guard<std::mutex> lock(g_formUninstallCallbackMapMutex_);
264     g_formUninstallCallbackMap.clear();
265     return true;
266 }
267 
268 class JsFormHost {
269 public:
270     JsFormHost() = default;
271     ~JsFormHost() = default;
272 
Finalizer(napi_env env,void * data,void * hint)273     static void Finalizer(napi_env env, void* data, void* hint)
274     {
275         HILOG_INFO("call");
276         std::unique_ptr<JsFormHost>(static_cast<JsFormHost*>(data));
277     }
278 
AddForm(napi_env env,napi_callback_info info)279     static napi_value AddForm(napi_env env, napi_callback_info info)
280     {
281         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAddForm);
282     }
283 
DeleteForm(napi_env env,napi_callback_info info)284     static napi_value DeleteForm(napi_env env, napi_callback_info info)
285     {
286         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDeleteForm);
287     }
288 
ReleaseForm(napi_env env,napi_callback_info info)289     static napi_value ReleaseForm(napi_env env, napi_callback_info info)
290     {
291         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnReleaseForm);
292     }
293 
RequestForm(napi_env env,napi_callback_info info)294     static napi_value RequestForm(napi_env env, napi_callback_info info)
295     {
296         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRequestForm);
297     }
298 
RequestFormWithParams(napi_env env,napi_callback_info info)299     static napi_value RequestFormWithParams(napi_env env, napi_callback_info info)
300     {
301         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRequestFormWithParams);
302     }
303 
CastTempForm(napi_env env,napi_callback_info info)304     static napi_value CastTempForm(napi_env env, napi_callback_info info)
305     {
306         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnCastTempForm);
307     }
308 
NotifyVisibleForms(napi_env env,napi_callback_info info)309     static napi_value NotifyVisibleForms(napi_env env, napi_callback_info info)
310     {
311         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyVisibleForms);
312     }
313 
NotifyInvisibleForms(napi_env env,napi_callback_info info)314     static napi_value NotifyInvisibleForms(napi_env env, napi_callback_info info)
315     {
316         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyInvisibleForms);
317     }
318 
EnableFormsUpdate(napi_env env,napi_callback_info info)319     static napi_value EnableFormsUpdate(napi_env env, napi_callback_info info)
320     {
321         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnEnableFormsUpdate);
322     }
323 
DisableFormsUpdate(napi_env env,napi_callback_info info)324     static napi_value DisableFormsUpdate(napi_env env, napi_callback_info info)
325     {
326         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDisableFormsUpdate);
327     }
328 
IsSystemReady(napi_env env,napi_callback_info info)329     static napi_value IsSystemReady(napi_env env, napi_callback_info info)
330     {
331         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnIsSystemReady);
332     }
333 
DeleteInvalidForms(napi_env env,napi_callback_info info)334     static napi_value DeleteInvalidForms(napi_env env, napi_callback_info info)
335     {
336         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnDeleteInvalidForms);
337     }
338 
AcquireFormState(napi_env env,napi_callback_info info)339     static napi_value AcquireFormState(napi_env env, napi_callback_info info)
340     {
341         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAcquireFormState);
342     }
343 
RegisterFormObserver(napi_env env,napi_callback_info info)344     static napi_value RegisterFormObserver(napi_env env, napi_callback_info info)
345     {
346         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRegisterFormObserver);
347     }
348 
UnregisterFormObserver(napi_env env,napi_callback_info info)349     static napi_value UnregisterFormObserver(napi_env env, napi_callback_info info)
350     {
351         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUnregisterFormObserver);
352     }
353 
NotifyFormsVisible(napi_env env,napi_callback_info info)354     static napi_value NotifyFormsVisible(napi_env env, napi_callback_info info)
355     {
356         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsVisible);
357     }
358 
NotifyFormsEnableUpdate(napi_env env,napi_callback_info info)359     static napi_value NotifyFormsEnableUpdate(napi_env env, napi_callback_info info)
360     {
361         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsEnableUpdate);
362     }
363 
GetAllFormsInfo(napi_env env,napi_callback_info info)364     static napi_value GetAllFormsInfo(napi_env env, napi_callback_info info)
365     {
366         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnGetAllFormsInfo);
367     }
368 
GetFormsInfo(napi_env env,napi_callback_info info)369     static napi_value GetFormsInfo(napi_env env, napi_callback_info info)
370     {
371         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnGetFormsInfo);
372     }
373 
ShareForm(napi_env env,napi_callback_info info)374     static napi_value ShareForm(napi_env env, napi_callback_info info)
375     {
376         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnShareForm);
377     }
378 
AcquireFormData(napi_env env,napi_callback_info info)379     static napi_value AcquireFormData(napi_env env, napi_callback_info info)
380     {
381         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnAcquireFormData);
382     }
383 
SetRouterProxy(napi_env env,napi_callback_info info)384     static napi_value SetRouterProxy(napi_env env, napi_callback_info info)
385     {
386         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetRouterProxy);
387     }
388 
ClearRouterProxy(napi_env env,napi_callback_info info)389     static napi_value ClearRouterProxy(napi_env env, napi_callback_info info)
390     {
391         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnClearRouterProxy);
392     }
393 
NotifyFormsPrivacyProtected(napi_env env,napi_callback_info info)394     static napi_value NotifyFormsPrivacyProtected(napi_env env, napi_callback_info info)
395     {
396         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnNotifyFormsPrivacyProtected);
397     }
398 
SetFormsRecyclable(napi_env env,napi_callback_info info)399     static napi_value SetFormsRecyclable(napi_env env, napi_callback_info info)
400     {
401         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetFormsRecyclable);
402     }
403 
RecoverForms(napi_env env,napi_callback_info info)404     static napi_value RecoverForms(napi_env env, napi_callback_info info)
405     {
406         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRecoverForms);
407     }
408 
RecycleForms(napi_env env,napi_callback_info info)409     static napi_value RecycleForms(napi_env env, napi_callback_info info)
410     {
411         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnRecycleForms);
412     }
413 
UpdateFormLocation(napi_env env,napi_callback_info info)414     static napi_value UpdateFormLocation(napi_env env, napi_callback_info info)
415     {
416         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUpdateFormLocation);
417     }
418 
SetPublishFormResult(napi_env env,napi_callback_info info)419     static napi_value SetPublishFormResult(napi_env env, napi_callback_info info)
420     {
421         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnSetPublishFormResult);
422     }
423 
UpdateFormLockedState(napi_env env,napi_callback_info info)424     static napi_value UpdateFormLockedState(napi_env env, napi_callback_info info)
425     {
426         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUpdateFormLockedState);
427     }
428 
UpdateFormSize(napi_env env,napi_callback_info info)429     static napi_value UpdateFormSize(napi_env env, napi_callback_info info)
430     {
431         GET_CB_INFO_AND_CALL(env, info, JsFormHost, OnUpdateFormSize);
432     }
433 
434 private:
CheckCallerIsSystemApp()435     bool CheckCallerIsSystemApp()
436     {
437         auto selfToken = IPCSkeleton::GetSelfTokenID();
438         return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken);
439     }
440 
ConvertFromId(napi_env env,napi_value jsValue,int64_t & formId)441     static bool ConvertFromId(napi_env env, napi_value jsValue, int64_t &formId)
442     {
443         std::string strFormId;
444         if (!ConvertFromJsValue(env, jsValue, strFormId)) {
445             HILOG_ERROR("convert strFormId failed");
446             return false;
447         }
448 
449         if (strFormId.empty()) {
450             HILOG_ERROR("empty strFormId");
451             return false;
452         }
453 
454         if (!ConvertStringToInt64(strFormId, formId)) {
455             HILOG_ERROR("convert string formId to int64 failed");
456             return false;
457         }
458         return true;
459     }
460 
GetStringsValue(napi_env env,napi_value array,std::vector<std::string> & strList)461     bool GetStringsValue(napi_env env, napi_value array, std::vector<std::string> &strList)
462     {
463         napi_valuetype paramType = napi_undefined;
464         napi_typeof(env, array, &paramType);
465         if (paramType == napi_undefined || paramType == napi_null) {
466             HILOG_ERROR("input array is napi_undefined or napi_null");
467             return false;
468         }
469         uint32_t nativeArrayLen = 0;
470         napi_get_array_length(env, array, &nativeArrayLen);
471         napi_value element = nullptr;
472 
473         for (uint32_t i = 0; i < nativeArrayLen; i++) {
474             std::string itemStr("");
475             napi_get_element(env, array, i, &element);
476             if (!ConvertFromJsValue(env, element, itemStr)) {
477                 HILOG_ERROR("GetElement from to array [%{public}u] error", i);
478                 return false;
479             }
480             strList.push_back(itemStr);
481         }
482 
483         return true;
484     }
485 
ConvertFromIds(napi_env env,napi_value jsValue,std::vector<int64_t> & formIds)486     bool ConvertFromIds(napi_env env, napi_value jsValue, std::vector<int64_t> &formIds)
487     {
488         std::vector<string> strFormIdList;
489         if (!GetStringsValue(env, jsValue, strFormIdList)) {
490             HILOG_ERROR("convert strFormIdList failed");
491             return false;
492         }
493 
494         for (size_t i = 0; i < strFormIdList.size(); i++) {
495             int64_t formIdValue;
496             if (!ConvertStringToInt64(strFormIdList[i], formIdValue)) {
497                 HILOG_ERROR("convert formIdValue failed");
498                 return false;
499             }
500             formIds.push_back(formIdValue);
501         }
502         return true;
503     }
504 
ConvertDeviceId(napi_env env,napi_value jsValue,std::string & deviceId)505     bool ConvertDeviceId(napi_env env, napi_value jsValue, std::string &deviceId)
506     {
507         if (!ConvertFromJsValue(env, jsValue, deviceId)) {
508             HILOG_ERROR("convert deviceId failed");
509             return false;
510         }
511 
512         if (deviceId.empty()) {
513             HILOG_ERROR("empty deviceId");
514             return false;
515         }
516 
517         return true;
518     }
519 
ParseParameter(napi_env env,napi_value * argv,int32_t & formErrorCode,std::string & messageInfo)520     bool ParseParameter(napi_env env, napi_value *argv, int32_t &formErrorCode, std::string &messageInfo)
521     {
522         napi_valuetype param1Type = napi_undefined;
523         napi_typeof(env, argv[1], &param1Type);
524         if (param1Type != napi_object) {
525             HILOG_ERROR("result not napi_object");
526             return false;
527         }
528         napi_value publishFormErrorCode = nullptr;
529         napi_status codeRet = napi_get_named_property(env, argv[1], "code", &publishFormErrorCode);
530         napi_value message = nullptr;
531         napi_status messageRet = napi_get_named_property(env, argv[1], "message", &message);
532         if (codeRet != napi_ok || messageRet != napi_ok) {
533             HILOG_ERROR("get property failed");
534             return false;
535         }
536         messageInfo = GetStringFromNapi(env, message);
537         if (napi_get_value_int32(env, publishFormErrorCode, &formErrorCode) != napi_ok) {
538             HILOG_ERROR("PublishFormErrorCode not number");
539             return false;
540         }
541         if (formErrorCode < static_cast<int32_t>(Constants::PublishFormErrorCode::SUCCESS) ||
542                 formErrorCode > static_cast<int32_t>(Constants::PublishFormErrorCode::INTERNAL_ERROR)) {
543             HILOG_ERROR("PublishFormResult is convert fail");
544             return false;
545         }
546         return true;
547     }
548 
OnAddForm(napi_env env,size_t argc,napi_value * argv)549     napi_value OnAddForm(napi_env env, size_t argc, napi_value* argv)
550     {
551         HILOG_INFO("call");
552 
553         if (argc != ARGS_ONE) {
554             HILOG_ERROR("invalid argc");
555             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
556             return CreateJsUndefined(env);
557         }
558 
559         Want want;
560         if (!UnwrapWant(env, argv[PARAM0], want)) {
561             HILOG_ERROR("UnwrapWant failed");
562             NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
563             return CreateJsUndefined(env);
564         }
565 
566         std::shared_ptr<AppExecFwk::RunningFormInfo> runningFormInfo =
567             std::make_shared<AppExecFwk::RunningFormInfo>();
568         auto apiResult = std::make_shared<int32_t>();
569         NapiAsyncTask::ExecuteCallback execute = [want, runningFormInfo, ret = apiResult]() {
570             *ret = FormMgr::GetInstance().CreateForm(want, *runningFormInfo);
571         };
572 
573         NapiAsyncTask::CompleteCallback complete = [runningFormInfo, ret = apiResult](napi_env env,
574             NapiAsyncTask &task, int32_t status) {
575             HILOG_INFO("ret:%{public}d,formId:%{public}" PRId64, *ret, runningFormInfo->formId);
576             if (*ret == ERR_OK) {
577                 task.ResolveWithNoError(env, CreateRunningFormInfo(env, *runningFormInfo));
578             } else {
579                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
580             }
581         };
582 
583         napi_value result = nullptr;
584         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnAddForm",
585             env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
586         return result;
587     }
588 
OnDeleteForm(napi_env env,size_t argc,napi_value * argv)589     napi_value OnDeleteForm(napi_env env, size_t argc, napi_value* argv)
590     {
591         HILOG_DEBUG("call");
592         if (argc > ARGS_TWO || argc < ARGS_ONE) {
593             HILOG_ERROR("OnDeleteForm invalid argc");
594             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
595             return CreateJsUndefined(env);
596         }
597 
598         decltype(argc) convertArgc = 0;
599         int64_t formId = 0;
600         if (!ConvertFromId(env, argv[PARAM0], formId)) {
601             HILOG_ERROR("OnDeleteForm invalid formId");
602             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
603             return CreateJsUndefined(env);
604         }
605         convertArgc++;
606 
607         auto apiResult = std::make_shared<int32_t>();
608         NapiAsyncTask::ExecuteCallback execute = [formId, ret = apiResult]() {
609             *ret = FormMgr::GetInstance().DeleteForm(formId, FormHostClient::GetInstance());
610         };
611 
612         NapiAsyncTask::CompleteCallback complete = [formId, ret = apiResult](napi_env env,
613             NapiAsyncTask &task, int32_t status) {
614             HILOG_WARN("deleteForm ret:%{public}d,formId:%{public}" PRId64, *ret, formId);
615             if (*ret == ERR_OK) {
616                 task.ResolveWithNoError(env, CreateJsUndefined(env));
617             } else {
618                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
619             }
620         };
621 
622         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
623         napi_value result = nullptr;
624         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnDeleteForm",
625             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
626         return result;
627     }
628 
OnReleaseForm(napi_env env,size_t argc,napi_value * argv)629     napi_value OnReleaseForm(napi_env env, size_t argc, napi_value* argv)
630     {
631         HILOG_DEBUG("call");
632 
633         if (argc > ARGS_THREE || argc < ARGS_ONE) {
634             HILOG_ERROR("OnReleaseForm invalid argc");
635             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
636             return CreateJsUndefined(env);
637         }
638 
639         decltype(argc) convertArgc = 0;
640         int64_t formId = 0;
641         if (!ConvertFromId(env, argv[PARAM0], formId)) {
642             HILOG_ERROR("invalid formId");
643             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
644             return CreateJsUndefined(env);
645         }
646         convertArgc++;
647 
648         bool isReleaseCache = false;
649         if ((argc == ARGS_TWO || argc == ARGS_THREE) && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
650             if (!ConvertFromJsValue(env, argv[PARAM1], isReleaseCache)) {
651                 HILOG_ERROR("convert isReleaseCache failed");
652                 NapiFormUtil::ThrowParamTypeError(env, "isReleaseCache", "boolean");
653                 return CreateJsUndefined(env);
654             }
655             convertArgc++;
656         }
657 
658         NapiAsyncTask::CompleteCallback complete = [formId, isReleaseCache]
659             (napi_env env, NapiAsyncTask &task, int32_t status) {
660             auto ret = FormMgr::GetInstance().ReleaseForm(formId, FormHostClient::GetInstance(), isReleaseCache);
661             if (ret == ERR_OK) {
662                 task.ResolveWithNoError(env, CreateJsUndefined(env));
663             } else {
664                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
665             }
666         };
667 
668         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
669         napi_value result = nullptr;
670         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnReleaseForm",
671             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
672         return result;
673     }
674 
OnRequestForm(napi_env env,size_t argc,napi_value * argv)675     napi_value OnRequestForm(napi_env env, size_t argc, napi_value* argv)
676     {
677         HILOG_DEBUG("call");
678 
679         if (argc > ARGS_TWO || argc < ARGS_ONE) {
680             HILOG_ERROR("invalid argc");
681             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
682             return CreateJsUndefined(env);
683         }
684 
685         decltype(argc) convertArgc = 0;
686         int64_t formId = 0;
687         if (!ConvertFromId(env, argv[PARAM0], formId)) {
688             HILOG_ERROR("invalid formId");
689             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
690             return CreateJsUndefined(env);
691         }
692         convertArgc++;
693 
694         NapiAsyncTask::CompleteCallback complete = [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
695             Want want;
696             auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
697             if (ret == ERR_OK) {
698                 task.ResolveWithNoError(env, CreateJsUndefined(env));
699             } else {
700                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
701             }
702         };
703 
704         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
705         napi_value result = nullptr;
706         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRequestForm",
707             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
708         return result;
709     }
710 
OnRequestFormWithParams(napi_env env,size_t argc,napi_value * argv)711     napi_value OnRequestFormWithParams(napi_env env, size_t argc, napi_value* argv)
712     {
713         HILOG_DEBUG("call");
714 
715         if (argc > ARGS_TWO || argc < ARGS_ONE) {
716             HILOG_ERROR("invalid argc");
717             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
718             return CreateJsUndefined(env);
719         }
720 
721         decltype(argc) convertArgc = 0;
722         int64_t formId = 0;
723         if (!ConvertFromId(env, argv[PARAM0], formId)) {
724             HILOG_ERROR("invalid formId");
725             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
726             return CreateJsUndefined(env);
727         }
728         convertArgc++;
729 
730         if (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_object)) {
731             HILOG_ERROR("invalid secondInputParam");
732             NapiFormUtil::ThrowParamTypeError(env, "wantParams", "object");
733             return CreateJsUndefined(env);
734         }
735 
736         Want want;
737         AAFwk::WantParams wantParams;
738         if (UnwrapWantParams(env, argv[PARAM1], wantParams)) {
739             want.SetParams(wantParams);
740         }
741         convertArgc++;
742 
743         NapiAsyncTask::CompleteCallback complete = [formId, want](napi_env env, NapiAsyncTask &task, int32_t status) {
744             auto ret = FormMgr::GetInstance().RequestForm(formId, FormHostClient::GetInstance(), want);
745             if (ret == ERR_OK) {
746                 task.ResolveWithNoError(env, CreateJsUndefined(env));
747             } else {
748                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
749             }
750         };
751 
752         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
753         napi_value result = nullptr;
754         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRequestFormWithParams",
755             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
756         return result;
757     }
758 
OnCastTempForm(napi_env env,size_t argc,napi_value * argv)759     napi_value OnCastTempForm(napi_env env, size_t argc, napi_value* argv)
760     {
761         HILOG_DEBUG("call");
762 
763         if (argc > ARGS_TWO || argc < ARGS_ONE) {
764             HILOG_ERROR("invalid argc");
765             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
766             return CreateJsUndefined(env);
767         }
768 
769         decltype(argc) convertArgc = 0;
770         int64_t formId = 0;
771         if (!ConvertFromId(env, argv[PARAM0], formId)) {
772             HILOG_ERROR("invalid formId");
773             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
774             return CreateJsUndefined(env);
775         }
776         convertArgc++;
777 
778         NapiAsyncTask::CompleteCallback complete = [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
779             auto ret = FormMgr::GetInstance().CastTempForm(formId, FormHostClient::GetInstance());
780             if (ret == ERR_OK) {
781                 task.ResolveWithNoError(env, CreateJsUndefined(env));
782             } else {
783                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
784             }
785         };
786 
787         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
788         napi_value result = nullptr;
789         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnCastTempForm",
790             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
791         return result;
792     }
793 
OnNotifyVisibleForms(napi_env env,size_t argc,napi_value * argv)794     napi_value OnNotifyVisibleForms(napi_env env, size_t argc, napi_value* argv)
795     {
796         HILOG_DEBUG("call");
797 
798         if (argc > ARGS_TWO || argc < ARGS_ONE) {
799             HILOG_ERROR("invalid argc");
800             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
801             return CreateJsUndefined(env);
802         }
803 
804         decltype(argc) convertArgc = 0;
805         std::vector<int64_t> formIds;
806         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
807             HILOG_ERROR("invalid formIdList");
808             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
809             return CreateJsUndefined(env);
810         }
811         convertArgc++;
812 
813         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
814             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
815                 Constants::FORM_VISIBLE);
816             if (ret == ERR_OK) {
817                 task.ResolveWithNoError(env, CreateJsUndefined(env));
818             } else {
819                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
820             }
821         };
822 
823         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
824         napi_value result = nullptr;
825         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
826             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
827         return result;
828         HILOG_DEBUG("OnNotifyVisibleForms end");
829     }
830 
OnNotifyInvisibleForms(napi_env env,size_t argc,napi_value * argv)831     napi_value OnNotifyInvisibleForms(napi_env env, size_t argc, napi_value* argv)
832     {
833         HILOG_DEBUG("call");
834 
835         if (argc > ARGS_TWO || argc < ARGS_ONE) {
836             HILOG_ERROR("invalid argc");
837             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
838             return CreateJsUndefined(env);
839         }
840 
841         decltype(argc) convertArgc = 0;
842         std::vector<int64_t> formIds;
843         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
844             HILOG_ERROR("invalid formIdList");
845             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
846             return CreateJsUndefined(env);
847         }
848         convertArgc++;
849 
850         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
851             auto ret = FormMgr::GetInstance().NotifyWhetherVisibleForms(formIds, FormHostClient::GetInstance(),
852                 Constants::FORM_INVISIBLE);
853             if (ret == ERR_OK) {
854                 task.ResolveWithNoError(env, CreateJsUndefined(env));
855             } else {
856                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
857             }
858         };
859 
860         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
861         napi_value result = nullptr;
862         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
863             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
864         return result;
865         HILOG_DEBUG("OnNotifyInvisibleForms end");
866     }
867 
OnEnableFormsUpdate(napi_env env,size_t argc,napi_value * argv)868     napi_value OnEnableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
869     {
870         HILOG_DEBUG("call");
871 
872         if (argc > ARGS_TWO || argc < ARGS_ONE) {
873             HILOG_ERROR("invalid argc");
874             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
875             return CreateJsUndefined(env);
876         }
877 
878         decltype(argc) convertArgc = 0;
879         std::vector<int64_t> formIds;
880         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
881             HILOG_ERROR("invalid formIdList");
882             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
883             return CreateJsUndefined(env);
884         }
885         convertArgc++;
886 
887         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
888             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), true);
889             if (ret == ERR_OK) {
890                 task.ResolveWithNoError(env, CreateJsUndefined(env));
891             } else {
892                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
893             }
894         };
895 
896         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
897         napi_value result = nullptr;
898         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
899             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
900         return result;
901         HILOG_DEBUG("OnEnableFormsUpdate end");
902     }
903 
OnDisableFormsUpdate(napi_env env,size_t argc,napi_value * argv)904     napi_value OnDisableFormsUpdate(napi_env env, size_t argc, napi_value* argv)
905     {
906         HILOG_DEBUG("call");
907 
908         if (argc > ARGS_TWO || argc < ARGS_ONE) {
909             HILOG_ERROR("invalid argc");
910             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
911             return CreateJsUndefined(env);
912         }
913 
914         decltype(argc) convertArgc = 0;
915         std::vector<int64_t> iFormIds;
916         if (!ConvertFromIds(env, argv[PARAM0], iFormIds)) {
917             HILOG_ERROR("invalid formIdList");
918             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
919             return CreateJsUndefined(env);
920         }
921         convertArgc++;
922 
923         auto complete = [formIds = iFormIds](napi_env env, NapiAsyncTask &task, int32_t status) {
924             auto ret = FormMgr::GetInstance().LifecycleUpdate(formIds, FormHostClient::GetInstance(), false);
925             if (ret != ERR_OK) {
926                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
927                 return;
928             }
929             task.ResolveWithNoError(env, CreateJsUndefined(env));
930         };
931 
932         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
933         napi_value result = nullptr;
934         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnDisableFormsUpdate",
935             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
936         return result;
937     }
938 
OnIsSystemReady(napi_env env,size_t argc,napi_value * argv)939     napi_value OnIsSystemReady(napi_env env, size_t argc, napi_value* argv)
940     {
941         HILOG_DEBUG("call");
942 
943         if (!CheckCallerIsSystemApp()) {
944             HILOG_ERROR("the app not system-app,can't use system-api");
945             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
946             return CreateJsUndefined(env);
947         }
948 
949         if (argc > ARGS_ONE || argc < ARGS_ZERO) {
950             HILOG_ERROR("invalid argc");
951             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "0 or 1");
952             return CreateJsUndefined(env);
953         }
954 
955         auto complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
956             // Use original logic.
957             // Use the error code to return whether the function executed successfully.
958             auto ret = FormMgr::GetInstance().CheckFMSReady() ? 0 : 1;
959             if (ret == ERR_OK) {
960                 task.ResolveWithNoError(env, CreateJsUndefined(env));
961             } else {
962                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
963             }
964         };
965 
966         auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
967         napi_value result = nullptr;
968         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnIsSystemReady",
969             env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
970         return result;
971     }
972 
OnDeleteInvalidForms(napi_env env,size_t argc,napi_value * argv)973     napi_value OnDeleteInvalidForms(napi_env env, size_t argc, napi_value* argv)
974     {
975         HILOG_DEBUG("call");
976 
977         if (argc > ARGS_TWO || argc < ARGS_ONE) {
978             HILOG_ERROR("invalid argc");
979             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
980             return CreateJsUndefined(env);
981         }
982 
983         decltype(argc) convertArgc = 0;
984         std::vector<int64_t> formIds;
985         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
986             HILOG_ERROR("invalid formIdList");
987             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
988             return CreateJsUndefined(env);
989         }
990         convertArgc++;
991 
992         auto complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
993             int32_t num;
994             auto ret = FormMgr::GetInstance().DeleteInvalidForms(formIds, FormHostClient::GetInstance(), num);
995             if (ret == ERR_OK) {
996                 task.ResolveWithNoError(env, CreateJsValue(env, num));
997             } else {
998                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
999             }
1000         };
1001 
1002         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1003         napi_value result = nullptr;
1004         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnEnableFormsUpdate",
1005             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1006         return result;
1007     }
1008 
InnerAcquireFormState(napi_env env,const std::shared_ptr<NapiAsyncTask> & asyncTask,JsFormStateCallbackClient::AcquireFormStateTask && task,const Want & want)1009     void InnerAcquireFormState(
1010         napi_env env,
1011         const std::shared_ptr<NapiAsyncTask> &asyncTask,
1012         JsFormStateCallbackClient::AcquireFormStateTask &&task,
1013         const Want &want)
1014     {
1015         auto formStateCallback = std::make_shared<JsFormStateCallbackClient>(std::move(task));
1016         FormHostClient::GetInstance()->AddFormState(formStateCallback, want);
1017         FormStateInfo stateInfo;
1018         auto result = FormMgr::GetInstance().AcquireFormState(want, FormHostClient::GetInstance(), stateInfo);
1019         formStateCallback->SetWant(stateInfo.want);
1020         if (result != ERR_OK) {
1021             HILOG_DEBUG("AcquireFormState failed");
1022             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, result));
1023             FormHostClient::GetInstance()->RemoveFormState(want);
1024         }
1025     }
1026 
OnAcquireFormState(napi_env env,size_t argc,napi_value * argv)1027     napi_value OnAcquireFormState(napi_env env, size_t argc, napi_value* argv)
1028     {
1029         HILOG_DEBUG("call");
1030         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1031             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1032             return CreateJsUndefined(env);
1033         }
1034 
1035         Want want;
1036         napi_value argWant = argv[PARAM0];
1037         if (!UnwrapWant(env, argWant, want)) {
1038             HILOG_ERROR("invalid want");
1039             NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
1040             return CreateJsUndefined(env);
1041         }
1042 
1043         napi_value lastParam = (argc == ARGS_ONE) ? nullptr : argv[PARAM1];
1044         napi_value result = nullptr;
1045 
1046         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1047             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1048         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1049 
1050         JsFormStateCallbackClient::AcquireFormStateTask task = [env, asyncTask](int32_t state, Want want) {
1051             HILOG_DEBUG("task complete state:%{public}d", state);
1052             napi_value objValue = nullptr;
1053             napi_create_object(env, &objValue);
1054             napi_set_named_property(env, objValue, "want", CreateJsWant(env, want));
1055             napi_set_named_property(env, objValue, "formState", CreateJsValue(env, state));
1056             asyncTask->ResolveWithNoError(env, objValue);
1057         };
1058 
1059         InnerAcquireFormState(env, asyncTask, std::move(task), want);
1060         return result;
1061     }
1062 
OnSetRouterProxy(napi_env env,size_t argc,napi_value * argv)1063     napi_value OnSetRouterProxy(napi_env env, size_t argc, napi_value* argv)
1064     {
1065 #ifndef WATCH_API_DISABLE
1066         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1067             HILOG_ERROR("invalid argc");
1068             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1069             return CreateJsUndefined(env);
1070         }
1071         decltype(argc) convertArgc = 0;
1072 
1073         // Check the type of the PARAM0.
1074         std::vector<int64_t> formIds;
1075         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1076             HILOG_ERROR("invalid formIdList");
1077             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1078             return CreateJsUndefined(env);
1079         }
1080         convertArgc++;
1081 
1082         // Check the type of the PARAM1.
1083         if (!IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1084             HILOG_ERROR("invalid Param2");
1085             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<Want>");
1086             return CreateJsUndefined(env);
1087         }
1088         convertArgc++;
1089 
1090         auto apiResult = std::make_shared<int32_t>();
1091         JsFormRouterProxyMgr::GetInstance()->AddFormRouterProxyCallback(env, argv[PARAM1], formIds);
1092         auto execute = [formIds, ret = apiResult]() {
1093             *ret = FormMgr::GetInstance().RegisterFormRouterProxy(formIds, JsFormRouterProxyMgr::GetInstance());
1094         };
1095 
1096         NapiAsyncTask::CompleteCallback complete =
1097             [ret = apiResult](napi_env env, NapiAsyncTask &task, int32_t status) {
1098                 if (*ret == ERR_OK) {
1099                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1100                 } else {
1101                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
1102                 }
1103             };
1104 
1105         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1106         napi_value result = nullptr;
1107         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnSetRouterProxy",
1108             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1109         return result;
1110 #else
1111         return nullptr;
1112 #endif
1113     }
1114 
OnClearRouterProxy(napi_env env,size_t argc,napi_value * argv)1115     napi_value OnClearRouterProxy(napi_env env, size_t argc, napi_value* argv)
1116     {
1117 #ifndef WATCH_API_DISABLE
1118         // Check the number of input parameters.
1119         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1120             HILOG_ERROR("invalid argc");
1121             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1122             return CreateJsUndefined(env);
1123         }
1124         decltype(argc) convertArgc = 0;
1125 
1126         // Check the type of the PARAM0.
1127         std::vector<int64_t> formIds;
1128         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1129             HILOG_ERROR("invalid formIdList");
1130             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1131             return CreateJsUndefined(env);
1132         }
1133         convertArgc++;
1134 
1135         auto apiResult = std::make_shared<int32_t>();
1136         JsFormRouterProxyMgr::GetInstance()->RemoveFormRouterProxyCallback(formIds);
1137         auto execute = [formIds, ret = apiResult]() {
1138             *ret = FormMgr::GetInstance().UnregisterFormRouterProxy(formIds);
1139         };
1140 
1141         NapiAsyncTask::CompleteCallback complete =
1142             [ret = apiResult](napi_env env, NapiAsyncTask &task, int32_t status) {
1143                 if (*ret == ERR_OK) {
1144                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1145                 } else {
1146                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
1147                 }
1148             };
1149         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1150         napi_value result = nullptr;
1151         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnClearRouterProxy",
1152             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1153         return result;
1154 #else
1155         return nullptr;
1156 #endif
1157     }
1158 
OnRegisterFormObserver(napi_env env,size_t argc,napi_value * argv)1159     napi_value OnRegisterFormObserver(napi_env env, size_t argc, napi_value* argv)
1160     {
1161         HILOG_DEBUG("call");
1162         if (!CheckCallerIsSystemApp()) {
1163             HILOG_ERROR("The app not system-app,can't use system-api");
1164             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1165             return CreateJsUndefined(env);
1166         }
1167 
1168         // Check the number of input parameters.
1169         if (argc != ARGS_TWO) {
1170             HILOG_ERROR("invalid argc");
1171             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
1172             return CreateJsUndefined(env);
1173         }
1174 
1175         std::string type;
1176         if (!ConvertFromJsValue(env, argv[PARAM0], type) ||
1177             (FORM_LISTENER_TYPE.find(type) == FORM_LISTENER_TYPE.end())) {
1178             HILOG_ERROR("args[0] not register func %{public}s", type.c_str());
1179             NapiFormUtil::ThrowParamTypeError(env, "type",
1180                 "formUninstall or formOverflow or changeSceneAnimationState or getFormRect or getLiveFormStatus");
1181             return CreateJsUndefined(env);
1182         }
1183 
1184         // Check the type of the PARAM1.
1185         if (!IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1186             HILOG_ERROR("invalid param1");
1187             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<string>");
1188             return CreateJsUndefined(env);
1189         }
1190         napi_value callback = argv[PARAM1];
1191         napi_ref callbackRef;
1192         napi_create_reference(env, callback, REF_COUNT, &callbackRef);
1193         if (type == FORM_UNINSTALL) {
1194             FormHostClient::GetInstance()->RegisterUninstallCallback(FormUninstallCallback);
1195             AddFormUninstallCallback(env, argv[PARAM1]);
1196         } else if (type == FORM_OVERFLOW) {
1197             return OnRegisterOverflowListener(env, callbackRef);
1198         } else if (type == CHANGE_SCENE_ANIMATION_STATE) {
1199             return OnRegisterChangeSceneAnimationStateListener(env, callbackRef);
1200         } else if (type == GET_FORM_RECT) {
1201             return OnRegisterGetFormRectListener(env, callbackRef);
1202         } else if (type == GET_LIVE_FORM_STATUS) {
1203             return OnRegisterGetLiveFormStatusListener(env, callbackRef);
1204         }
1205         return CreateJsUndefined(env);
1206     }
1207 
OnUnregisterFormObserver(napi_env env,size_t argc,napi_value * argv)1208     napi_value OnUnregisterFormObserver(napi_env env, size_t argc, napi_value* argv)
1209     {
1210         HILOG_DEBUG("call");
1211         if (!CheckCallerIsSystemApp()) {
1212             HILOG_ERROR("the application not system-app,can't use system-api");
1213             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1214             return CreateJsUndefined(env);
1215         }
1216 
1217         // Check the number of input parameters.
1218         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1219             HILOG_ERROR("invalid argc");
1220             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1221             return CreateJsUndefined(env);
1222         }
1223 
1224         // Check the type of the PARAM0 and convert it to string.
1225         std::string type;
1226         if (!ConvertFromJsValue(env, argv[PARAM0], type) ||
1227             (FORM_LISTENER_TYPE.find(type) == FORM_LISTENER_TYPE.end())) {
1228             HILOG_ERROR("Invalid type provided: %{public}s."
1229                         "Expected formUninstall or formOverflow or changeSceneAnimationState or getFormRect or "
1230                         "getLiveFormStatus.",
1231                 type.c_str());
1232             NapiFormUtil::ThrowParamTypeError(env, "type",
1233                 "formUninstall or formOverflow or changeSceneAnimationState or getFormRect or getLiveFormStatus");
1234             return CreateJsUndefined(env);
1235         }
1236         // Check the type of the PARAM1.
1237         if (argc == ARGS_TWO && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1238             HILOG_ERROR("invalid param1");
1239             NapiFormUtil::ThrowParamTypeError(env, "callback", "Callback<string>");
1240             return CreateJsUndefined(env);
1241         }
1242 
1243         if (argc == ARGS_TWO) {
1244             DelFormUninstallCallback(argv[PARAM1]);
1245             return CreateJsUndefined(env);
1246         }
1247 
1248         if (type == FORM_UNINSTALL) {
1249             ClearFormUninstallCallback();
1250         } else if (type == FORM_OVERFLOW) {
1251             return OffRegisterOverflowListener(env);
1252         } else if (type == CHANGE_SCENE_ANIMATION_STATE) {
1253             return OffRegisterChangeSceneAnimationStateListener(env);
1254         } else if (type == GET_FORM_RECT) {
1255             return OffRegisterGetFormRectListener(env);
1256         } else if (type == GET_LIVE_FORM_STATUS) {
1257             return OffRegisterGetLiveFormStatusListener(env);
1258         }
1259         return CreateJsUndefined(env);
1260     }
1261 
OnNotifyFormsVisible(napi_env env,size_t argc,napi_value * argv)1262     napi_value OnNotifyFormsVisible(napi_env env, size_t argc, napi_value* argv)
1263     {
1264         HILOG_DEBUG("call");
1265 
1266         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1267             HILOG_ERROR("invalid argc");
1268             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1269             return CreateJsUndefined(env);
1270         }
1271 
1272         decltype(argc) convertArgc = 0;
1273         std::vector<int64_t> formIds;
1274         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1275             HILOG_ERROR("invalid formIdList");
1276             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1277             return CreateJsUndefined(env);
1278         }
1279         convertArgc++;
1280 
1281         bool isVisible = false;
1282         if (!ConvertFromJsValue(env, argv[PARAM1], isVisible)) {
1283             HILOG_ERROR("convert isVisible failed");
1284             NapiFormUtil::ThrowParamTypeError(env, "isVisible", "boolean");
1285             return CreateJsUndefined(env);
1286         }
1287         convertArgc++;
1288 
1289         auto complete = [formIds, isVisible](napi_env env, NapiAsyncTask &task, int32_t status) {
1290             auto ret = FormMgr::GetInstance().NotifyFormsVisible(formIds, isVisible,
1291                 FormHostClient::GetInstance());
1292             if (ret == ERR_OK) {
1293                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1294             } else {
1295                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1296             }
1297         };
1298 
1299         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1300         napi_value result = nullptr;
1301         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnNotifyFormsVisible",
1302             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1303         return result;
1304     }
1305 
OnNotifyFormsEnableUpdate(napi_env env,size_t argc,napi_value * argv)1306     napi_value OnNotifyFormsEnableUpdate(napi_env env, size_t argc, napi_value* argv)
1307     {
1308         HILOG_DEBUG("call");
1309 
1310         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1311             HILOG_ERROR("invalid argc");
1312             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1313             return CreateJsUndefined(env);
1314         }
1315 
1316         decltype(argc) convertArgc = 0;
1317         std::vector<int64_t> formIds;
1318         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1319             HILOG_ERROR("invalid formIdList");
1320             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1321             return CreateJsUndefined(env);
1322         }
1323         convertArgc++;
1324 
1325         bool isEnableUpdate = false;
1326         if (!ConvertFromJsValue(env, argv[PARAM1], isEnableUpdate)) {
1327             HILOG_ERROR("convert isEnableUpdate failed");
1328             NapiFormUtil::ThrowParamTypeError(env, "isEnableUpdate", "boolean");
1329             return CreateJsUndefined(env);
1330         }
1331         convertArgc++;
1332 
1333         auto complete = [formIds, isEnableUpdate](napi_env env, NapiAsyncTask &task, int32_t status) {
1334             auto ret = FormMgr::GetInstance().NotifyFormsEnableUpdate(formIds, isEnableUpdate,
1335                 FormHostClient::GetInstance());
1336             if (ret == ERR_OK) {
1337                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1338             } else {
1339                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1340             }
1341         };
1342 
1343         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1344         napi_value result = nullptr;
1345         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnNotifyFormsVisible",
1346             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1347         return result;
1348     }
1349 
OnGetAllFormsInfo(napi_env env,size_t argc,napi_value * argv)1350     napi_value OnGetAllFormsInfo(napi_env env, size_t argc, napi_value* argv)
1351     {
1352         HILOG_DEBUG("call");
1353         if (argc > ARGS_ONE || argc < ARGS_ZERO) {
1354             HILOG_ERROR("invalid argc");
1355             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "0 or 1");
1356             return CreateJsUndefined(env);
1357         }
1358 
1359         auto errCodeVal = std::make_shared<int32_t>(0);
1360         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1361         NapiAsyncTask::ExecuteCallback execute = [formInfos = formInfoList, errCode = errCodeVal]() {
1362             if (formInfos == nullptr || errCode == nullptr) {
1363                 HILOG_ERROR("invalid param");
1364                 return;
1365             }
1366             *errCode = FormMgr::GetInstance().GetAllFormsInfo(*formInfos);
1367         };
1368 
1369         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1370 
1371         auto callback = (argc == ARGS_ZERO) ? nullptr : argv[PARAM0];
1372         napi_value result = nullptr;
1373         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetAllFormsInfo",
1374             env, CreateAsyncTaskWithLastParam(env, callback, std::move(execute), std::move(complete), &result));
1375         return result;
1376     }
1377 
GetFormsInfoByFilter(napi_env env,size_t argc,napi_value * argv)1378     napi_value GetFormsInfoByFilter(napi_env env, size_t argc, napi_value* argv)
1379     {
1380         HILOG_INFO("call");
1381         if (argc != ARGS_ONE) {
1382             HILOG_ERROR("invalid argc");
1383             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
1384             return CreateJsUndefined(env);
1385         }
1386 
1387         decltype(argc) convertArgc = 0;
1388         AppExecFwk::FormInfoFilter filter;
1389         napi_value jsValue = GetPropertyValueByPropertyName(env, argv[PARAM0], "supportedDimensions", napi_object);
1390         if (jsValue != nullptr) {
1391             std::vector<int32_t> dimensions;
1392             UnwrapArrayInt32FromJS(env, jsValue, dimensions);
1393             for (size_t i = 0; i < dimensions.size(); ++i) {
1394                 if (dimensions[i] < 0) {
1395                     HILOG_ERROR("dimensions value should not be negative");
1396                     NapiFormUtil::ThrowParamError(env, "dimensions value should not be negative");
1397                     return CreateJsUndefined(env);
1398                 }
1399                 filter.supportDimensions.emplace_back(dimensions[i]);
1400             }
1401         }
1402 
1403         napi_value jsShapeValue = GetPropertyValueByPropertyName(env, argv[PARAM0], "supportedShapes", napi_object);
1404         if (jsShapeValue != nullptr && !GetIntVecValue(env, jsShapeValue, filter.supportShapes)) {
1405             HILOG_ERROR("shapes value should not be negative");
1406             NapiFormUtil::ThrowParamError(env, "shapes value should not be negative");
1407             return CreateJsUndefined(env);
1408         }
1409 
1410         UnwrapStringByPropertyName(env, argv[PARAM0], "moduleName", filter.moduleName);
1411         UnwrapStringByPropertyName(env, argv[PARAM0], "bundleName", filter.bundleName);
1412 
1413         convertArgc++;
1414 
1415         auto errCodeVal = std::make_shared<int32_t>(0);
1416         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1417         NapiAsyncTask::ExecuteCallback execute = [filter, formInfos = formInfoList, errCode = errCodeVal]() {
1418             if (formInfos == nullptr || errCode == nullptr) {
1419                 HILOG_ERROR("invalid param");
1420                 return;
1421             }
1422             *errCode = FormMgr::GetInstance().GetFormsInfoByFilter(filter, *formInfos);
1423         };
1424 
1425         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1426 
1427         napi_value result = nullptr;
1428         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1429         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetFormsInfo",
1430             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1431         return result;
1432     }
1433 
GetIntVecValue(napi_env & env,napi_value & jsValue,std::vector<int32_t> & results)1434     bool GetIntVecValue(napi_env &env, napi_value &jsValue, std::vector<int32_t> &results)
1435     {
1436         std::vector<int32_t> vals;
1437         UnwrapArrayInt32FromJS(env, jsValue, vals);
1438         for (size_t i = 0; i < vals.size(); ++i) {
1439             if (vals[i] < 0) {
1440                 HILOG_ERROR("value should not be negative");
1441                 return false;
1442             }
1443             results.emplace_back(vals[i]);
1444         }
1445         return true;
1446     }
1447 
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)1448     napi_value OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
1449     {
1450         HILOG_INFO("call");
1451         if (argc == ARGS_ONE && IsTypeForNapiValue(env, argv[PARAM0], napi_object)) {
1452             return GetFormsInfoByFilter(env, argc, argv);
1453         }
1454         if (argc > ARGS_THREE || argc < ARGS_ONE) {
1455             HILOG_ERROR("invalid argc");
1456             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
1457             return CreateJsUndefined(env);
1458         }
1459         decltype(argc) convertArgc = 0;
1460         std::string bName("");
1461         if (!ConvertFromJsValue(env, argv[PARAM0], bName)) {
1462             HILOG_ERROR("bundleName convert failed");
1463             NapiFormUtil::ThrowParamTypeError(env, "bundleName", "string");
1464             return CreateJsUndefined(env);
1465         }
1466         convertArgc++;
1467         std::string mName("");
1468         if ((argc == ARGS_TWO || argc == ARGS_THREE) && !IsTypeForNapiValue(env, argv[PARAM1], napi_function)) {
1469             if (!ConvertFromJsValue(env, argv[PARAM1], mName)) {
1470                 HILOG_ERROR("moduleName convert failed");
1471                 NapiFormUtil::ThrowParamTypeError(env, "moduleName", "string");
1472                 return CreateJsUndefined(env);
1473             }
1474             convertArgc++;
1475         }
1476 
1477         auto errCodeVal = std::make_shared<int32_t>(0);
1478         auto formInfoList = std::make_shared<std::vector<FormInfo>>();
1479         NapiAsyncTask::ExecuteCallback execute = [bName, mName, convertArgc, formInfos = formInfoList,
1480             errCode = errCodeVal]() {
1481             if (formInfos == nullptr || errCode == nullptr) {
1482                 HILOG_ERROR("invalid param");
1483                 return;
1484             }
1485             std::string bundleName(bName);
1486             std::string moduleName(mName);
1487             if (convertArgc == ARGS_ONE) {
1488                 *errCode = FormMgr::GetInstance().GetFormsInfoByApp(bundleName, *formInfos);
1489             } else {
1490                 *errCode = FormMgr::GetInstance().GetFormsInfoByModule(bundleName, moduleName, *formInfos);
1491             }
1492         };
1493 
1494         NapiAsyncTask::CompleteCallback complete = CreateFormInfosCompleteCallback(errCodeVal, formInfoList);
1495         napi_value result = nullptr;
1496         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1497         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnGetFormsInfo",
1498             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1499         return result;
1500     }
1501 
CreateFormInfosCompleteCallback(std::shared_ptr<int32_t> errCodeVal,std::shared_ptr<std::vector<FormInfo>> formInfoList)1502     NapiAsyncTask::CompleteCallback CreateFormInfosCompleteCallback(std::shared_ptr<int32_t> errCodeVal,
1503         std::shared_ptr<std::vector<FormInfo>> formInfoList)
1504     {
1505         return [errCode = errCodeVal, formInfos = formInfoList](
1506             napi_env env, NapiAsyncTask &task, int32_t status) {
1507             if (errCode == nullptr || formInfos == nullptr) {
1508                 HILOG_ERROR("invalid param");
1509                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ERR_APPEXECFWK_FORM_COMMON_CODE));
1510                 return;
1511             }
1512             if (*errCode != ERR_OK) {
1513                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *errCode));
1514                 return;
1515             }
1516             task.ResolveWithNoError(env, CreateFormInfos(env, *formInfos));
1517         };
1518     }
1519 
InnerShareForm(napi_env env,const std::shared_ptr<AbilityRuntime::NapiAsyncTask> & asyncTask,ShareFormCallBackClient::ShareFormTask && task,int64_t formId,const std::string & remoteDeviceId)1520     void InnerShareForm(napi_env env, const std::shared_ptr<AbilityRuntime::NapiAsyncTask> &asyncTask,
1521         ShareFormCallBackClient::ShareFormTask &&task, int64_t formId, const std::string &remoteDeviceId)
1522     {
1523         auto shareFormCallback = std::make_shared<ShareFormCallBackClient>(std::move(task));
1524         int64_t requestCode = SystemTimeMillis();
1525         FormHostClient::GetInstance()->AddShareFormCallback(shareFormCallback, requestCode);
1526 
1527         ErrCode ret = FormMgr::GetInstance().ShareForm(
1528             formId, remoteDeviceId, FormHostClient::GetInstance(), requestCode);
1529         if (ret != ERR_OK) {
1530             HILOG_INFO("share form fail");
1531             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1532             FormHostClient::GetInstance()->RemoveShareFormCallback(requestCode);
1533         }
1534     }
1535 
InnerAcquireFormData(napi_env env,const std::shared_ptr<AbilityRuntime::NapiAsyncTask> & asyncTask,JsFormDataCallbackClient::AcquireFormDataTask && task,int64_t formId)1536     void InnerAcquireFormData(napi_env env, const std::shared_ptr<AbilityRuntime::NapiAsyncTask> &asyncTask,
1537        JsFormDataCallbackClient::AcquireFormDataTask &&task, int64_t formId)
1538     {
1539         auto formDataCallbackClient = std::make_shared<JsFormDataCallbackClient>(std::move(task));
1540         int64_t requestCode = SystemTimeMillis();
1541         FormHostClient::GetInstance()->AddAcqiureFormDataCallback(formDataCallbackClient, requestCode);
1542 
1543         AAFwk::WantParams formData;
1544         auto ret = FormMgr::GetInstance().AcquireFormData(formId, requestCode, FormHostClient::GetInstance(), formData);
1545         if (ret != ERR_OK) {
1546             HILOG_ERROR("acquire form failed");
1547             asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1548             FormHostClient::GetInstance()->RemoveAcquireDataCallback(requestCode);
1549         }
1550     }
1551 
OnShareForm(napi_env env,size_t argc,napi_value * argv)1552     napi_value OnShareForm(napi_env env, size_t argc, napi_value* argv)
1553     {
1554         HILOG_DEBUG("call");
1555         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1556             HILOG_ERROR("invalid argc");
1557             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2 or 3");
1558             return CreateJsUndefined(env);
1559         }
1560 
1561         decltype(argc) convertArgc = 0;
1562         int64_t formId = 0;
1563         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1564             HILOG_ERROR("invalid formId");
1565             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1566             return CreateJsUndefined(env);
1567         }
1568         convertArgc++;
1569 
1570         std::string devicedId;
1571         if (!ConvertDeviceId(env, argv[PARAM1], devicedId)) {
1572             HILOG_ERROR("invalid deviceId");
1573             NapiFormUtil::ThrowParamTypeError(env, "devicedId", "string");
1574             return CreateJsUndefined(env);
1575         }
1576         convertArgc++;
1577 
1578         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1579         napi_value result = nullptr;
1580 
1581         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1582             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1583         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1584 
1585         ShareFormCallBackClient::ShareFormTask task = [env, asyncTask](int32_t code) {
1586             HILOG_DEBUG("task complete code:%{public}d", code);
1587             if (code == ERR_OK) {
1588                 asyncTask->ResolveWithNoError(env, CreateJsUndefined(env));
1589             } else {
1590                 asyncTask->Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, code));
1591             }
1592         };
1593 
1594         InnerShareForm(env, asyncTask, std::move(task), formId, devicedId);
1595 
1596         return result;
1597     }
1598 
OnAcquireFormData(napi_env env,size_t argc,napi_value * argv)1599     napi_value OnAcquireFormData(napi_env env, size_t argc, napi_value* argv)
1600     {
1601 #ifndef WATCH_API_DISABLE
1602         HILOG_DEBUG("call");
1603         if (argc > ARGS_TWO || argc < ARGS_ONE) {
1604             HILOG_ERROR("invalid argc");
1605             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1606             return CreateJsUndefined(env);
1607         }
1608 
1609         // The promise form has only one parameters
1610         decltype(argc) unwrapArgc = 1;
1611         int64_t formId = 0;
1612         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1613             HILOG_ERROR("invalid formId");
1614             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1615             return CreateJsUndefined(env);
1616         }
1617 
1618         napi_value lastParam = (argc <= unwrapArgc) ? nullptr : argv[unwrapArgc];
1619         napi_value result = nullptr;
1620 
1621         std::unique_ptr<AbilityRuntime::NapiAsyncTask> uasyncTask =
1622             AbilityRuntime::CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
1623         std::shared_ptr<AbilityRuntime::NapiAsyncTask> asyncTask = std::move(uasyncTask);
1624 
1625         JsFormDataCallbackClient::AcquireFormDataTask task = [env, asyncTask](AAFwk::WantParams data) {
1626             HILOG_DEBUG("task complete form data");
1627             napi_value objValue = nullptr;
1628             napi_create_object(env, &objValue);
1629             napi_set_named_property(env, objValue, "formData", CreateJsWantParams(env, data));
1630             asyncTask->ResolveWithNoError(env, objValue);
1631         };
1632 
1633         InnerAcquireFormData(env, asyncTask, std::move(task), formId);
1634         return result;
1635 #else
1636         return nullptr;
1637 #endif
1638     }
1639 
OnNotifyFormsPrivacyProtected(napi_env env,size_t argc,napi_value * argv)1640     napi_value OnNotifyFormsPrivacyProtected(napi_env env, size_t argc, napi_value* argv)
1641     {
1642         HILOG_INFO("call");
1643         if (argc > ARGS_THREE || argc < ARGS_TWO) {
1644             HILOG_ERROR("invalid argc");
1645             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
1646             return CreateJsUndefined(env);
1647         }
1648 
1649         decltype(argc) convertArgc = 0;
1650         std::vector<int64_t> formIds;
1651         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1652             HILOG_ERROR("invalid formIdList");
1653             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1654             return CreateJsUndefined(env);
1655         }
1656         convertArgc++;
1657 
1658         bool isProtected = false;
1659         if (!ConvertFromJsValue(env, argv[PARAM1], isProtected)) {
1660             HILOG_ERROR("convert isProtected failed");
1661             NapiFormUtil::ThrowParamTypeError(env, "isProtected", "boolean");
1662             return CreateJsUndefined(env);
1663         }
1664         convertArgc++;
1665 
1666         NapiAsyncTask::CompleteCallback complete =
1667             [formIds, isProtected](napi_env env, NapiAsyncTask &task, int32_t status) {
1668                 auto ret = FormMgr::GetInstance().NotifyFormsPrivacyProtected(formIds,
1669                     isProtected, FormHostClient::GetInstance());
1670                 if (ret == ERR_OK) {
1671                     task.ResolveWithNoError(env, CreateJsUndefined(env));
1672                 } else {
1673                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1674                 }
1675             };
1676 
1677         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1678         napi_value result = nullptr;
1679         NapiAsyncTask::ScheduleWithDefaultQos("NapiFormHost::OnNotifyFormsPrivacyProtected",
1680             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1681         return result;
1682     }
1683 
OnSetFormsRecyclable(napi_env env,size_t argc,napi_value * argv)1684     napi_value OnSetFormsRecyclable(napi_env env, size_t argc, napi_value *argv)
1685     {
1686 #ifndef WATCH_API_DISABLE
1687         HILOG_DEBUG("call");
1688         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1689             HILOG_ERROR("invalid argc");
1690             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1691             return CreateJsUndefined(env);
1692         }
1693 
1694         decltype(argc) convertArgc = 0;
1695         std::vector<int64_t> formIds;
1696         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1697             HILOG_ERROR("invalid formIdList");
1698             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1699             return CreateJsUndefined(env);
1700         }
1701         convertArgc++;
1702 
1703         NapiAsyncTask::CompleteCallback complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
1704             auto ret = FormMgr::GetInstance().SetFormsRecyclable(formIds);
1705             if (ret == ERR_OK) {
1706                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1707             } else {
1708                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1709             }
1710         };
1711 
1712         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1713         napi_value result = nullptr;
1714         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnSetFormsRecyclable",
1715             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1716         return result;
1717 #else
1718         return nullptr;
1719 #endif
1720     }
1721 
OnRecoverForms(napi_env env,size_t argc,napi_value * argv)1722     napi_value OnRecoverForms(napi_env env, size_t argc, napi_value *argv)
1723     {
1724         HILOG_DEBUG("call");
1725         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1726             HILOG_ERROR("invalid argc");
1727             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1728             return CreateJsUndefined(env);
1729         }
1730 
1731         decltype(argc) convertArgc = 0;
1732         std::vector<int64_t> formIds;
1733         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1734             HILOG_ERROR("invalid formIdList");
1735             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1736             return CreateJsUndefined(env);
1737         }
1738         convertArgc++;
1739 
1740         auto apiResult = std::make_shared<int32_t>();
1741         NapiAsyncTask::ExecuteCallback execute = [formIds, ret = apiResult]() {
1742             Want want;
1743             *ret = FormMgr::GetInstance().RecoverForms(formIds, want);
1744         };
1745 
1746         NapiAsyncTask::CompleteCallback complete =
1747             [ret = apiResult](napi_env env, NapiAsyncTask &task, int32_t status) {
1748             if (*ret == ERR_OK) {
1749                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1750             } else {
1751                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, *ret));
1752             }
1753         };
1754 
1755         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1756         napi_value result = nullptr;
1757         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRecoverForms",
1758             env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
1759         return result;
1760     }
1761 
OnRecycleForms(napi_env env,size_t argc,napi_value * argv)1762     napi_value OnRecycleForms(napi_env env, size_t argc, napi_value *argv)
1763     {
1764         HILOG_DEBUG("call");
1765         if (argc < ARGS_ONE || argc > ARGS_TWO) {
1766             HILOG_ERROR("invalid argc");
1767             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1 or 2");
1768             return CreateJsUndefined(env);
1769         }
1770 
1771         decltype(argc) convertArgc = 0;
1772         std::vector<int64_t> formIds;
1773         if (!ConvertFromIds(env, argv[PARAM0], formIds)) {
1774             HILOG_ERROR("invalid formIdList");
1775             NapiFormUtil::ThrowParamTypeError(env, "formIds", "Array<string>");
1776             return CreateJsUndefined(env);
1777         }
1778         convertArgc++;
1779 
1780         NapiAsyncTask::CompleteCallback complete = [formIds](napi_env env, NapiAsyncTask &task, int32_t status) {
1781             Want want;
1782             auto ret = FormMgr::GetInstance().RecycleForms(formIds, want);
1783             if (ret == ERR_OK) {
1784                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1785             } else {
1786                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1787             }
1788         };
1789 
1790         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1791         napi_value result = nullptr;
1792         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnRecycleForms",
1793             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1794         return result;
1795     }
1796 
OnUpdateFormLockedState(napi_env env,size_t argc,napi_value * argv)1797     napi_value OnUpdateFormLockedState(napi_env env, size_t argc, napi_value* argv)
1798     {
1799         HILOG_DEBUG("call");
1800 
1801         if (argc != ARGS_TWO) {
1802             HILOG_ERROR("invalid argc");
1803             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
1804             return CreateJsUndefined(env);
1805         }
1806 
1807         decltype(argc) convertArgc = 0;
1808         int64_t formId;
1809         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1810             HILOG_ERROR("invalid formId");
1811             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1812             return CreateJsUndefined(env);
1813         }
1814         convertArgc++;
1815 
1816         bool isLocked = false;
1817         if (!ConvertFromJsValue(env, argv[PARAM1], isLocked)) {
1818             HILOG_ERROR("convert isLocked failed");
1819             NapiFormUtil::ThrowParamTypeError(env, "isLocked", "boolean");
1820             return CreateJsUndefined(env);
1821         }
1822         convertArgc++;
1823 
1824         auto complete = [formId, isLocked](napi_env env, NapiAsyncTask &task, int32_t status) {
1825             auto ret = FormMgr::GetInstance().NotifyFormLocked(formId, isLocked);
1826             if (ret == ERR_OK) {
1827                 task.ResolveWithNoError(env, CreateJsUndefined(env));
1828             } else {
1829                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1830             }
1831         };
1832 
1833         napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
1834         napi_value result = nullptr;
1835         NapiAsyncTask::ScheduleWithDefaultQos("JsFormHost::OnUpdateFormLockedState",
1836             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1837         return result;
1838     }
1839 
OnUpdateFormLocation(napi_env env,size_t argc,napi_value * argv)1840     napi_value OnUpdateFormLocation(napi_env env, size_t argc, napi_value *argv)
1841     {
1842         HILOG_DEBUG("call");
1843         if (argc != ARGS_TWO) {
1844             HILOG_ERROR("invalid argc");
1845             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "argc != 2");
1846             return CreateJsUndefined(env);
1847         }
1848 
1849         int64_t formId = -1;
1850         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1851             HILOG_ERROR("Convert strFormIdList failed");
1852             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1853             return CreateJsUndefined(env);
1854         }
1855         HILOG_INFO("formId:%{public}s", std::to_string(formId).c_str());
1856         int32_t formLocation = INVALID_FORM_LOCATION;
1857         if (napi_get_value_int32(env, argv[PARAM1], &formLocation) == napi_ok) {
1858             if (formLocation < static_cast<int32_t>(Constants::FormLocation::OTHER) ||
1859                  formLocation > static_cast<int32_t>(Constants::FormLocation::AI_SUGGESTION)) {
1860                 HILOG_ERROR("formLocation not FormLocation enum");
1861                 NapiFormUtil::ThrowParamTypeError(env, "formLocation", "FormLocation enum");
1862                 return CreateJsUndefined(env);
1863             }
1864         } else {
1865             HILOG_ERROR("formLocation not number");
1866             NapiFormUtil::ThrowParamTypeError(env, "formLocation", "number");
1867             return CreateJsUndefined(env);
1868         }
1869         HILOG_INFO("formLocation:%{public}s", std::to_string(formLocation).c_str());
1870         auto ret = FormMgr::GetInstance().UpdateFormLocation(formId, formLocation);
1871         if (ret == ERR_OK) {
1872             return CreateJsUndefined(env);
1873         }
1874         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
1875         return CreateJsUndefined(env);
1876     }
1877 
OnSetPublishFormResult(napi_env env,size_t argc,napi_value * argv)1878     napi_value OnSetPublishFormResult(napi_env env, size_t argc, napi_value *argv)
1879     {
1880         HILOG_DEBUG("call");
1881         if (!CheckCallerIsSystemApp()) {
1882             HILOG_ERROR("the application not system-app,can't use system-api");
1883             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
1884             return CreateJsUndefined(env);
1885         }
1886         if (argc != ARGS_TWO) {
1887             HILOG_ERROR("invalid argc");
1888             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
1889             return CreateJsUndefined(env);
1890         }
1891         decltype(argc) convertArgc = 0;
1892         int64_t formId;
1893         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1894             HILOG_ERROR("Convert strFormId failed");
1895             NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1896             return CreateJsUndefined(env);
1897         }
1898         convertArgc++;
1899         std::string messageInfo = "";
1900         int32_t formErrorCode = INVALID_FORM_RESULT_ERRCODE;
1901         if (!ParseParameter(env, argv, formErrorCode, messageInfo)) {
1902             HILOG_ERROR("Parsing Argument Errors");
1903             NapiFormUtil::ThrowParamError(env, "Failed to get property.");
1904             return CreateJsUndefined(env);
1905         }
1906         convertArgc++;
1907 
1908         AppExecFwk::Constants::PublishFormResult publishFormResult;
1909         publishFormResult.code = static_cast<AppExecFwk::Constants::PublishFormErrorCode>(formErrorCode);
1910         publishFormResult.message = messageInfo;
1911         ErrCode ret = FormMgr::GetInstance().SetPublishFormResult(formId, publishFormResult);
1912         if (ret == ERR_OK) {
1913             return CreateJsUndefined(env);
1914         }
1915         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
1916         return CreateJsUndefined(env);
1917     }
1918 
OnRegisterOverflowListener(napi_env env,napi_ref callbackRef)1919     napi_value OnRegisterOverflowListener(napi_env env, napi_ref callbackRef)
1920     {
1921         HILOG_INFO("call");
1922         bool result = FormMgr::GetInstance().RegisterOverflowProxy(JsFormRouterProxyMgr::GetInstance());
1923         if (!result) {
1924             return CreateJsValue(env, result);
1925         }
1926         result = JsFormRouterProxyMgr::GetInstance()->RegisterOverflowListener(env, callbackRef);
1927         return CreateJsValue(env, result);
1928     }
1929 
OffRegisterOverflowListener(napi_env env)1930     napi_value OffRegisterOverflowListener(napi_env env)
1931     {
1932         HILOG_INFO("call");
1933         bool result = FormMgr::GetInstance().UnregisterOverflowProxy();
1934         if (!result) {
1935             return CreateJsValue(env, result);
1936         }
1937         result = JsFormRouterProxyMgr::GetInstance()->UnregisterOverflowListener();
1938         return CreateJsValue(env, result);
1939     }
1940 
OnRegisterChangeSceneAnimationStateListener(napi_env env,napi_ref callbackRef)1941     napi_value OnRegisterChangeSceneAnimationStateListener(napi_env env, napi_ref callbackRef)
1942     {
1943         HILOG_INFO("call");
1944         bool result = FormMgr::GetInstance().RegisterChangeSceneAnimationStateProxy(
1945             JsFormRouterProxyMgr::GetInstance());
1946         if (!result) {
1947             return CreateJsValue(env, result);
1948         }
1949         result = JsFormRouterProxyMgr::GetInstance()->RegisterChangeSceneAnimationStateListener(
1950             env, callbackRef);
1951         return CreateJsValue(env, result);
1952     }
1953 
OffRegisterChangeSceneAnimationStateListener(napi_env env)1954     napi_value OffRegisterChangeSceneAnimationStateListener(napi_env env)
1955     {
1956         HILOG_INFO("call");
1957         bool result = FormMgr::GetInstance().UnregisterChangeSceneAnimationStateProxy();
1958         if (!result) {
1959             return CreateJsValue(env, result);
1960         }
1961         result = JsFormRouterProxyMgr::GetInstance()->UnregisterChangeSceneAnimationStateListener();
1962         return CreateJsValue(env, result);
1963     }
1964 
OnRegisterGetFormRectListener(napi_env env,napi_ref callbackRef)1965     napi_value OnRegisterGetFormRectListener(napi_env env, napi_ref callbackRef)
1966     {
1967         HILOG_INFO("call");
1968         bool result = FormMgr::GetInstance().RegisterGetFormRectProxy(
1969             JsFormRouterProxyMgr::GetInstance());
1970         if (!result) {
1971             return CreateJsValue(env, result);
1972         }
1973         result = JsFormRouterProxyMgr::GetInstance()->RegisterGetFormRectListener(
1974             env, callbackRef);
1975         return CreateJsValue(env, result);
1976     }
1977 
OffRegisterGetFormRectListener(napi_env env)1978     napi_value OffRegisterGetFormRectListener(napi_env env)
1979     {
1980         HILOG_INFO("call");
1981         bool result = FormMgr::GetInstance().UnregisterGetFormRectProxy();
1982         if (!result) {
1983             return CreateJsValue(env, result);
1984         }
1985         result = JsFormRouterProxyMgr::GetInstance()->UnregisterGetFormRectListener();
1986         return CreateJsValue(env, result);
1987     }
1988 
OnUpdateFormSize(napi_env env,size_t argc,napi_value * argv)1989     napi_value OnUpdateFormSize(napi_env env, size_t argc, napi_value* argv)
1990     {
1991         HILOG_DEBUG("call");
1992         if (argc != ARGS_THREE) {
1993             HILOG_ERROR("invalid argc");
1994             NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "3");
1995             return CreateJsUndefined(env);
1996         }
1997         int64_t formId;
1998         if (!ConvertFromId(env, argv[PARAM0], formId)) {
1999             HILOG_ERROR("Convert formId failed");
2000             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_FORM_ID_NOT_EXIST);
2001             return CreateJsUndefined(env);
2002         }
2003         decltype(argc) convertArgc = 0;
2004         convertArgc++;
2005         int32_t newDimension;
2006         if (napi_get_value_int32(env, argv[PARAM1], &newDimension) == napi_ok) {
2007             if (newDimension < static_cast<int32_t>(Constants::Dimension::DIMENSION_MIN) ||
2008                 newDimension > static_cast<int32_t>(Constants::Dimension::DIMENSION_MAX)) {
2009                 HILOG_ERROR("newDimension not Dimension enum");
2010                 NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_FORM_DIMENSION_ERROR);
2011                 return CreateJsUndefined(env);
2012             }
2013         } else {
2014             HILOG_ERROR("newDimension not number");
2015             NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_FORM_DIMENSION_ERROR);
2016             return CreateJsUndefined(env);
2017         }
2018         convertArgc++;
2019         AppExecFwk::Rect* newRect = new (std::nothrow) AppExecFwk::Rect {};
2020         if (newRect == nullptr) {
2021             HILOG_ERROR("Failed to new newRect");
2022             return CreateJsUndefined(env);
2023         }
2024         if (!ConvertFormRect(env, argv[PARAM2], newRect)) {
2025             HILOG_ERROR("convert newRect failed");
2026             delete newRect;
2027             NapiFormUtil::ThrowParamError(env, "The newRect is invalid");
2028             return CreateJsUndefined(env);
2029         }
2030         convertArgc++;
2031         auto ret = FormMgr::GetInstance().UpdateFormSize(formId, newDimension, *newRect);
2032         delete newRect;
2033         if (ret == ERR_OK) {
2034             return CreateJsUndefined(env);
2035         }
2036         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
2037         return CreateJsUndefined(env);
2038     }
2039 
ConvertFormRect(napi_env env,napi_value rect,AppExecFwk::Rect * newRect)2040     bool ConvertFormRect(napi_env env, napi_value rect, AppExecFwk::Rect* newRect)
2041     {
2042         if (newRect == nullptr) {
2043             HILOG_ERROR("input newRect is null");
2044             return false;
2045         }
2046         napi_valuetype type = napi_undefined;
2047         napi_typeof(env, rect, &type);
2048         if (type == napi_undefined || type == napi_null) {
2049             HILOG_ERROR("input rect is undefined or null");
2050             return false;
2051         }
2052         if (!GetAndConvertProperty(env, rect, "left", newRect->left) ||
2053             !GetAndConvertProperty(env, rect, "top", newRect->top) ||
2054             !GetAndConvertProperty(env, rect, "width", newRect->width) ||
2055             !GetAndConvertProperty(env, rect, "height", newRect->height)) {
2056             return false;
2057         }
2058         return true;
2059     }
2060 
GetAndConvertProperty(napi_env env,napi_value object,const char * propertyName,double & outValue)2061     bool GetAndConvertProperty(napi_env env, napi_value object, const char* propertyName, double& outValue)
2062     {
2063         napi_value propertyValue;
2064         napi_status status = napi_get_named_property(env, object, propertyName, &propertyValue);
2065         if (status != napi_ok) {
2066             HILOG_ERROR("Failed to get property: %{public}s", propertyName);
2067             return false;
2068         }
2069         if (!ConvertFromJsValue(env, propertyValue, outValue)) {
2070             HILOG_ERROR("ConvertFromJsValue %{public}s failed", propertyName);
2071             return false;
2072         }
2073         return true;
2074     }
2075 
OnRegisterGetLiveFormStatusListener(napi_env env,napi_ref callbackRef)2076     napi_value OnRegisterGetLiveFormStatusListener(napi_env env, napi_ref callbackRef)
2077     {
2078         HILOG_INFO("call");
2079         bool result = FormMgr::GetInstance().RegisterGetLiveFormStatusProxy(
2080             JsFormRouterProxyMgr::GetInstance());
2081         if (!result) {
2082             return CreateJsValue(env, result);
2083         }
2084         result = JsFormRouterProxyMgr::GetInstance()->RegisterGetLiveFormStatusListener(
2085             env, callbackRef);
2086         return CreateJsValue(env, result);
2087     }
2088 
OffRegisterGetLiveFormStatusListener(napi_env env)2089     napi_value OffRegisterGetLiveFormStatusListener(napi_env env)
2090     {
2091         HILOG_INFO("call");
2092         bool result = FormMgr::GetInstance().UnregisterGetLiveFormStatusProxy();
2093         if (!result) {
2094             return CreateJsValue(env, result);
2095         }
2096         result = JsFormRouterProxyMgr::GetInstance()->UnregisterGetLiveFormStatusListener();
2097         return CreateJsValue(env, result);
2098     }
2099 };
2100 
JsFormHostInit(napi_env env,napi_value exportObj)2101 napi_value JsFormHostInit(napi_env env, napi_value exportObj)
2102 {
2103     HILOG_DEBUG("call");
2104 
2105     std::unique_ptr<JsFormHost> jsFormHost = std::make_unique<JsFormHost>();
2106     napi_wrap(env, exportObj, jsFormHost.release(), JsFormHost::Finalizer, nullptr, nullptr);
2107 
2108     const char *moduleName = "JsFormHost";
2109     BindNativeFunction(env, exportObj, "deleteForm", moduleName, JsFormHost::DeleteForm);
2110     BindNativeFunction(env, exportObj, "releaseForm", moduleName, JsFormHost::ReleaseForm);
2111     BindNativeFunction(env, exportObj, "requestForm", moduleName, JsFormHost::RequestForm);
2112     BindNativeFunction(env, exportObj, "requestFormWithParams", moduleName, JsFormHost::RequestFormWithParams);
2113     BindNativeFunction(env, exportObj, "castTempForm", moduleName, JsFormHost::CastTempForm);
2114     BindNativeFunction(env, exportObj, "castToNormalForm", moduleName, JsFormHost::CastTempForm);
2115     BindNativeFunction(env, exportObj, "notifyVisibleForms", moduleName, JsFormHost::NotifyVisibleForms);
2116     BindNativeFunction(env, exportObj, "notifyInvisibleForms", moduleName, JsFormHost::NotifyInvisibleForms);
2117     BindNativeFunction(env, exportObj, "enableFormsUpdate", moduleName, JsFormHost::EnableFormsUpdate);
2118     BindNativeFunction(env, exportObj, "disableFormsUpdate", moduleName, JsFormHost::DisableFormsUpdate);
2119     BindNativeFunction(env, exportObj, "isSystemReady", moduleName, JsFormHost::IsSystemReady);
2120     BindNativeFunction(env, exportObj, "deleteInvalidForms", moduleName, JsFormHost::DeleteInvalidForms);
2121     BindNativeFunction(env, exportObj, "acquireFormState", moduleName, JsFormHost::AcquireFormState);
2122     BindNativeFunction(env, exportObj, "on", moduleName, JsFormHost::RegisterFormObserver);
2123     BindNativeFunction(env, exportObj, "off", moduleName, JsFormHost::UnregisterFormObserver);
2124     BindNativeFunction(env, exportObj, "notifyFormsVisible", moduleName, JsFormHost::NotifyFormsVisible);
2125     BindNativeFunction(env, exportObj, "notifyFormsEnableUpdate", moduleName, JsFormHost::NotifyFormsEnableUpdate);
2126     BindNativeFunction(env, exportObj, "getAllFormsInfo", moduleName, JsFormHost::GetAllFormsInfo);
2127     BindNativeFunction(env, exportObj, "getFormsInfo", moduleName, JsFormHost::GetFormsInfo);
2128     BindNativeFunction(env, exportObj, "shareForm", moduleName, JsFormHost::ShareForm);
2129     BindNativeFunction(env, exportObj, "notifyFormsPrivacyProtected", moduleName,
2130         JsFormHost::NotifyFormsPrivacyProtected);
2131     BindNativeFunction(env, exportObj, "acquireFormData", moduleName, JsFormHost::AcquireFormData);
2132     BindNativeFunction(env, exportObj, "setRouterProxy", moduleName, JsFormHost::SetRouterProxy);
2133     BindNativeFunction(env, exportObj, "clearRouterProxy", moduleName, JsFormHost::ClearRouterProxy);
2134     BindNativeFunction(env, exportObj, "setFormsRecyclable", moduleName, JsFormHost::SetFormsRecyclable);
2135     BindNativeFunction(env, exportObj, "recoverForms", moduleName, JsFormHost::RecoverForms);
2136     BindNativeFunction(env, exportObj, "recycleForms", moduleName, JsFormHost::RecycleForms);
2137     BindNativeFunction(env, exportObj, "updateFormLocation", moduleName, JsFormHost::UpdateFormLocation);
2138     BindNativeFunction(env, exportObj, "setPublishFormResult", moduleName, JsFormHost::SetPublishFormResult);
2139     BindNativeFunction(env, exportObj, "addForm", moduleName, JsFormHost::AddForm);
2140     BindNativeFunction(env, exportObj, "updateFormLockedState", moduleName, JsFormHost::UpdateFormLockedState);
2141     BindNativeFunction(env, exportObj, "updateFormSize", moduleName, JsFormHost::UpdateFormSize);
2142 
2143     return CreateJsUndefined(env);
2144 }
2145 
FormRouterProxyCallbackClient(napi_env env,napi_ref callbackRef)2146 FormRouterProxyCallbackClient::FormRouterProxyCallbackClient(napi_env env, napi_ref callbackRef)
2147 {
2148     env_ = env;
2149     callbackRef_ = callbackRef;
2150     handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
2151 }
2152 
~FormRouterProxyCallbackClient()2153 FormRouterProxyCallbackClient::~FormRouterProxyCallbackClient()
2154 {
2155     napi_delete_reference(env_, callbackRef_);
2156 }
2157 
ProcessFormRouterProxy(const Want & want)2158 void FormRouterProxyCallbackClient::ProcessFormRouterProxy(const Want &want)
2159 {
2160     HILOG_INFO("call");
2161     if (handler_ == nullptr) {
2162         HILOG_ERROR("null Handler");
2163         return;
2164     }
2165     handler_->PostSyncTask([thisWeakPtr = weak_from_this(), want]() {
2166         auto sharedThis = thisWeakPtr.lock();
2167         if (sharedThis == nullptr) {
2168             HILOG_ERROR("null SharedThis");
2169             return;
2170         }
2171 
2172         napi_value callbackValues = CreateJsWant(sharedThis->env_, want);
2173         napi_value callResult;
2174         napi_value myCallback = nullptr;
2175         napi_get_reference_value(sharedThis->env_, sharedThis->callbackRef_, &myCallback);
2176         if (myCallback != nullptr) {
2177             napi_call_function(sharedThis->env_, nullptr, myCallback, ARGS_ONE, &callbackValues, &callResult);
2178         }
2179     });
2180 }
2181 
2182 sptr<JsFormRouterProxyMgr> JsFormRouterProxyMgr::instance_ = nullptr;
2183 std::mutex JsFormRouterProxyMgr::mutex_;
GetInstance()2184 sptr<JsFormRouterProxyMgr> JsFormRouterProxyMgr::GetInstance()
2185 {
2186     if (instance_ == nullptr) {
2187         std::lock_guard<std::mutex> lock(mutex_);
2188         if (instance_ == nullptr) {
2189             instance_ = new (std::nothrow) JsFormRouterProxyMgr();
2190             if (instance_ == nullptr) {
2191                 HILOG_ERROR("create JsFormRouterProxyMgr failed");
2192             }
2193         }
2194     }
2195     return instance_;
2196 }
2197 
RouterEvent(int64_t formId,const Want & want)2198 ErrCode JsFormRouterProxyMgr::RouterEvent(int64_t formId, const Want &want)
2199 {
2200     HILOG_DEBUG("call");
2201 
2202     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
2203     auto callbackClient = formRouterProxyCallbackMap_.find(formId);
2204     if (callbackClient != formRouterProxyCallbackMap_.end()) {
2205         if (callbackClient->second != nullptr) {
2206             callbackClient->second->ProcessFormRouterProxy(want);
2207         }
2208     }
2209     return ERR_OK;
2210 }
2211 
AddFormRouterProxyCallback(napi_env env,napi_value callback,const std::vector<int64_t> & formIds)2212 void JsFormRouterProxyMgr::AddFormRouterProxyCallback(napi_env env, napi_value callback,
2213     const std::vector<int64_t> &formIds)
2214 {
2215 #ifndef WATCH_API_DISABLE
2216     HILOG_DEBUG("call");
2217     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
2218 
2219     napi_ref callbackRef;
2220     napi_create_reference(env, callback, REF_COUNT, &callbackRef);
2221     std::shared_ptr<FormRouterProxyCallbackClient> callbackClient = std::make_shared<FormRouterProxyCallbackClient>(env,
2222         callbackRef);
2223 
2224     for (const auto &formId : formIds) {
2225         auto iter = formRouterProxyCallbackMap_.find(formId);
2226         if (iter != formRouterProxyCallbackMap_.end()) {
2227             iter->second = callbackClient;
2228             continue;
2229         }
2230         formRouterProxyCallbackMap_.emplace(formId, callbackClient);
2231     }
2232 #endif
2233 }
2234 
RemoveFormRouterProxyCallback(const std::vector<int64_t> & formIds)2235 void JsFormRouterProxyMgr::RemoveFormRouterProxyCallback(const std::vector<int64_t> &formIds)
2236 {
2237     HILOG_INFO("call");
2238     std::lock_guard<std::mutex> lock(FormRouterProxyCallbackMutex_);
2239     for (const auto &formId : formIds) {
2240         auto iter = formRouterProxyCallbackMap_.find(formId);
2241         if (iter != formRouterProxyCallbackMap_.end()) {
2242             formRouterProxyCallbackMap_.erase(formId);
2243         }
2244     }
2245 }
2246 
RegisterOverflowListener(napi_env env,napi_ref callbackRef)2247 bool JsFormRouterProxyMgr::RegisterOverflowListener(napi_env env, napi_ref callbackRef)
2248 {
2249     HILOG_INFO("call");
2250 
2251     if (callbackRef == nullptr) {
2252         HILOG_ERROR("Invalid callback reference");
2253         return false;
2254     }
2255 
2256     if (overflowRegisterCallback_ != nullptr) {
2257         napi_delete_reference(env, overflowRegisterCallback_);
2258         overflowRegisterCallback_ = nullptr;
2259     }
2260 
2261     overflowRegisterCallback_ = callbackRef;
2262     overflowEnv_ = env;
2263 
2264     napi_value callback;
2265     napi_get_reference_value(env, callbackRef, &callback);
2266     napi_valuetype valueType;
2267     napi_typeof(env, callback, &valueType);
2268     if (valueType != napi_function) {
2269         HILOG_ERROR("Callback is not a function");
2270         return false;
2271     }
2272 
2273     HILOG_INFO("Listener registered successfully");
2274     return true;
2275 }
2276 
UnregisterOverflowListener()2277 bool JsFormRouterProxyMgr::UnregisterOverflowListener()
2278 {
2279     HILOG_INFO("call");
2280     overflowRegisterCallback_ = nullptr;
2281     overflowEnv_ = nullptr;
2282     return true;
2283 }
2284 
RequestOverflow(const int64_t formId,const AppExecFwk::OverflowInfo & overflowInfo,bool isOverflow)2285 ErrCode JsFormRouterProxyMgr::RequestOverflow(const int64_t formId, const AppExecFwk::OverflowInfo &overflowInfo,
2286     bool isOverflow)
2287 {
2288     HILOG_INFO("call");
2289     LiveFormInterfaceParam* dataParam = new (std::nothrow) LiveFormInterfaceParam {
2290         .formId = std::to_string(formId),
2291         .overflowInfo = overflowInfo,
2292         .isOverflow = isOverflow
2293     };
2294     if (dataParam == nullptr) {
2295         HILOG_ERROR("Failed to new dataParam, formId:%{public}" PRId64 ".", formId);
2296         return ERR_GET_INFO_FAILED;
2297     }
2298     std::shared_ptr<EventHandler> mainHandler = std::make_shared<EventHandler>(EventRunner::GetMainEventRunner());
2299     std::function<void()> executeFunc = [client = sptr<JsFormRouterProxyMgr>(this), dataParam]() {
2300         JsFormRouterProxyMgr::GetInstance()->RequestOverflowInner(dataParam);
2301     };
2302     mainHandler->PostSyncTask(executeFunc, "JsFormRouterProxyMgr::RequestOverflow");
2303     HILOG_INFO("call RequestOverflow end, result:%{public}d", dataParam->result);
2304     bool result = dataParam->result;
2305     delete dataParam;
2306     return result ? ERR_OK : ERR_GET_INFO_FAILED;
2307 }
2308 
RequestOverflowInner(LiveFormInterfaceParam * dataParam)2309 void JsFormRouterProxyMgr::RequestOverflowInner(LiveFormInterfaceParam* dataParam)
2310 {
2311     HILOG_INFO("call");
2312     napi_handle_scope scope = nullptr;
2313     napi_open_handle_scope(overflowEnv_, &scope);
2314     if (scope == nullptr) {
2315         HILOG_ERROR("null scope");
2316         return;
2317     }
2318     napi_value requestObj;
2319     napi_create_object(overflowEnv_, &requestObj);
2320 
2321     napi_value formIdValue;
2322     napi_create_string_utf8(overflowEnv_, dataParam->formId.c_str(), NAPI_AUTO_LENGTH, &formIdValue);
2323     napi_set_named_property(overflowEnv_, requestObj, "formId", formIdValue);
2324     napi_set_named_property(overflowEnv_, requestObj, "isOverflow", CreateJsValue(overflowEnv_, dataParam->isOverflow));
2325 
2326     napi_value overflowInfoValue;
2327     CreateFormOverflowInfo(overflowEnv_, dataParam->overflowInfo, &overflowInfoValue);
2328     napi_set_named_property(overflowEnv_, requestObj, "overflowInfo", overflowInfoValue);
2329 
2330     napi_value myCallback = nullptr;
2331     napi_get_reference_value(overflowEnv_, overflowRegisterCallback_, &myCallback);
2332 
2333     napi_valuetype valueType;
2334     napi_typeof(overflowEnv_, myCallback, &valueType);
2335 
2336     if (valueType != napi_function) {
2337         dataParam->result = false;
2338         napi_close_handle_scope(overflowEnv_, scope);
2339         return;
2340     }
2341 
2342     napi_value args[] = { requestObj };
2343     napi_value callResult = nullptr;
2344     napi_status status = napi_call_function(overflowEnv_, nullptr, myCallback, 1, args, &callResult);
2345     if (status != napi_ok) {
2346         dataParam->result = false;
2347         napi_close_handle_scope(overflowEnv_, scope);
2348         return;
2349     }
2350 
2351     napi_valuetype returnType;
2352     napi_typeof(overflowEnv_, callResult, &returnType);
2353 
2354     bool result = false;
2355     if (returnType == napi_undefined) {
2356         dataParam->result = false;
2357         napi_close_handle_scope(overflowEnv_, scope);
2358         return;
2359     }
2360 
2361     napi_get_value_bool(overflowEnv_, callResult, &result);
2362     dataParam->result = result;
2363     napi_close_handle_scope(overflowEnv_, scope);
2364 }
2365 
CreateFormOverflowInfo(napi_env env,AppExecFwk::OverflowInfo & overflowInfo,napi_value * result)2366 void JsFormRouterProxyMgr::CreateFormOverflowInfo(napi_env env, AppExecFwk::OverflowInfo &overflowInfo,
2367     napi_value* result)
2368 {
2369     HILOG_INFO("CreateFormOverflowInfo call");
2370     napi_handle_scope scope = nullptr;
2371     napi_open_handle_scope(env, &scope);
2372     if (scope == nullptr) {
2373         HILOG_ERROR("null scope");
2374         return;
2375     }
2376     napi_value area = nullptr;
2377     napi_create_object(env, &area);
2378     napi_set_named_property(env, area, "left", CreateJsValue(env, overflowInfo.area.left));
2379     napi_set_named_property(env, area, "top", CreateJsValue(env, overflowInfo.area.top));
2380     napi_set_named_property(env, area, "width", CreateJsValue(env, overflowInfo.area.width));
2381     napi_set_named_property(env, area, "height", CreateJsValue(env, overflowInfo.area.height));
2382 
2383     napi_value duration = nullptr;
2384     napi_create_int32(env, overflowInfo.duration, &duration);
2385     napi_create_object(env, result);
2386     napi_set_named_property(env, *result, "area", area);
2387     napi_set_named_property(env, *result, "duration", duration);
2388     napi_set_named_property(env, *result, "useDefaultAnimation", CreateJsValue(env, overflowInfo.useDefaultAnimation));
2389     napi_close_handle_scope(env, scope);
2390 }
2391 
RegisterChangeSceneAnimationStateListener(napi_env env,napi_ref callbackRef)2392 bool JsFormRouterProxyMgr::RegisterChangeSceneAnimationStateListener(napi_env env, napi_ref callbackRef)
2393 {
2394     HILOG_INFO("call");
2395 
2396     if (callbackRef == nullptr) {
2397         HILOG_ERROR("Invalid callback reference");
2398         return false;
2399     }
2400 
2401     if (changeSceneAnimationStateRigisterCallback_ != nullptr) {
2402         napi_delete_reference(env, changeSceneAnimationStateRigisterCallback_);
2403         changeSceneAnimationStateRigisterCallback_ = nullptr;
2404     }
2405 
2406     changeSceneAnimationStateRigisterCallback_ = callbackRef;
2407     changeSceneAnimationStateEnv_ = env;
2408 
2409     napi_value callback;
2410     napi_get_reference_value(env, callbackRef, &callback);
2411     napi_valuetype valueType;
2412     napi_typeof(env, callback, &valueType);
2413     if (valueType != napi_function) {
2414         HILOG_ERROR("Callback is not a function");
2415         return false;
2416     }
2417 
2418     HILOG_INFO("Listener registered successfully");
2419     return true;
2420 }
2421 
UnregisterChangeSceneAnimationStateListener()2422 bool JsFormRouterProxyMgr::UnregisterChangeSceneAnimationStateListener()
2423 {
2424     HILOG_INFO("call");
2425     changeSceneAnimationStateRigisterCallback_ = nullptr;
2426     changeSceneAnimationStateEnv_ = nullptr;
2427     return true;
2428 }
2429 
ChangeSceneAnimationState(const int64_t formId,int32_t state)2430 ErrCode JsFormRouterProxyMgr::ChangeSceneAnimationState(const int64_t formId, int32_t state)
2431 {
2432     HILOG_INFO("call");
2433     LiveFormInterfaceParam* dataParam = new (std::nothrow) LiveFormInterfaceParam {
2434         .formId = std::to_string(formId),
2435         .state = state
2436     };
2437     if (dataParam == nullptr) {
2438         HILOG_ERROR("Failed to new dataParam, formId:%{public}" PRId64 ".", formId);
2439         return ERR_GET_INFO_FAILED;
2440     }
2441     std::shared_ptr<EventHandler> mainHandler = std::make_shared<EventHandler>(EventRunner::GetMainEventRunner());
2442     std::function<void()> executeFunc = [client = sptr<JsFormRouterProxyMgr>(this), dataParam]() {
2443         JsFormRouterProxyMgr::GetInstance()->ChangeSceneAnimationStateInner(dataParam);
2444     };
2445     mainHandler->PostSyncTask(executeFunc, "JsFormRouterProxyMgr::ChangeSceneAnimationState");
2446     HILOG_INFO("call ChangeSceneAnimationState end, result:%{public}d", dataParam->result);
2447     bool result = dataParam->result;
2448     delete dataParam;
2449     return result ? ERR_OK : ERR_GET_INFO_FAILED;
2450 }
2451 
ChangeSceneAnimationStateInner(LiveFormInterfaceParam * dataParam)2452 void JsFormRouterProxyMgr::ChangeSceneAnimationStateInner(LiveFormInterfaceParam* dataParam)
2453 {
2454     HILOG_INFO("call");
2455     napi_handle_scope scope = nullptr;
2456     napi_open_handle_scope(changeSceneAnimationStateEnv_, &scope);
2457     if (scope == nullptr) {
2458         HILOG_ERROR("null scope");
2459         return;
2460     }
2461     napi_value requestObj;
2462     napi_create_object(changeSceneAnimationStateEnv_, &requestObj);
2463 
2464     napi_value formIdValue;
2465     napi_create_string_utf8(changeSceneAnimationStateEnv_, dataParam->formId.c_str(), NAPI_AUTO_LENGTH, &formIdValue);
2466     napi_set_named_property(changeSceneAnimationStateEnv_, requestObj, "formId", formIdValue);
2467     napi_set_named_property(changeSceneAnimationStateEnv_, requestObj, "state",
2468         CreateJsValue(changeSceneAnimationStateEnv_, dataParam->state));
2469 
2470     napi_value myCallback = nullptr;
2471     napi_get_reference_value(changeSceneAnimationStateEnv_, changeSceneAnimationStateRigisterCallback_, &myCallback);
2472 
2473     napi_valuetype valueType;
2474     napi_typeof(changeSceneAnimationStateEnv_, myCallback, &valueType);
2475 
2476     if (valueType != napi_function) {
2477         dataParam->result = false;
2478         napi_close_handle_scope(changeSceneAnimationStateEnv_, scope);
2479         return;
2480     }
2481 
2482     napi_value args[] = { requestObj };
2483     napi_value callResult = nullptr;
2484     napi_status status = napi_call_function(changeSceneAnimationStateEnv_, nullptr, myCallback, 1, args, &callResult);
2485     if (status != napi_ok) {
2486         dataParam->result = false;
2487         napi_close_handle_scope(changeSceneAnimationStateEnv_, scope);
2488         return;
2489     }
2490 
2491     napi_valuetype returnType;
2492     napi_typeof(changeSceneAnimationStateEnv_, callResult, &returnType);
2493 
2494     if (returnType == napi_undefined) {
2495         dataParam->result = false;
2496         napi_close_handle_scope(changeSceneAnimationStateEnv_, scope);
2497         return;
2498     }
2499 
2500     bool result = false;
2501     napi_get_value_bool(changeSceneAnimationStateEnv_, callResult, &result);
2502     dataParam->result = result;
2503     napi_close_handle_scope(changeSceneAnimationStateEnv_, scope);
2504 }
2505 
RegisterGetFormRectListener(napi_env env,napi_ref callbackRef)2506 bool JsFormRouterProxyMgr::RegisterGetFormRectListener(napi_env env, napi_ref callbackRef)
2507 {
2508     HILOG_INFO("call");
2509     if (callbackRef == nullptr) {
2510         HILOG_ERROR("Invalid callback reference");
2511         return false;
2512     }
2513 
2514     if (getFormRectCallbackRef_ != nullptr) {
2515         napi_delete_reference(env, getFormRectCallbackRef_);
2516         getFormRectCallbackRef_ = nullptr;
2517     }
2518 
2519     getFormRectCallbackRef_ = callbackRef;
2520     getFormRectEnv_ = env;
2521 
2522     napi_value callback;
2523     napi_get_reference_value(env, callbackRef, &callback);
2524     napi_valuetype valueType;
2525     napi_typeof(env, callback, &valueType);
2526     if (valueType != napi_function) {
2527         HILOG_ERROR("Callback is not a function");
2528         return false;
2529     }
2530 
2531     HILOG_INFO("Listener registered successfully");
2532     return true;
2533 }
2534 
UnregisterGetFormRectListener()2535 bool JsFormRouterProxyMgr::UnregisterGetFormRectListener()
2536 {
2537     HILOG_INFO("call");
2538     getFormRectCallbackRef_ = nullptr;
2539     getFormRectEnv_ = nullptr;
2540     return true;
2541 }
2542 
GetFormRect(const int64_t formId,AppExecFwk::Rect & rect)2543 ErrCode JsFormRouterProxyMgr::GetFormRect(const int64_t formId, AppExecFwk::Rect &rect)
2544 {
2545     HILOG_INFO("call");
2546     LiveFormInterfaceParam* dataParam = new (std::nothrow) LiveFormInterfaceParam {
2547         .formId = std::to_string(formId)
2548     };
2549     if (dataParam == nullptr) {
2550         HILOG_ERROR("Failed to new dataParam, formId:%{public}" PRId64 ".", formId);
2551         return ERR_GET_INFO_FAILED;
2552     }
2553     std::shared_ptr<EventHandler> mainHandler = std::make_shared<EventHandler>(EventRunner::GetMainEventRunner());
2554     std::function<void()> executeGetFormRectFunc = [client = sptr<JsFormRouterProxyMgr>(this), dataParam]() {
2555         JsFormRouterProxyMgr::GetInstance()->GetFormRectInner(dataParam);
2556     };
2557     mainHandler->PostSyncTask(executeGetFormRectFunc, "JsFormRouterProxyMgr::GetFormRect");
2558     HILOG_INFO("call GetFormRect end, result:%{public}d", dataParam->result);
2559     bool result = dataParam->result;
2560     rect = std::move(dataParam->formRect);
2561     delete dataParam;
2562     return result ? ERR_OK : ERR_GET_INFO_FAILED;
2563 }
2564 
CallBackReturn(const Rect & item,LiveFormInterfaceParam * liveFormInterfaceParam,bool ret)2565 void CallBackReturn(const Rect &item, LiveFormInterfaceParam* liveFormInterfaceParam, bool ret)
2566 {
2567     if (liveFormInterfaceParam == nullptr) {
2568         HILOG_INFO("getFormRect callback param has been released");
2569         return;
2570     }
2571     liveFormInterfaceParam->result = ret;
2572     liveFormInterfaceParam->formRect = item;
2573     HILOG_INFO("getFormRect end.");
2574 }
2575 
GetFormRectInner(LiveFormInterfaceParam * dataParam)2576 void JsFormRouterProxyMgr::GetFormRectInner(LiveFormInterfaceParam *dataParam)
2577 {
2578     HILOG_INFO("call");
2579     napi_handle_scope scope = nullptr;
2580     napi_open_handle_scope(getFormRectEnv_, &scope);
2581     if (scope == nullptr) {
2582         HILOG_ERROR("null scope");
2583         return;
2584     }
2585     AbilityRuntime::HandleEscape handleEscape(getFormRectEnv_);
2586     napi_value callbackValue;
2587     napi_create_string_utf8(getFormRectEnv_, dataParam->formId.c_str(), NAPI_AUTO_LENGTH, &callbackValue);
2588 
2589     napi_value myCallback = nullptr;
2590     napi_get_reference_value(getFormRectEnv_, getFormRectCallbackRef_, &myCallback);
2591     napi_valuetype valueType;
2592     napi_typeof(getFormRectEnv_, myCallback, &valueType);
2593 
2594     if (valueType != napi_function) {
2595         dataParam->result = false;
2596         napi_close_handle_scope(getFormRectEnv_, scope);
2597         return;
2598     }
2599     napi_value callResult = nullptr;
2600     napi_status status =
2601         napi_call_function(getFormRectEnv_, nullptr, myCallback, ARGS_ONE, &callbackValue, &callResult);
2602     if (status != napi_ok) {
2603         dataParam->result = false;
2604         napi_close_handle_scope(getFormRectEnv_, scope);
2605         return;
2606     }
2607 
2608     napi_valuetype returnType;
2609     napi_typeof(getFormRectEnv_, callResult, &returnType);
2610 
2611     if (returnType == napi_undefined) {
2612         dataParam->result = false;
2613         napi_close_handle_scope(getFormRectEnv_, scope);
2614         return;
2615     }
2616     bool isPromise = false;
2617     napi_value funcResult = handleEscape.Escape(callResult);
2618     napi_is_promise(getFormRectEnv_, funcResult, &isPromise);
2619     if (!isPromise) {
2620         HILOG_INFO("result not promise");
2621         std::unique_ptr<AppExecFwk::Rect> item = std::make_unique<AppExecFwk::Rect>();
2622         bool ret = ConvertFunctionResult(getFormRectEnv_, funcResult, *item);
2623         CallBackReturn(*item, dataParam, ret);
2624         napi_close_handle_scope(getFormRectEnv_, scope);
2625         return;
2626     }
2627     CallPromise(funcResult, dataParam);
2628     napi_close_handle_scope(getFormRectEnv_, scope);
2629 }
2630 
CallPromise(napi_value funcResult,LiveFormInterfaceParam * params)2631 void JsFormRouterProxyMgr::CallPromise(napi_value funcResult, LiveFormInterfaceParam *params)
2632 {
2633     HILOG_INFO("call");
2634     napi_value promiseThen = nullptr;
2635     napi_value promiseCatch = nullptr;
2636     napi_get_named_property(getFormRectEnv_, funcResult, "then", &promiseThen);
2637     napi_get_named_property(getFormRectEnv_, funcResult, "catch", &promiseCatch);
2638 
2639     bool isCallable = false;
2640     napi_is_callable(getFormRectEnv_, promiseThen, &isCallable);
2641     if (!isCallable) {
2642         HILOG_ERROR("property then is not callable.");
2643         return;
2644     }
2645     napi_is_callable(getFormRectEnv_, promiseCatch, &isCallable);
2646     if (!isCallable) {
2647         HILOG_ERROR("property catch is not callable.");
2648         return;
2649     }
2650 
2651     napi_value promiseCallback = nullptr;
2652     auto *callbackInfo = PromiseCallbackInfo::Create(params);
2653     if (callbackInfo == nullptr) {
2654         HILOG_ERROR("Failed to new promise callbackInfo.");
2655         return;
2656     }
2657     napi_create_function(getFormRectEnv_, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
2658         callbackInfo, &promiseCallback);
2659 
2660     napi_status status;
2661     napi_value argvPromise[1] = { promiseCallback };
2662 
2663     status = napi_call_function(getFormRectEnv_, funcResult, promiseThen, ARGS_ONE, argvPromise, nullptr);
2664     if (status != napi_ok) {
2665         HILOG_ERROR("Invoke pushCheck promise then error.");
2666         PromiseCallbackInfo::Destroy(callbackInfo);
2667         return;
2668     }
2669 
2670     status = napi_call_function(getFormRectEnv_, funcResult, promiseCatch, ARGS_ONE, argvPromise, nullptr);
2671     if (status != napi_ok) {
2672         HILOG_ERROR("Invoke pushCheck promise catch error.");
2673         PromiseCallbackInfo::Destroy(callbackInfo);
2674         return;
2675     }
2676 }
2677 
PromiseCallback(napi_env env,napi_callback_info info)2678 napi_value JsFormRouterProxyMgr::PromiseCallback(napi_env env, napi_callback_info info)
2679 {
2680     HILOG_INFO("enter");
2681     if (info == nullptr) {
2682         HILOG_ERROR("PromiseCallback, invalid input info");
2683         return nullptr;
2684     }
2685 
2686     size_t argc = 1;
2687     napi_value argv[1] = {nullptr};
2688     void *data = nullptr;
2689 
2690     napi_get_cb_info(env, info, &argc, &argv[PARAM0], nullptr, &data);
2691     std::unique_ptr<AppExecFwk::Rect> item = std::make_unique<AppExecFwk::Rect>();
2692     bool ret = ConvertFunctionResult(env, argv[PARAM0], *item);
2693     if (data == nullptr) {
2694         HILOG_ERROR("PromiseCallback, invalid data");
2695         return nullptr;
2696     }
2697 
2698     auto *callbackInfo = static_cast<PromiseCallbackInfo *>(data);
2699     if (callbackInfo == nullptr) {
2700         HILOG_ERROR("PromiseCallback, invalid callbackInfo");
2701         return nullptr;
2702     }
2703     CallBackReturn(*item, callbackInfo->GetJsCallBackParam(), ret);
2704 
2705     PromiseCallbackInfo::Destroy(callbackInfo);
2706     callbackInfo = nullptr;
2707     return nullptr;
2708 }
2709 
ConvertFunctionResult(napi_env env,napi_value funcResult,Rect & item)2710 bool JsFormRouterProxyMgr::ConvertFunctionResult(napi_env env, napi_value funcResult, Rect &item)
2711 {
2712     if (funcResult == nullptr) {
2713         HILOG_ERROR("The funcResult is error.");
2714         return false;
2715     }
2716 
2717     napi_valuetype rectType = napi_undefined;
2718     napi_typeof(env, funcResult, &rectType);
2719     if (rectType != napi_object) {
2720         HILOG_ERROR("form rect type not napi_object");
2721         return false;
2722     }
2723     bool isItemValid = CreateFormRectInfo(env, funcResult, item);
2724     if (!isItemValid) {
2725         HILOG_ERROR("create form rect error");
2726         return false;
2727     }
2728 
2729     return true;
2730 }
2731 
RegisterGetLiveFormStatusListener(napi_env env,napi_ref callbackRef)2732 bool JsFormRouterProxyMgr::RegisterGetLiveFormStatusListener(napi_env env, napi_ref callbackRef)
2733 {
2734     HILOG_INFO("call");
2735     if (callbackRef == nullptr) {
2736         HILOG_ERROR("Invalid callback reference");
2737         return false;
2738     }
2739 
2740     if (getLiveFormStatusCallbackRef_ != nullptr) {
2741         napi_delete_reference(env, getLiveFormStatusCallbackRef_);
2742         getLiveFormStatusCallbackRef_ = nullptr;
2743     }
2744 
2745     getLiveFormStatusCallbackRef_ = callbackRef;
2746     getLiveFormStatusEnv_ = env;
2747 
2748     napi_value callback;
2749     napi_get_reference_value(env, callbackRef, &callback);
2750     napi_valuetype valueType;
2751     napi_typeof(env, callback, &valueType);
2752     if (valueType != napi_function) {
2753         HILOG_ERROR("Callback is not a function");
2754         return false;
2755     }
2756 
2757     HILOG_INFO("Listener registered successfully");
2758     return true;
2759 }
2760 
UnregisterGetLiveFormStatusListener()2761 bool JsFormRouterProxyMgr::UnregisterGetLiveFormStatusListener()
2762 {
2763     HILOG_INFO("call");
2764     getLiveFormStatusCallbackRef_ = nullptr;
2765     getLiveFormStatusEnv_ = nullptr;
2766     return true;
2767 }
2768 
GetLiveFormStatus(std::unordered_map<std::string,std::string> & liveFormStatusMap)2769 ErrCode JsFormRouterProxyMgr::GetLiveFormStatus(std::unordered_map<std::string, std::string> &liveFormStatusMap)
2770 {
2771     HILOG_INFO("call");
2772 
2773     LiveFormInterfaceParam* dataParam = new (std::nothrow) LiveFormInterfaceParam {};
2774     if (dataParam == nullptr) {
2775         HILOG_ERROR("Failed to new dataParam");
2776         return ERR_GET_INFO_FAILED;
2777     }
2778 
2779     auto task = [dataParam] () {
2780         JsFormRouterProxyMgr::GetInstance()->GetLiveFormStatusInner(dataParam);
2781         HILOG_INFO("getLiveFormStatus start notify.");
2782         std::unique_lock<std::mutex> lock(dataParam->mutex);
2783         dataParam->isReady = true;
2784         dataParam->condition.notify_all();
2785     };
2786 
2787     napi_send_event(getLiveFormStatusEnv_, task, napi_eprio_immediate);
2788     std::unique_lock<std::mutex> lock(dataParam->mutex);
2789     dataParam->condition.wait_for(
2790         lock, std::chrono::milliseconds(CALL_INRTERFACE_TIMEOUT_MILLS), [&] { return dataParam->isReady; });
2791     bool result = dataParam->result;
2792     liveFormStatusMap = std::move(dataParam->liveFormStatusMap);
2793     delete dataParam;
2794     return result ? ERR_OK : ERR_GET_INFO_FAILED;
2795 }
2796 
GetLiveFormStatusInner(LiveFormInterfaceParam * dataParam)2797 void JsFormRouterProxyMgr::GetLiveFormStatusInner(LiveFormInterfaceParam *dataParam)
2798 {
2799     HILOG_INFO("call");
2800     if (dataParam == nullptr) {
2801         HILOG_ERROR("null dataParam");
2802         return;
2803     }
2804     dataParam->result = false;
2805     napi_handle_scope scope = nullptr;
2806     napi_open_handle_scope(getLiveFormStatusEnv_, &scope);
2807     if (scope == nullptr) {
2808         HILOG_ERROR("null scope");
2809         return;
2810     }
2811 
2812     napi_value myCallback = nullptr;
2813     napi_get_reference_value(getLiveFormStatusEnv_, getLiveFormStatusCallbackRef_, &myCallback);
2814 
2815     napi_valuetype callbackType;
2816     napi_typeof(getLiveFormStatusEnv_, myCallback, &callbackType);
2817     if (callbackType != napi_function) {
2818         HILOG_ERROR("callbackType is not napi_function.");
2819         napi_close_handle_scope(getLiveFormStatusEnv_, scope);
2820         return;
2821     }
2822 
2823     napi_value callResult;
2824     napi_status status = napi_call_function(getLiveFormStatusEnv_, nullptr, myCallback, 0, nullptr, &callResult);
2825     if (status != napi_ok) {
2826         HILOG_ERROR("status is not napi_ok.");
2827         napi_close_handle_scope(getLiveFormStatusEnv_, scope);
2828         return;
2829     }
2830 
2831     napi_valuetype returnType;
2832     napi_typeof(getLiveFormStatusEnv_, callResult, &returnType);
2833     if (returnType == napi_undefined) {
2834         HILOG_ERROR("returnType is napi_undefined.");
2835         napi_close_handle_scope(getLiveFormStatusEnv_, scope);
2836         return;
2837     }
2838 
2839     HILOG_INFO("parse result");
2840     std::unordered_map<std::string, std::string> liveFormStatusMap;
2841     bool ret = ConvertNapiValueToMap(getLiveFormStatusEnv_, callResult, liveFormStatusMap);
2842     dataParam->result = ret;
2843     dataParam->liveFormStatusMap = liveFormStatusMap;
2844     napi_close_handle_scope(getLiveFormStatusEnv_, scope);
2845 }
2846 
ConvertNapiValueToMap(napi_env env,napi_value value,std::unordered_map<std::string,std::string> & uMap)2847 bool JsFormRouterProxyMgr::ConvertNapiValueToMap(
2848     napi_env env, napi_value value, std::unordered_map<std::string, std::string> &uMap)
2849 {
2850     if (value == nullptr) {
2851         HILOG_ERROR("The value is error.");
2852         return false;
2853     }
2854 
2855     napi_valuetype valueType;
2856     napi_typeof(env, value, &valueType);
2857     if (valueType != napi_object) {
2858         HILOG_ERROR("return type is not object");
2859         return false;
2860     }
2861 
2862     napi_value propNames;
2863     napi_get_property_names(env, value, &propNames);
2864 
2865     napi_valuetype propNamesType;
2866     napi_typeof(env, propNames, &propNamesType);
2867     if (propNamesType != napi_object) {
2868         HILOG_ERROR("propNamesType is not napi_object");
2869         return false;
2870     }
2871 
2872     uint32_t length;
2873     napi_status status = napi_get_array_length(env, propNames, &length);
2874     if (status != napi_ok) {
2875         HILOG_ERROR("get array length error");
2876         return false;
2877     }
2878     HILOG_INFO("length: %{public}d", length);
2879     for (uint32_t i = 0; i < length; ++i) {
2880         napi_value key;
2881         napi_get_element(env, propNames, i, &key);
2882 
2883         napi_valuetype keyType;
2884         napi_typeof(env, key, &keyType);
2885         if (keyType != napi_string) {
2886             HILOG_ERROR("keyType is not napi_string");
2887             continue;
2888         }
2889 
2890         napi_value valueObj;
2891         napi_get_property(env, value, key, &valueObj);
2892 
2893         napi_valuetype valType;
2894         napi_typeof(env, valueObj, &valType);
2895         if (valType != napi_string) {
2896             HILOG_ERROR("valType is not napi_string");
2897             continue;
2898         }
2899 
2900         std::string mKey = GetStringFromNapi(env, key);
2901         std::string mValue = GetStringFromNapi(env, valueObj);
2902         uMap.insert({mKey, mValue});
2903     }
2904     return true;
2905 }
2906 
PromiseCallbackInfo(LiveFormInterfaceParam * liveFormInterfaceParam)2907 PromiseCallbackInfo::PromiseCallbackInfo(LiveFormInterfaceParam* liveFormInterfaceParam)
2908     : liveFormInterfaceParam_(liveFormInterfaceParam)
2909 {}
2910 
2911 PromiseCallbackInfo::~PromiseCallbackInfo() = default;
2912 
Create(LiveFormInterfaceParam * liveFormInterfaceParam)2913 PromiseCallbackInfo* PromiseCallbackInfo::Create(LiveFormInterfaceParam* liveFormInterfaceParam)
2914 {
2915     return new (std::nothrow) PromiseCallbackInfo(liveFormInterfaceParam);
2916 }
2917 
Destroy(PromiseCallbackInfo * callbackInfo)2918 void PromiseCallbackInfo::Destroy(PromiseCallbackInfo *callbackInfo)
2919 {
2920     delete callbackInfo;
2921 }
2922 
GetJsCallBackParam()2923 LiveFormInterfaceParam* PromiseCallbackInfo::GetJsCallBackParam()
2924 {
2925     return liveFormInterfaceParam_;
2926 }
2927 } // namespace AbilityRuntime
2928 } // namespace OHOS
2929