• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_form_provider.h"
17 
18 #include <cinttypes>
19 #include <vector>
20 
21 #include "fms_log_wrapper.h"
22 #include "form_constants.h"
23 #ifdef NO_RUNTIME_EMULATOR
24 #include "form_event_hiappevent.h"
25 #endif
26 #include "form_instance.h"
27 #include "form_mgr_errors.h"
28 #include "form_mgr.h"
29 #include "running_form_info.h"
30 #include "js_runtime_utils.h"
31 #include "ipc_skeleton.h"
32 #include "napi_common_util.h"
33 #include "napi_common_want.h"
34 #include "napi_form_util.h"
35 #include "napi/native_api.h"
36 #include "napi/native_node_api.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 namespace {
46 constexpr size_t ARGS_SIZE_ZERO = 0;
47 constexpr size_t ARGS_SIZE_ONE = 1;
48 constexpr size_t ARGS_SIZE_TWO = 2;
49 constexpr size_t ARGS_SIZE_THREE = 3;
50 const std::string IS_FORM_AGENT = "isFormAgent";
51 enum class ActivationState : int32_t {
52     Deactivated = 0,
53     Activated = 1
54 };
55 
CheckParamNum(napi_env env,size_t argc,size_t minParamNum,size_t maxParamNum)56 bool CheckParamNum(napi_env env, size_t argc, size_t minParamNum, size_t maxParamNum)
57 {
58     HILOG_DEBUG("argc is %{public}zu,param range is [%{public}zu,%{public}zu]",
59         argc, minParamNum, maxParamNum);
60     if (argc > maxParamNum || argc < minParamNum) {
61         HILOG_ERROR("invalid param number %{public}zu", argc);
62         std::string errMsg = "[" + std::to_string(minParamNum) + ", " + std::to_string(maxParamNum) + "]";
63         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), errMsg);
64         return false;
65     }
66     return true;
67 }
68 
ConvertFormInfoFilterThrow(napi_env env,napi_value jsValue,AppExecFwk::FormInfoFilter & formInfoFilter)69 static bool ConvertFormInfoFilterThrow(napi_env env, napi_value jsValue, AppExecFwk::FormInfoFilter &formInfoFilter)
70 {
71     napi_valuetype jsValueType = napi_undefined;
72     napi_typeof(env, jsValue, &jsValueType);
73     if (jsValueType != napi_object) {
74         HILOG_ERROR("an object is expected, but an argument of different type is passed in");
75         NapiFormUtil::ThrowParamTypeError(env, "filter", "formInfo.FormInfoFilter");
76         return false;
77     }
78 
79     napi_value nativeDataValue = nullptr;
80     napi_status ret = napi_get_named_property(env, jsValue, "moduleName", &nativeDataValue);
81     if (ret != napi_ok) {
82         HILOG_ERROR("get property failed");
83         NapiFormUtil::ThrowParamError(env, "Failed to get property.");
84         return false;
85     }
86     napi_valuetype nativeDataValueType = napi_undefined;
87     napi_typeof(env, nativeDataValue, &nativeDataValueType);
88     if (nativeDataValue == nullptr || (nativeDataValueType != napi_undefined &&
89         !ConvertFromJsValue(env, nativeDataValue, formInfoFilter.moduleName))) {
90         HILOG_ERROR("convert nativeDataValue failed");
91         NapiFormUtil::ThrowParamError(env, "Failed to convert FormInfoFilter.");
92         return false;
93     }
94 
95     HILOG_INFO("module:%{public}s", formInfoFilter.moduleName.c_str());
96 
97     return true;
98 }
99 
ConvertFormId(napi_env env,napi_value jsValue,int64_t & formId)100 static bool ConvertFormId(napi_env env, napi_value jsValue, int64_t &formId)
101 {
102     std::string strFormId;
103     if (!ConvertFromJsValue(env, jsValue, strFormId)) {
104         HILOG_ERROR("convert strFormId failed");
105         return false;
106     }
107 
108     if (strFormId.empty()) {
109         HILOG_ERROR("empty strFormId");
110     }
111 
112     if (!ConvertStringToInt64(strFormId, formId)) {
113         HILOG_ERROR("convert string formId to int64 failed");
114         return false;
115     }
116     return true;
117 }
118 }
119 
GetStringByProp(napi_env env,napi_value value,const std::string & prop)120 static std::string GetStringByProp(napi_env env, napi_value value, const std::string &prop)
121 {
122     HILOG_DEBUG("GetStringByProp start");
123     std::string result;
124     bool propExist = false;
125     napi_value propValue = nullptr;
126     napi_valuetype valueType = napi_undefined;
127     napi_has_named_property(env, value, prop.c_str(), &propExist);
128     if (!propExist) {
129         HILOG_ERROR("prop[%{public}s] absent", prop.c_str());
130         return result;
131     }
132     napi_get_named_property(env, value, prop.c_str(), &propValue);
133     if (propValue == nullptr) {
134         HILOG_ERROR("prop[%{public}s] get error", prop.c_str());
135         return result;
136     }
137     napi_typeof(env, propValue, &valueType);
138     if (valueType != napi_string) {
139         HILOG_ERROR("prop[%{public}s] not string", prop.c_str());
140         return result;
141     }
142     size_t size = 0;
143     if (napi_get_value_string_utf8(env, propValue, nullptr, 0, &size) != napi_ok) {
144         HILOG_ERROR("prop[%{public}s] get size error", prop.c_str());
145         return result;
146     }
147     result.reserve(size + 1);
148     result.resize(size);
149     if (napi_get_value_string_utf8(env, propValue, result.data(), (size + 1), &size) != napi_ok) {
150         HILOG_ERROR("prop[%{public}s] get value error", prop.c_str());
151         return "";
152     }
153     return result;
154 }
155 
Finalizer(napi_env env,void * data,void * hint)156 void JsFormProvider::Finalizer(napi_env env, void *data, void *hint)
157 {
158     HILOG_INFO("call");
159     std::unique_ptr<JsFormProvider>(static_cast<JsFormProvider *>(data));
160 }
161 
GetFormsInfo(napi_env env,napi_callback_info info)162 napi_value JsFormProvider::GetFormsInfo(napi_env env, napi_callback_info info)
163 {
164     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetFormsInfo);
165 }
166 
OnGetFormsInfoParseParam(NapiParamPackage & napiParam,size_t & convertArgc,bool & isPromise,AppExecFwk::FormInfoFilter & formInfoFilter)167 bool JsFormProvider::OnGetFormsInfoParseParam(NapiParamPackage &napiParam,
168     size_t &convertArgc, bool &isPromise, AppExecFwk::FormInfoFilter &formInfoFilter)
169 {
170     napi_env env = napiParam.env;
171     size_t argc  = napiParam.argc;
172     napi_value* argv = napiParam.argv;
173     // GetformsInfo()
174     if (argc == ARGS_SIZE_ZERO) {
175         isPromise = true;
176     }
177     if (argc == ARGS_SIZE_ONE) {
178         napi_valuetype argvZeroType = napi_undefined;
179         napi_typeof(env, argv[PARAM0], &argvZeroType);
180         if (argvZeroType != napi_undefined) {
181             // GetformsInfo(*)
182             if (argvZeroType == napi_function) {
183                 // GetformsInfo(callback)
184                 isPromise = false;
185             } else {
186                 // GetformsInfo(*);GetformsInfo(fliter)
187                 if (ConvertFormInfoFilterThrow(env, argv[PARAM0], formInfoFilter)) {
188                     convertArgc++;
189                     isPromise = true;
190                 } else {
191                     // no default value
192                     return false;
193                 }
194             }
195         } else {
196             isPromise = true;
197         }
198     }
199 
200     if (argc >= ARGS_SIZE_TWO) {
201         napi_valuetype argvType = napi_undefined;
202         napi_typeof(env, argv[PARAM0], &argvType);
203         if (argvType != napi_undefined) {
204             if (argvType == napi_function) {
205                 // GetformsInfo(callback, *)
206                 isPromise = false;
207             } else {
208                 // GetformsInfo(fliter, *) || GetformsInfo(fliter, callback)
209                 if (ConvertFormInfoFilterThrow(env, argv[PARAM0], formInfoFilter)) {
210                     convertArgc++;
211                     // GetformsInfo(fliter, callback)
212                     napi_valuetype paramTwoType = napi_undefined;
213                     napi_typeof(env, argv[PARAM1], &paramTwoType);
214                     isPromise = paramTwoType != napi_function;
215                 } else {
216                     HILOG_ERROR("convert form info filter failed");
217                     return false;
218                 }
219             }
220         } else {
221             isPromise = true;
222         }
223     }
224     return true;
225 }
226 
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)227 napi_value JsFormProvider::OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
228 {
229     HILOG_DEBUG("call");
230 
231     size_t convertArgc = 0;
232     bool isPromise = false;
233     FormInfoFilter formInfoFilter;
234 
235     NapiParamPackage napiParam(env, argc, argv);
236 
237     if (!OnGetFormsInfoParseParam(napiParam, convertArgc, isPromise, formInfoFilter)) {
238         HILOG_ERROR("parse param failed");
239         return CreateJsUndefined(env);
240     }
241 
242     NapiAsyncTask::CompleteCallback complete =
243         [formInfoFilter](napi_env env, NapiAsyncTask &task, int32_t status) {
244             std::vector<FormInfo> formInfos;
245             auto ret = FormMgr::GetInstance().GetFormsInfo(formInfoFilter, formInfos);
246             if (ret != ERR_OK) {
247                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
248                 return;
249             }
250             task.ResolveWithNoError(env, CreateFormInfos(env, formInfos));
251         };
252 
253     napi_value lastParam = isPromise ? nullptr : argv[convertArgc];
254     napi_value result = nullptr;
255     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetFormsInfo",
256         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
257     return result;
258 }
259 
GetPublishedFormInfoById(napi_env env,napi_callback_info info)260 napi_value JsFormProvider::GetPublishedFormInfoById(napi_env env, napi_callback_info info)
261 {
262     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetPublishedFormInfoById);
263 }
264 
OnGetPublishedFormInfoById(napi_env env,size_t argc,napi_value * argv)265 napi_value JsFormProvider::OnGetPublishedFormInfoById(napi_env env, size_t argc, napi_value* argv)
266 {
267     HILOG_DEBUG("call");
268     if (CheckParamNum(env, argc, ARGS_SIZE_ONE, ARGS_SIZE_TWO) == false) {
269         return CreateJsUndefined(env);
270     }
271     napi_valuetype paramZeroType = napi_undefined;
272     napi_typeof(env, argv[PARAM0], &paramZeroType);
273     if (paramZeroType != napi_string) {
274         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
275         return CreateJsUndefined(env);
276     }
277     int64_t formId = 0;
278     std::string strFormId;
279     if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
280         HILOG_ERROR("ConvertFromJsValue failed");
281         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
282         return CreateJsUndefined(env);
283     }
284     if (!ConvertStringToInt64(strFormId, formId)) {
285         HILOG_ERROR("convert form string failed");
286         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
287         return CreateJsUndefined(env);
288     }
289 
290     HILOG_INFO("before GetPublishedFormInfoById, formId:%{public}" PRId64, formId);
291     NapiAsyncTask::CompleteCallback complete =
292         [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
293             RunningFormInfo formInfo;
294             auto ret = FormMgr::GetInstance().GetPublishedFormInfoById(formId, formInfo);
295             if (ret != ERR_OK) {
296                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
297                 return;
298             }
299             task.ResolveWithNoError(env, CreateRunningFormInfo(env, formInfo));
300         };
301 
302     napi_value lastParam = (argc == ARGS_SIZE_TWO) ? argv[PARAM1] : nullptr;
303     napi_value result = nullptr;
304     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetPublishedFormInfoById",
305         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
306     return result;
307 }
308 
GetPublishedFormInfos(napi_env env,napi_callback_info info)309 napi_value JsFormProvider::GetPublishedFormInfos(napi_env env, napi_callback_info info)
310 {
311     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetPublishedFormInfos);
312 }
313 
OnGetPublishedFormInfos(napi_env env,size_t argc,napi_value * argv)314 napi_value JsFormProvider::OnGetPublishedFormInfos(napi_env env, size_t argc, napi_value* argv)
315 {
316     HILOG_DEBUG("call");
317 
318     NapiAsyncTask::CompleteCallback complete =
319         [](napi_env env, NapiAsyncTask &task, int32_t status) {
320             std::vector<RunningFormInfo> formInfos;
321             auto ret = FormMgr::GetInstance().GetPublishedFormInfos(formInfos);
322             if (ret != ERR_OK) {
323                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
324                 return;
325             }
326             task.ResolveWithNoError(env, CreateRunningFormInfos(env, formInfos));
327         };
328 
329     napi_value result = nullptr;
330     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetPublishedFormInfos",
331         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
332     return result;
333 }
OpenFormManager(napi_env env,napi_callback_info info)334 napi_value JsFormProvider::OpenFormManager(napi_env env, napi_callback_info info)
335 {
336     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnOpenFormManager);
337 }
338 
OnOpenFormManager(napi_env env,size_t argc,napi_value * argv)339 napi_value JsFormProvider::OnOpenFormManager(napi_env env, size_t argc, napi_value* argv)
340 {
341     HILOG_DEBUG("call");
342     Want want;
343     if (!AppExecFwk::UnwrapWant(env, argv[PARAM0], want)) {
344         HILOG_ERROR("fail convert want");
345         NapiFormUtil::ThrowParamError(env, "Failed to convert want.");
346         return CreateJsUndefined(env);
347     }
348 
349     const std::string bundleName = want.GetBundle();
350     const std::string abilityName = want.GetElement().GetAbilityName();
351     want.SetElementName(bundleName, abilityName);
352     want.SetAction(AppExecFwk::Constants::FORM_PAGE_ACTION);
353     want.SetParam(AppExecFwk::Constants::PARAM_PAGE_ROUTER_SERVICE_CODE,
354                   AppExecFwk::Constants::PAGE_ROUTER_SERVICE_CODE_FORM_MANAGE);
355     const std::string key = AppExecFwk::Constants::PARMA_REQUEST_METHOD;
356     const std::string value = AppExecFwk::Constants::OPEN_FORM_MANAGE_VIEW;
357     want.SetParam(key, value);
358     HILOG_DEBUG("JsFormProvider OnOpenFormManager want:%{public}s", want.ToString().c_str());
359 
360     NapiAsyncTask::CompleteCallback complete =
361             [want](napi_env env, NapiAsyncTask &task, int32_t status) {
362 #ifdef NO_RUNTIME_EMULATOR
363                 int64_t processorId = FormEventHiAppEvent::AddProcessor();
364                 HILOG_INFO("Add processor begin.Processor id is %{public}" PRId64, processorId);
365                 time_t beginTime = time(nullptr);
366 #endif
367                 auto ret = FormMgr::GetInstance().StartAbilityByFms(want);
368 #ifdef NO_RUNTIME_EMULATOR
369                 PublishFormData publishFormData = {want.GetBundle(), want.GetElement().GetAbilityName(),
370                     want.GetIntParam(Constants::PARAM_FORM_DIMENSION_KEY, -1),
371                     want.GetStringParam(Constants::PARAM_MODULE_NAME_KEY),
372                     want.GetStringParam(Constants::PARAM_FORM_NAME_KEY)};
373                 FormEventHiAppEvent::WriteAppFormEndEvent(ret, beginTime, "OpenFormManager", publishFormData,
374                     processorId);
375 #endif
376                 if (ret != ERR_OK) {
377                     task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
378                     return;
379                 }
380                 task.ResolveWithNoError(env, CreateJsUndefined(env));
381             };
382 
383     napi_value result = nullptr;
384     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnOpenFormManager",
385         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
386     return result;
387 }
388 
OpenFormManagerCrossBundle(napi_env env,napi_callback_info info)389 napi_value JsFormProvider::OpenFormManagerCrossBundle(napi_env env, napi_callback_info info)
390 {
391     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnOpenFormManagerCrossBundle);
392 }
393 
OnOpenFormManagerCrossBundle(napi_env env,size_t argc,napi_value * argv)394 napi_value JsFormProvider::OnOpenFormManagerCrossBundle(napi_env env, size_t argc, napi_value* argv)
395 {
396     HILOG_DEBUG("call");
397 #ifdef NO_RUNTIME_EMULATOR
398     int64_t processorId = FormEventHiAppEvent::AddProcessor();
399     HILOG_INFO("Add processor begin.Processor id is %{public}" PRId64, processorId);
400     time_t beginTime = time(nullptr);
401 #endif
402     Want want;
403     if (!AppExecFwk::UnwrapWant(env, argv[PARAM0], want)) {
404         HILOG_ERROR("fail convert want");
405         NapiFormUtil::ThrowParamError(env, "Failed to convert want.");
406         return CreateJsUndefined(env);
407     }
408 
409     const std::string bundleName = want.GetBundle();
410     const std::string abilityName = want.GetElement().GetAbilityName();
411     want.SetElementName(bundleName, abilityName);
412     want.SetAction(AppExecFwk::Constants::FORM_PAGE_ACTION);
413     want.SetParam(AppExecFwk::Constants::PARAM_PAGE_ROUTER_SERVICE_CODE,
414                   AppExecFwk::Constants::PAGE_ROUTER_SERVICE_CODE_FORM_MANAGE);
415     const std::string key = AppExecFwk::Constants::PARMA_REQUEST_METHOD;
416     const std::string value = AppExecFwk::Constants::OPEN_FORM_MANAGE_VIEW;
417     want.SetParam(key, value);
418     HILOG_DEBUG("JsFormProvider OnOpenFormManagerCrossBundle want:%{public}s", want.ToString().c_str());
419 
420     auto ret = FormMgr::GetInstance().StartAbilityByCrossBundle(want);
421     if (ret != ERR_OK) {
422         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
423     }
424 #ifdef NO_RUNTIME_EMULATOR
425     PublishFormData publishFormData = {want.GetBundle(), want.GetElement().GetAbilityName(),
426         want.GetIntParam(Constants::PARAM_FORM_DIMENSION_KEY, -1),
427         want.GetStringParam(Constants::PARAM_MODULE_NAME_KEY),
428         want.GetStringParam(Constants::PARAM_FORM_NAME_KEY)};
429     FormEventHiAppEvent::WriteAppFormEndEvent(ret, beginTime, "OpenFormManagerCrossBundle", publishFormData,
430         processorId);
431 #endif
432     return CreateJsUndefined(env);
433 }
434 
SetFormNextRefreshTime(napi_env env,napi_callback_info info)435 napi_value JsFormProvider::SetFormNextRefreshTime(napi_env env, napi_callback_info info)
436 {
437     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnSetFormNextRefreshTime);
438 }
439 
OnSetFormNextRefreshTime(napi_env env,size_t argc,napi_value * argv)440 napi_value JsFormProvider::OnSetFormNextRefreshTime(napi_env env, size_t argc, napi_value* argv)
441 {
442     HILOG_DEBUG("call");
443     if (CheckParamNum(env, argc, ARGS_SIZE_TWO, ARGS_SIZE_THREE) == false) {
444         return CreateJsUndefined(env);
445     }
446     napi_valuetype paramZeroType = napi_undefined;
447     napi_typeof(env, argv[PARAM0], &paramZeroType);
448     if (paramZeroType != napi_string) {
449         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
450         return CreateJsUndefined(env);
451     }
452     int64_t formId = 0;
453     std::string strFormId;
454     if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
455         HILOG_ERROR("ConvertFromJsValue failed");
456         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
457         return CreateJsUndefined(env);
458     }
459     if (!ConvertStringToInt64(strFormId, formId)) {
460         HILOG_ERROR("convert form string failed");
461         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
462         return CreateJsUndefined(env);
463     }
464     napi_valuetype paramOneType = napi_undefined;
465     napi_typeof(env, argv[PARAM1], &paramOneType);
466     if (paramOneType != napi_number) {
467         NapiFormUtil::ThrowParamTypeError(env, "minute", "number");
468         return CreateJsUndefined(env);
469     }
470     int32_t time;
471     if (!ConvertFromJsValue(env, argv[PARAM1], time)) {
472         NapiFormUtil::ThrowParamTypeError(env, "minute", "number");
473         return CreateJsUndefined(env);
474     }
475     NapiAsyncTask::CompleteCallback complete = [formId, time](napi_env env, NapiAsyncTask &task, int32_t status) {
476         int32_t ret = FormMgr::GetInstance().SetNextRefreshTime(formId, time);
477         if (ret != ERR_OK) {
478             task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
479             return;
480         }
481         task.ResolveWithNoError(env, CreateJsUndefined(env));
482     };
483     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
484     napi_value result = nullptr;
485     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnSetFormNextRefreshTime",
486         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
487     return result;
488 }
489 
UpdateForm(napi_env env,napi_callback_info info)490 napi_value JsFormProvider::UpdateForm(napi_env env, napi_callback_info info)
491 {
492     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnUpdateForm);
493 }
494 
OnUpdateFormParseParam(napi_env env,size_t argc,napi_value * argv,int64_t & formId)495 napi_value JsFormProvider::OnUpdateFormParseParam(napi_env env, size_t argc, napi_value* argv, int64_t &formId)
496 {
497     if (CheckParamNum(env, argc, ARGS_SIZE_TWO, ARGS_SIZE_THREE) == false) {
498         return CreateJsUndefined(env);
499     }
500     if (!ConvertFormId(env, argv[PARAM0], formId)) {
501         HILOG_ERROR("convert form string failed");
502         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
503         return CreateJsUndefined(env);
504     }
505     napi_valuetype paramOneType = napi_undefined;
506     napi_typeof(env, argv[PARAM1], &paramOneType);
507     if (paramOneType != napi_object) {
508         HILOG_ERROR("formBindingData not napi_object");
509         NapiFormUtil::ThrowParamTypeError(env, "formBindingData", "formBindingData.FormBindingData");
510         return CreateJsUndefined(env);
511     }
512     return nullptr;
513 }
514 
OnUpdateForm(napi_env env,size_t argc,napi_value * argv)515 napi_value JsFormProvider::OnUpdateForm(napi_env env, size_t argc, napi_value* argv)
516 {
517     HILOG_DEBUG("call");
518 
519     int64_t formId = 0;
520     napi_value parseResult = OnUpdateFormParseParam(env, argc, argv, formId);
521     if (parseResult != nullptr) {
522         HILOG_ERROR("parse param failed");
523         return parseResult;
524     }
525 
526     auto formProviderData = std::make_shared<OHOS::AppExecFwk::FormProviderData>();
527     std::string formDataStr = GetStringByProp(env, argv[PARAM1], "data");
528     formProviderData->SetDataString(formDataStr);
529     formProviderData->ParseImagesData();
530 
531     std::vector<AppExecFwk::FormDataProxy> formDataProxies;
532     napi_value nativeProxies = nullptr;
533     napi_get_named_property(env, argv[PARAM1], "proxies", &nativeProxies);
534     if (nativeProxies != nullptr) {
535         ConvertFromDataProxies(env, nativeProxies, formDataProxies);
536     }
537 
538     NapiAsyncTask::CompleteCallback complete =
539         [formId, data = formProviderData, formDataProxies](napi_env env, NapiAsyncTask &task, int32_t status) {
540             int32_t ret = FormMgr::GetInstance().UpdateForm(formId, *data, formDataProxies);
541             if (ret != ERR_OK) {
542                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
543                 return;
544             }
545             task.ResolveWithNoError(env, CreateJsUndefined(env));
546         };
547     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
548     napi_value result = nullptr;
549     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnUpdateForm",
550         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
551     return result;
552 }
553 
IsRequestPublishFormSupported(napi_env env,napi_callback_info info)554 napi_value JsFormProvider::IsRequestPublishFormSupported(napi_env env, napi_callback_info info)
555 {
556     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnIsRequestPublishFormSupported);
557 }
558 
OnIsRequestPublishFormSupported(napi_env env,size_t argc,napi_value * argv)559 napi_value JsFormProvider::OnIsRequestPublishFormSupported(napi_env env, size_t argc, napi_value* argv)
560 {
561     HILOG_DEBUG("call");
562     if (CheckParamNum(env, argc, ARGS_SIZE_ZERO, ARGS_SIZE_ONE) == false) {
563         return CreateJsUndefined(env);
564     }
565 
566     auto selfToken = IPCSkeleton::GetSelfTokenID();
567     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
568         HILOG_ERROR("The application not system-app,can't use system-api");
569         NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
570         return CreateJsUndefined(env);
571     }
572 
573     NapiAsyncTask::CompleteCallback complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
574         bool value = FormMgr::GetInstance().IsRequestPublishFormSupported();
575         napi_value jsValue = nullptr;
576         napi_get_boolean(env, value, &jsValue);
577         task.ResolveWithNoError(env, jsValue);
578     };
579     napi_value lastParam = (argc == ARGS_SIZE_ONE) ? argv[PARAM0] : nullptr;
580     napi_value result = nullptr;
581     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnIsRequestPublishFormSupported",
582         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
583     return result;
584 }
585 
RequestPublishForm(napi_env env,napi_callback_info info)586 napi_value JsFormProvider::RequestPublishForm(napi_env env, napi_callback_info info)
587 {
588     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnRequestPublishForm);
589 }
590 
OnRequestPublishForm(napi_env env,size_t argc,napi_value * argv)591 napi_value JsFormProvider::OnRequestPublishForm(napi_env env, size_t argc, napi_value* argv)
592 {
593     HILOG_DEBUG("call");
594     if (CheckParamNum(env, argc, ARGS_SIZE_ONE, ARGS_SIZE_THREE) == false) {
595         return CreateJsUndefined(env);
596     }
597 
598     auto asyncCallbackInfo = std::make_shared<RequestPublishFormCallbackInfo>();
599     decltype(argc) convertArgc = 0;
600     napi_valuetype paramZeroType = napi_undefined;
601     napi_typeof(env, argv[PARAM0], &paramZeroType);
602     if (paramZeroType != napi_object) {
603         HILOG_ERROR("formId not napi_object");
604         NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
605         return CreateJsUndefined(env);
606     }
607     if (!AppExecFwk::UnwrapWant(env, argv[PARAM0], asyncCallbackInfo->want)) {
608         HILOG_ERROR("fail convert want");
609         NapiFormUtil::ThrowParamError(env, "Failed to convert want.");
610         return CreateJsUndefined(env);
611     }
612     convertArgc++;
613 
614     if (argc > ARGS_SIZE_ONE) {
615         napi_valuetype paramOneType = napi_undefined;
616         napi_typeof(env, argv[PARAM1], &paramOneType);
617         if (paramOneType == napi_object) {
618             asyncCallbackInfo->withFormBindingData = true;
619             auto formProviderData = std::make_unique<FormProviderData>();
620             std::string formDataStr = GetStringByProp(env, argv[PARAM1], "data");
621             formProviderData->SetDataString(formDataStr);
622             formProviderData->ParseImagesData();
623             asyncCallbackInfo->formProviderData = std::move(formProviderData);
624 
625             napi_value nativeProxies = nullptr;
626             napi_get_named_property(env, argv[PARAM1], "proxies", &nativeProxies);
627             if (nativeProxies != nullptr) {
628                 ConvertFromDataProxies(env, nativeProxies, asyncCallbackInfo->formDataProxies);
629             }
630             convertArgc++;
631         } else if (paramOneType == napi_function) {
632             asyncCallbackInfo->withFormBindingData = false;
633         } else {
634             HILOG_ERROR("formBindingData not napi_object");
635             NapiFormUtil::ThrowParamTypeError(env, "formBindingData", "formBindingData.FormBindingData");
636             return CreateJsUndefined(env);
637         }
638     }
639 
640     NapiAsyncTask::CompleteCallback complete = [asyncCallbackInfo](napi_env env, NapiAsyncTask &task, int32_t status) {
641         int64_t formId = 0;
642         asyncCallbackInfo->want.SetParam(IS_FORM_AGENT, false);
643         ErrCode ret = FormMgr::GetInstance().RequestPublishForm(asyncCallbackInfo->want,
644             asyncCallbackInfo->withFormBindingData, asyncCallbackInfo->formProviderData, formId,
645             asyncCallbackInfo->formDataProxies);
646         if (ret != ERR_OK) {
647             task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
648             return;
649         }
650         std::string formIdStr = std::to_string(formId);
651         napi_value result = nullptr;
652         napi_create_string_utf8(env, formIdStr.c_str(), formIdStr.size(), &result);
653         task.ResolveWithNoError(env, result);
654     };
655     napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
656     napi_value result = nullptr;
657     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnRequestPublishForm",
658         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
659     return result;
660 }
661 
ConvertFromDataProxies(napi_env env,napi_value value,std::vector<AppExecFwk::FormDataProxy> & formDataProxies)662 bool JsFormProvider::ConvertFromDataProxies(napi_env env, napi_value value,
663     std::vector<AppExecFwk::FormDataProxy> &formDataProxies)
664 {
665     bool result = false;
666     napi_is_array(env, value, &result);
667     if (value == nullptr || !result) {
668         HILOG_WARN("null jsValue not array");
669         return false;
670     }
671 
672     uint32_t length = 0;
673     napi_get_array_length(env, value, &length);
674     napi_value element = nullptr;
675     for (uint32_t i = 0; i < length; i++) {
676         AppExecFwk::FormDataProxy formDataProxy("", "");
677         napi_get_element(env, value, i, &element);
678         if (!ConvertFormDataProxy(env, element, formDataProxy)) {
679             HILOG_ERROR("GetElement from array [%{public}u] error", i);
680             continue;
681         }
682         formDataProxies.push_back(formDataProxy);
683     }
684     return true;
685 }
686 
ConvertFormDataProxy(napi_env env,napi_value value,AppExecFwk::FormDataProxy & formDataProxy)687 bool JsFormProvider::ConvertFormDataProxy(napi_env env, napi_value value,
688     AppExecFwk::FormDataProxy &formDataProxy)
689 {
690     napi_valuetype valueType = napi_undefined;
691     napi_typeof(env, value, &valueType);
692     if (value == nullptr || valueType != napi_object) {
693         HILOG_WARN("null jsValue,not object");
694         return false;
695     }
696 
697     napi_value key = nullptr;
698     napi_get_named_property(env, value, "key", &key);
699     if (!ConvertFromJsValue(env, key, formDataProxy.key)) {
700         HILOG_ERROR("Parse key error");
701         return false;
702     }
703 
704     napi_value subscribeId = nullptr;
705     napi_get_named_property(env, value, "subscriberId", &subscribeId);
706     if (subscribeId != nullptr && !ConvertFromJsValue(env, subscribeId, formDataProxy.subscribeId)) {
707         HILOG_WARN("Parse subscribeId failed, use empty as default value");
708         formDataProxy.subscribeId = "";
709     }
710     HILOG_INFO("key:%{public}s,subscribeId:%{public}s", formDataProxy.key.c_str(),
711         formDataProxy.subscribeId.c_str());
712     return true;
713 }
714 
OpenFormEditAbility(napi_env env,napi_callback_info info)715 napi_value JsFormProvider::OpenFormEditAbility(napi_env env, napi_callback_info info)
716 {
717     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnOpenFormEditAbility);
718 }
719 
OnOpenFormEditAbility(napi_env env,size_t argc,napi_value * argv)720 napi_value JsFormProvider::OnOpenFormEditAbility(napi_env env, size_t argc, napi_value* argv)
721 {
722     HILOG_DEBUG("call");
723     if (!CheckParamNum(env, argc, ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
724         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2 or 3");
725         return CreateJsUndefined(env);
726     }
727     std::string abilityName;
728     if (!ConvertFromJsValue(env, argv[PARAM0], abilityName)) {
729         HILOG_ERROR("ConvertFromJsValue failed");
730         NapiFormUtil::ThrowParamTypeError(env, "abilityName", "string");
731         return CreateJsUndefined(env);
732     }
733 
734     int64_t formId = 0;
735     if (!ConvertFormId(env, argv[PARAM1], formId)) {
736         HILOG_ERROR("ConvertFromJsValue");
737         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
738         return CreateJsUndefined(env);
739     }
740 
741     bool isMainPage = true;
742     if (argc == ARGS_SIZE_THREE) {
743         if (!ConvertFromJsValue(env, argv[PARAM2], isMainPage)) {
744             isMainPage = true;
745         }
746     }
747     HILOG_INFO("OnOpenFormEditAbility abilityName: %{public}s, formId: %{public}" PRId64 "isMainPage: %{public}s",
748         abilityName.c_str(), formId, isMainPage ? "true" : "false");
749     auto ret = FormMgr::GetInstance().OpenFormEditAbility(abilityName, formId, isMainPage);
750     if (ret != ERR_OK) {
751         NapiFormUtil::ThrowByInternalErrorCode(env, ret);
752     }
753     return CreateJsUndefined(env);
754 }
755 
RequestOverflow(napi_env env,napi_callback_info info)756 napi_value JsFormProvider::RequestOverflow(napi_env env, napi_callback_info info)
757 {
758     HILOG_INFO("Call");
759     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnRequestOverflow);
760 }
761 
OnRequestOverflow(napi_env env,size_t argc,napi_value * argv)762 napi_value JsFormProvider::OnRequestOverflow(napi_env env, size_t argc, napi_value* argv)
763 {
764     HILOG_INFO("Call");
765     if (argc != ARGS_SIZE_TWO) {
766         HILOG_ERROR("Wrong number of arguments");
767         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "2");
768         return CreateJsUndefined(env);
769     }
770 
771     int64_t formId = 0;
772     if (!ConvertFormId(env, argv[PARAM0], formId)) {
773         HILOG_ERROR("Convert formId failed, formId:%{public}" PRId64 ".", formId);
774         NapiFormUtil::ThrowParamError(env, "The formId is invalid");
775         return CreateJsUndefined(env);
776     }
777 
778     AppExecFwk::OverflowInfo* overflowInfo = new (std::nothrow) AppExecFwk::OverflowInfo {};
779     if (overflowInfo == nullptr) {
780         HILOG_ERROR("Failed to new overflowInfo");
781         return CreateJsUndefined(env);
782     }
783     if (!ConvertFormOverflowInfo(env, argv[PARAM1], overflowInfo)) {
784         HILOG_ERROR("convert overflowInfo failed");
785         delete overflowInfo;
786         NapiFormUtil::ThrowParamError(env, "The overflowInfo is invalid");
787         return CreateJsUndefined(env);
788     }
789 
790     NapiAsyncTask::CompleteCallback complete =
791         [formId, overflowInfo](napi_env env, NapiAsyncTask &task, int32_t status) {
792             ErrCode ret = FormMgr::GetInstance().RequestOverflow(formId, *overflowInfo, true);
793             delete overflowInfo;
794             if (ret != ERR_OK) {
795                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
796                 return;
797             }
798             task.ResolveWithNoError(env, CreateJsUndefined(env));
799         };
800     napi_value result = nullptr;
801     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnRequestOverflow",
802         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
803     return result;
804 }
805 
CancelOverflow(napi_env env,napi_callback_info info)806 napi_value JsFormProvider::CancelOverflow(napi_env env, napi_callback_info info)
807 {
808     HILOG_INFO("call");
809     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnCancelOverflow);
810 }
811 
OnCancelOverflow(napi_env env,size_t argc,napi_value * argv)812 napi_value JsFormProvider::OnCancelOverflow(napi_env env, size_t argc, napi_value* argv)
813 {
814     HILOG_INFO("call");
815     if (argc != ARGS_SIZE_ONE) {
816         HILOG_ERROR("wrong number of arguments");
817         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
818         return CreateJsUndefined(env);
819     }
820 
821     int64_t formId = 0;
822     if (!ConvertFormId(env, argv[PARAM0], formId)) {
823         HILOG_ERROR("convert formId failed, formId:%{public}" PRId64 ".", formId);
824         NapiFormUtil::ThrowParamError(env, "The formId is invalid");
825         return CreateJsUndefined(env);
826     }
827 
828     AppExecFwk::OverflowInfo* overflowInfo = new (std::nothrow) AppExecFwk::OverflowInfo {};
829     if (overflowInfo == nullptr) {
830         HILOG_ERROR("Failed to new overflowInfo");
831         return CreateJsUndefined(env);
832     }
833     NapiAsyncTask::CompleteCallback complete =
834         [formId, overflowInfo](napi_env env, NapiAsyncTask &task, int32_t status) {
835             HILOG_INFO("complete");
836             bool ret = FormMgr::GetInstance().RequestOverflow(formId, *overflowInfo, false);
837             delete overflowInfo;
838             if (!ret) {
839                 HILOG_INFO("complete ret false");
840                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
841                 return;
842             }
843             HILOG_INFO("complete ret true");
844             napi_value jsValue = nullptr;
845             napi_get_boolean(env, ret, &jsValue);
846             task.ResolveWithNoError(env, jsValue);
847         };
848     napi_value result = nullptr;
849     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnCancelOverflow",
850         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
851     HILOG_INFO("call end");
852     return result;
853 }
854 
ActivateSceneAnimation(napi_env env,napi_callback_info info)855 napi_value JsFormProvider::ActivateSceneAnimation(napi_env env, napi_callback_info info)
856 {
857     HILOG_INFO("call");
858     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnActivateSceneAnimation);
859 }
860 
OnActivateSceneAnimation(napi_env env,size_t argc,napi_value * argv)861 napi_value JsFormProvider::OnActivateSceneAnimation(napi_env env, size_t argc, napi_value* argv)
862 {
863     HILOG_INFO("call");
864     if (argc != ARGS_SIZE_ONE) {
865         HILOG_ERROR("OnActivateSceneAnimation wrong number of arguments.");
866         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
867         return CreateJsUndefined(env);
868     }
869 
870     int64_t formId;
871     if (!ConvertFormId(env, argv[PARAM0], formId)) {
872         HILOG_ERROR("Convert formId failed, formId:%{public}" PRId64 ".", formId);
873         NapiFormUtil::ThrowParamError(env, "The formId is invalid");
874         return CreateJsUndefined(env);
875     }
876 
877     NapiAsyncTask::CompleteCallback complete =
878         [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
879             ErrCode ret = FormMgr::GetInstance().ChangeSceneAnimationState(formId,
880                 static_cast<int32_t>(ActivationState::Activated));
881             if (ret != ERR_OK) {
882                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
883                 return;
884             }
885             task.ResolveWithNoError(env, CreateJsUndefined(env));
886         };
887     napi_value result = nullptr;
888     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnActivateSceneAnimation",
889         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
890     return result;
891 }
892 
DeactivateSceneAnimation(napi_env env,napi_callback_info info)893 napi_value JsFormProvider::DeactivateSceneAnimation(napi_env env, napi_callback_info info)
894 {
895     HILOG_INFO("call");
896     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnDeactivateSceneAnimation);
897 }
898 
OnDeactivateSceneAnimation(napi_env env,size_t argc,napi_value * argv)899 napi_value JsFormProvider::OnDeactivateSceneAnimation(napi_env env, size_t argc, napi_value* argv)
900 {
901     HILOG_INFO("call");
902     if (argc != ARGS_SIZE_ONE) {
903         HILOG_ERROR("OnDeactivateSceneAnimation wrong number of arguments");
904         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
905         return CreateJsUndefined(env);
906     }
907 
908     int64_t formId;
909     if (!ConvertFormId(env, argv[PARAM0], formId)) {
910         HILOG_ERROR("Convert formId failed, formId:%{public}" PRId64 ".", formId);
911         NapiFormUtil::ThrowParamError(env, "The formId is invalid");
912         return CreateJsUndefined(env);
913     }
914 
915     NapiAsyncTask::CompleteCallback complete =
916         [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
917             ErrCode ret = FormMgr::GetInstance().ChangeSceneAnimationState(formId,
918                 static_cast<int32_t>(ActivationState::Deactivated));
919             if (ret != ERR_OK) {
920                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
921                 return;
922             }
923             task.ResolveWithNoError(env, CreateJsUndefined(env));
924         };
925     napi_value result = nullptr;
926     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnDeactivateSceneAnimation",
927         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
928     return result;
929 }
930 
ConvertFormOverflowInfo(napi_env env,napi_value argv,AppExecFwk::OverflowInfo * overflowInfo)931 bool JsFormProvider::ConvertFormOverflowInfo(napi_env env, napi_value argv, AppExecFwk::OverflowInfo* overflowInfo)
932 {
933     HILOG_INFO("call");
934     napi_valuetype type = napi_undefined;
935     napi_typeof(env, argv, &type);
936     if (type != napi_object) {
937         HILOG_ERROR("not napi_object");
938         return false;
939     }
940     napi_value rangeArea = nullptr;
941     napi_status areaRet = napi_get_named_property(env, argv, "area", &rangeArea);
942     if (areaRet != napi_ok) {
943         HILOG_ERROR("get overflowInfo area failed");
944         return false;
945     }
946     napi_value rangeDuration;
947     napi_status durationRet = napi_get_named_property(env, argv, "duration", &rangeDuration);
948     int32_t duration = -1;
949     if (durationRet != napi_ok) {
950         HILOG_WARN("get overflowInfo duration failed");
951         return false;
952     }
953     if (!ConvertFromJsValue(env, rangeDuration, duration)) {
954         HILOG_ERROR("ConvertFromJsValue duration failed");
955         return false;
956     }
957     overflowInfo->duration = duration;
958     HILOG_INFO("ConvertFormOverflowInfo duration: %{public}d", duration);
959 
960     napi_value defaultAnimateNapiVal;
961     napi_status defaultAnimateRet = napi_get_named_property(env, argv, "useDefaultAnimation", &defaultAnimateNapiVal);
962     bool defaultAnimation = true;
963     if (defaultAnimateRet == napi_ok) {
964         if (!ConvertFromJsValue(env, defaultAnimateNapiVal, defaultAnimation)) {
965             HILOG_ERROR("ConvertFormOverflowInfo defaultAnimation: failed");
966         }
967     } else {
968         HILOG_WARN("get overflowInfo defaultAnimation failed");
969     }
970     overflowInfo->useDefaultAnimation = defaultAnimation;
971     HILOG_INFO("ConvertFormOverflowInfo defaultAnimation: %{public}d", defaultAnimation);
972 
973     AppExecFwk::Rect area;
974     if (!ConvertOverflowInfoArea(env, rangeArea, area)) {
975         HILOG_ERROR("get overflowInfo area failed");
976         return false;
977     }
978     overflowInfo->area = area;
979     HILOG_INFO("ConvertFormOverflowInfo rect: %{public}f, %{public}f, %{public}f, %{public}f",
980         area.left, area.top, area.width, area.height);
981     return true;
982 }
983 
GetAndConvertProperty(napi_env env,napi_value object,const char * propertyName,double & outValue)984 bool JsFormProvider::GetAndConvertProperty(napi_env env, napi_value object, const char* propertyName, double& outValue)
985 {
986     napi_value propertyValue;
987     napi_status status = napi_get_named_property(env, object, propertyName, &propertyValue);
988     if (status != napi_ok) {
989         HILOG_ERROR("Failed to get property: %{public}s", propertyName);
990         return false;
991     }
992     if (!ConvertFromJsValue(env, propertyValue, outValue)) {
993         HILOG_ERROR("ConvertFromJsValue %{public}s failed", propertyName);
994         return false;
995     }
996     return true;
997 }
998 
ConvertOverflowInfoArea(napi_env env,napi_value rangeArea,AppExecFwk::Rect & area)999 bool JsFormProvider::ConvertOverflowInfoArea(napi_env env, napi_value rangeArea, AppExecFwk::Rect &area)
1000 {
1001     napi_valuetype type = napi_undefined;
1002     napi_typeof(env, rangeArea, &type);
1003     if (type == napi_undefined || type == napi_null) {
1004         HILOG_ERROR("input rangeArea is undefined or null");
1005         return false;
1006     }
1007     if (!GetAndConvertProperty(env, rangeArea, "left", area.left) ||
1008         !GetAndConvertProperty(env, rangeArea, "top", area.top) ||
1009         !GetAndConvertProperty(env, rangeArea, "width", area.width) ||
1010         !GetAndConvertProperty(env, rangeArea, "height", area.height)) {
1011         return false;
1012     }
1013     return true;
1014 }
1015 
GetFormRect(napi_env env,napi_callback_info info)1016 napi_value JsFormProvider::GetFormRect(napi_env env, napi_callback_info info)
1017 {
1018     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetFormRect);
1019 }
1020 
CreateFormRect(napi_env env,const AppExecFwk::Rect & rect)1021 napi_value CreateFormRect(napi_env env, const AppExecFwk::Rect &rect)
1022 {
1023     HILOG_DEBUG("call");
1024 
1025     napi_value objContext = nullptr;
1026     napi_create_object(env, &objContext);
1027 
1028     napi_set_named_property(env, objContext, "left", CreateJsValue(env, rect.left));
1029     napi_set_named_property(env, objContext, "top", CreateJsValue(env, rect.top));
1030     napi_set_named_property(env, objContext, "width", CreateJsValue(env, rect.width));
1031     napi_set_named_property(env, objContext, "height", CreateJsValue(env, rect.height));
1032 
1033     return objContext;
1034 }
1035 
OnGetFormRect(napi_env env,size_t argc,napi_value * argv)1036 napi_value JsFormProvider::OnGetFormRect(napi_env env, size_t argc, napi_value* argv)
1037 {
1038     HILOG_INFO("call");
1039     if (argc != ARGS_SIZE_ONE) {
1040         HILOG_ERROR("OnGetFormRect wrong number of arguments.");
1041         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), "1");
1042         return CreateJsUndefined(env);
1043     }
1044 
1045     int64_t formId;
1046     if (!ConvertFormId(env, argv[PARAM0], formId)) {
1047         HILOG_ERROR("OnGetFormRect convert formId failed.");
1048         NapiFormUtil::ThrowParamError(env, "The formId is invalid");
1049         return CreateJsUndefined(env);
1050     }
1051 
1052     NapiAsyncTask::CompleteCallback complete =
1053         [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
1054             HILOG_INFO("OnGetFormRect start");
1055             AppExecFwk::Rect item;
1056             ErrCode ret = FormMgr::GetInstance().GetFormRect(formId, item);
1057             if (ret != ERR_OK) {
1058                 HILOG_INFO("OnGetFormRect failed, code:%{public}d", ret);
1059                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1060                 return;
1061             }
1062             task.ResolveWithNoError(env, CreateFormRect(env, item));
1063         };
1064     napi_value result = nullptr;
1065     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetFormRect",
1066         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
1067     return result;
1068 }
1069 
GetPublishedRunningFormInfos(napi_env env,napi_callback_info info)1070 napi_value JsFormProvider::GetPublishedRunningFormInfos(napi_env env, napi_callback_info info)
1071 {
1072     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetPublishedRunningFormInfos);
1073 }
1074 
OnGetPublishedRunningFormInfos(napi_env env,size_t argc,napi_value * argv)1075 napi_value JsFormProvider::OnGetPublishedRunningFormInfos(napi_env env, size_t argc, napi_value* argv)
1076 {
1077     HILOG_DEBUG("call");
1078 
1079     NapiAsyncTask::CompleteCallback complete =
1080         [](napi_env env, NapiAsyncTask &task, int32_t status) {
1081             std::vector<RunningFormInfo> runningFormInfos;
1082             auto ret = FormMgr::GetInstance().GetPublishedFormInfos(runningFormInfos);
1083             if (ret != ERR_OK) {
1084                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1085                 return;
1086             }
1087             task.ResolveWithNoError(env, CreateNewRunningFormInfos(env, runningFormInfos));
1088         };
1089 
1090     napi_value result = nullptr;
1091     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetPublishedRunningFormInfos",
1092         env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
1093     return result;
1094 }
1095 
GetPublishedRunningFormInfoById(napi_env env,napi_callback_info info)1096 napi_value JsFormProvider::GetPublishedRunningFormInfoById(napi_env env, napi_callback_info info)
1097 {
1098     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetPublishedRunningFormInfoById);
1099 }
1100 
OnGetPublishedRunningFormInfoById(napi_env env,size_t argc,napi_value * argv)1101 napi_value JsFormProvider::OnGetPublishedRunningFormInfoById(napi_env env, size_t argc, napi_value* argv)
1102 {
1103     HILOG_DEBUG("call");
1104     if (CheckParamNum(env, argc, ARGS_SIZE_ONE, ARGS_SIZE_TWO) == false) {
1105         return CreateJsUndefined(env);
1106     }
1107     napi_valuetype paramZeroType = napi_undefined;
1108     napi_typeof(env, argv[PARAM0], &paramZeroType);
1109     if (paramZeroType != napi_string) {
1110         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1111         return CreateJsUndefined(env);
1112     }
1113     int64_t formId = 0;
1114     std::string strFormId;
1115     if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
1116         HILOG_ERROR("ConvertFromJsValue failed");
1117         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
1118         return CreateJsUndefined(env);
1119     }
1120     if (!ConvertStringToInt64(strFormId, formId)) {
1121         HILOG_ERROR("convert form string failed");
1122         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
1123         return CreateJsUndefined(env);
1124     }
1125 
1126     HILOG_INFO("before GetPublishedRunningFormInfoById, formId:%{public}" PRId64, formId);
1127     NapiAsyncTask::CompleteCallback complete =
1128         [formId](napi_env env, NapiAsyncTask &task, int32_t status) {
1129             RunningFormInfo runningFormInfo;
1130             auto ret = FormMgr::GetInstance().GetPublishedFormInfoById(formId, runningFormInfo);
1131             if (ret != ERR_OK) {
1132                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
1133                 return;
1134             }
1135             task.ResolveWithNoError(env, CreateNewRunningFormInfo(env, runningFormInfo));
1136         };
1137 
1138     napi_value lastParam = (argc == ARGS_SIZE_TWO) ? argv[PARAM1] : nullptr;
1139     napi_value result = nullptr;
1140     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetPublishedRunningFormInfoById",
1141         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1142     return result;
1143 }
1144 }  // namespace AbilityRuntime
1145 }  // namespace OHOS
1146