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