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