1 /*
2  * Copyright (c) 2021-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 "napi_form_provider.h"
17 
18 #include <cinttypes>
19 #include <vector>
20 
21 #include "fms_log_wrapper.h"
22 #include "form_mgr_errors.h"
23 #include "form_mgr.h"
24 #include "js_runtime_utils.h"
25 #include "napi_common_util.h"
26 #include "napi_common_want.h"
27 #include "napi_form_util.h"
28 #include "napi/native_api.h"
29 #include "napi/native_node_api.h"
30 #include "runtime.h"
31 
32 namespace OHOS {
33 namespace AbilityRuntime {
34 using namespace OHOS;
35 using namespace OHOS::AAFwk;
36 using namespace OHOS::AppExecFwk;
37 
38 namespace {
39     constexpr size_t ARGS_SIZE_ZERO = 0;
40     constexpr size_t ARGS_SIZE_ONE = 1;
41     constexpr size_t ARGS_SIZE_TWO = 2;
42     constexpr size_t ARGS_SIZE_THREE = 3;
43     constexpr int REF_COUNT = 1;
44     constexpr int CALLBACK_FLG = 1;
45     constexpr int PROMISE_FLG = 2;
46     const std::string MODULE_NAME = "moduleName";
47     const std::string IS_FORM_AGENT = "isFormAgent";
48 }
49 
ExecuteAsyncCallbackWork(napi_env env,AsyncCallbackInfoBase * asyncCallbackInfo)50 napi_value ExecuteAsyncCallbackWork(napi_env env, AsyncCallbackInfoBase* asyncCallbackInfo)
51 {
52     if (napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
53         napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
54         // store return-message to callbackValues[0].
55         InnerCreateCallbackRetMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, callbackValues);
56         napi_value callback;
57         napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
58         napi_value callResult;
59         // call.
60         napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
61         napi_delete_reference(env, asyncCallbackInfo->callback);
62         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
63         delete asyncCallbackInfo;
64         asyncCallbackInfo = nullptr;
65     }
66     napi_value result = nullptr;
67     napi_get_undefined(env, &result);
68     return result;
69 }
70 
ExecuteAsyncPromiseWork(napi_env env,AsyncCallbackInfoBase * asyncCallbackInfo)71 void ExecuteAsyncPromiseWork(napi_env env, AsyncCallbackInfoBase* asyncCallbackInfo)
72 {
73     if (napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
74         napi_value error;
75         InnerCreatePromiseRetMsg(env, ERR_APPEXECFWK_FORM_COMMON_CODE, &error);
76         napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, error);
77         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
78         delete asyncCallbackInfo;
79         asyncCallbackInfo = nullptr;
80     }
81 }
82 
GetStringByProp(napi_env env,napi_value value,const std::string & prop)83 static std::string GetStringByProp(napi_env env, napi_value value, const std::string& prop)
84 {
85     std::string result;
86     bool propExist = false;
87     napi_value propValue = nullptr;
88     napi_valuetype valueType = napi_undefined;
89     napi_has_named_property(env, value, prop.c_str(), &propExist);
90     if (!propExist) {
91         HILOG_ERROR("%{public}s, prop[%{public}s] not exist.", __func__, prop.c_str());
92         return result;
93     }
94     napi_get_named_property(env, value, prop.c_str(), &propValue);
95     if (propValue == nullptr) {
96         HILOG_ERROR("%{public}s, prop[%{public}s] get failed.", __func__, prop.c_str());
97         return result;
98     }
99     napi_typeof(env, propValue, &valueType);
100     if (valueType != napi_string) {
101         HILOG_ERROR("%{public}s, prop[%{public}s] is not napi_string.", __func__, prop.c_str());
102         return result;
103     }
104     size_t size = 0;
105     if (napi_get_value_string_utf8(env, propValue, nullptr, 0, &size) != napi_ok) {
106         HILOG_ERROR("%{public}s, prop[%{public}s] get size failed.", __func__, prop.c_str());
107         return result;
108     }
109     result.reserve(size + 1);
110     result.resize(size);
111     if (napi_get_value_string_utf8(env, propValue, result.data(), (size + 1), &size) != napi_ok) {
112         HILOG_ERROR("%{public}s, prop[%{public}s] get value failed.", __func__, prop.c_str());
113         return "";
114     }
115     return result;
116 }
117 
InnerRequestPublishForm(napi_env env,AsyncRequestPublishFormCallbackInfo * const asyncCallbackInfo)118 static void InnerRequestPublishForm(napi_env env, AsyncRequestPublishFormCallbackInfo *const asyncCallbackInfo)
119 {
120     HILOG_DEBUG("%{public}s called.", __func__);
121     if (FormMgr::GetRecoverStatus() == Constants::IN_RECOVERING) {
122         HILOG_ERROR("%{public}s error, form is in recover status, can't do action on form.", __func__);
123         asyncCallbackInfo->result = ERR_APPEXECFWK_FORM_SERVER_STATUS_ERR;
124         return;
125     }
126 
127     asyncCallbackInfo->want.SetParam(IS_FORM_AGENT, false);
128     ErrCode errCode = FormMgr::GetInstance().RequestPublishForm(asyncCallbackInfo->want,
129         asyncCallbackInfo->withFormBindingData, asyncCallbackInfo->formProviderData, asyncCallbackInfo->formId);
130     if (errCode != ERR_OK) {
131         HILOG_ERROR("Failed to RequestPublishForm, error code is %{public}d.", errCode);
132     }
133     asyncCallbackInfo->result = errCode;
134     HILOG_DEBUG("%{public}s, end", __func__);
135 }
136 
RequestPublishFormParse(napi_env env,napi_value * argv,AsyncRequestPublishFormCallbackInfo * asyncCallbackInfo)137 static ErrCode RequestPublishFormParse(napi_env env, napi_value *argv,
138                                        AsyncRequestPublishFormCallbackInfo *asyncCallbackInfo)
139 {
140     bool parseResult = UnwrapWant(env, argv[0], asyncCallbackInfo->want);
141     if (!parseResult) {
142         HILOG_ERROR("%{public}s, failed to parse want.", __func__);
143         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
144     }
145 
146     if (asyncCallbackInfo->withFormBindingData) {
147         napi_valuetype valueType = napi_undefined;
148         napi_typeof(env, argv[1], &valueType);
149         if (valueType != napi_object) {
150             HILOG_ERROR("%{public}s, wrong type for argv[1].", __func__);
151             return ERR_APPEXECFWK_FORM_INVALID_PARAM;
152         }
153         auto formProviderData = std::make_unique<FormProviderData>();
154         std::string formDataStr = GetStringByProp(env, argv[1], "data");
155         formProviderData->SetDataString(formDataStr);
156         formProviderData->ParseImagesData();
157         asyncCallbackInfo->formProviderData = std::move(formProviderData);
158     }
159 
160     return ERR_OK;
161 }
162 
FormCallbackCreateAsyncWork(napi_env env,AsyncRequestPublishFormCallbackInfo * asyncCallbackInfo)163 static void FormCallbackCreateAsyncWork(napi_env env, AsyncRequestPublishFormCallbackInfo *asyncCallbackInfo)
164 {
165     napi_value resourceName;
166     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
167     napi_create_async_work(
168         env,
169         nullptr,
170         resourceName,
171         [](napi_env env, void *data) {
172             HILOG_INFO("running");
173             auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
174             InnerRequestPublishForm(env, asyncCallbackInfo);
175         },
176         [](napi_env env, napi_status status, void *data) {
177             HILOG_INFO("complete");
178             auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
179 
180             if (asyncCallbackInfo->callback != nullptr) {
181                 napi_value callback;
182                 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
183                 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
184                 if (asyncCallbackInfo->result == ERR_OK) {
185                     std::string strFormId = std::to_string(asyncCallbackInfo->formId);
186                     napi_value formId;
187                     napi_create_string_utf8(env, strFormId.c_str(), strFormId.length(), &formId);
188                     callbackValues[1] = formId;
189                 }
190 
191                 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
192                 napi_value callResult;
193                 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
194                 napi_delete_reference(env, asyncCallbackInfo->callback);
195             }
196 
197             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
198             delete asyncCallbackInfo;
199         },
200         (void *) asyncCallbackInfo,
201         &asyncCallbackInfo->asyncWork);
202 }
203 
RequestPublishFormCallback(napi_env env,napi_value * argv,bool withFormBindingData)204 static napi_value RequestPublishFormCallback(napi_env env, napi_value *argv, bool withFormBindingData)
205 {
206     HILOG_INFO("asyncCallback.");
207 
208     int32_t callbackIdx = 1;
209     if (withFormBindingData) {
210         callbackIdx++;
211     }
212     napi_valuetype valueType = napi_undefined;
213     NAPI_CALL(env, napi_typeof(env, argv[callbackIdx], &valueType));
214     if (valueType != napi_function) {
215         HILOG_ERROR("The arguments[1] type of requestPublishForm is incorrect, expected type is function.");
216         return nullptr;
217     }
218 
219     auto *asyncCallbackInfo = new (std::nothrow) AsyncRequestPublishFormCallbackInfo {
220         .env = env,
221         .withFormBindingData = withFormBindingData,
222     };
223     if (asyncCallbackInfo == nullptr) {
224         HILOG_ERROR("asyncCallbackInfo == nullptr");
225         return nullptr;
226     }
227 
228     ErrCode errCode = RequestPublishFormParse(env, argv, asyncCallbackInfo);
229     if (errCode != ERR_OK) {
230         delete asyncCallbackInfo;
231         return RetErrMsg(InitErrMsg(env, errCode, CALLBACK_FLG, argv[callbackIdx]));
232     }
233     napi_create_reference(env, argv[callbackIdx], REF_COUNT, &asyncCallbackInfo->callback);
234 
235     FormCallbackCreateAsyncWork(env, asyncCallbackInfo);
236     NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
237     return NapiGetResult(env, 1);
238 }
239 
FormPromiseCreateAsyncWork(napi_env env,AsyncRequestPublishFormCallbackInfo * asyncCallbackInfo)240 static void FormPromiseCreateAsyncWork(napi_env env, AsyncRequestPublishFormCallbackInfo *asyncCallbackInfo)
241 {
242     napi_value resourceName;
243     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
244     napi_create_async_work(
245         env,
246         nullptr,
247         resourceName,
248         [](napi_env env, void *data) {
249             HILOG_INFO("running");
250             auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
251             if (asyncCallbackInfo) {
252                 InnerRequestPublishForm(env, asyncCallbackInfo);
253             }
254         },
255         [](napi_env env, napi_status status, void *data) {
256             HILOG_INFO("complete");
257             auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
258             napi_value result;
259             if (asyncCallbackInfo) {
260                 if (asyncCallbackInfo->result == ERR_OK) {
261                     std::string strFormId = std::to_string(asyncCallbackInfo->formId);
262                     napi_create_string_utf8(env, strFormId.c_str(), strFormId.length(), &result);
263                     napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
264                 } else {
265                     InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
266                     napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
267                 }
268                 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
269                 delete asyncCallbackInfo;
270             }
271         },
272         (void *) asyncCallbackInfo,
273         &asyncCallbackInfo->asyncWork);
274 }
275 
RequestPublishFormPromise(napi_env env,napi_value * argv,bool withFormBindingData)276 static napi_value RequestPublishFormPromise(napi_env env, napi_value *argv, bool withFormBindingData)
277 {
278     HILOG_INFO("promise");
279     napi_deferred deferred;
280     napi_value promise;
281     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
282 
283     auto *asyncCallbackInfo = new (std::nothrow) AsyncRequestPublishFormCallbackInfo {
284         .env = env,
285         .deferred = deferred,
286         .withFormBindingData = withFormBindingData,
287     };
288     if (asyncCallbackInfo == nullptr) {
289         HILOG_ERROR("asyncCallbackInfo == nullptr");
290         return nullptr;
291     }
292 
293     ErrCode errCode = RequestPublishFormParse(env, argv, asyncCallbackInfo);
294     if (errCode != ERR_OK) {
295         delete asyncCallbackInfo;
296         return RetErrMsg(InitErrMsg(env, errCode, PROMISE_FLG, nullptr));
297     }
298 
299     FormPromiseCreateAsyncWork(env, asyncCallbackInfo);
300     napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
301     return promise;
302 }
303 
304 /**
305  * @brief  The implementation of Node-API interface: requestPinForm
306  *
307  * @param[in] env The environment that the Node-API call is invoked under
308  * @param[out] info An opaque datatype that is passed to a callback function
309  *
310  * @return This is an opaque pointer that is used to represent a JavaScript value
311  */
NAPI_RequestPublishForm(napi_env env,napi_callback_info info)312 napi_value NAPI_RequestPublishForm(napi_env env, napi_callback_info info)
313 {
314     HILOG_INFO("call");
315     // Check the number of the arguments
316     size_t argc = ARGS_SIZE_THREE;
317     napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
318     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
319     if (argc > ARGS_SIZE_THREE) {
320         HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
321         return nullptr;
322     }
323     HILOG_INFO("argc = [%{public}zu]", argc);
324 
325     if (argc < ARGS_SIZE_TWO) {
326         // promise, no form binding data
327         return RequestPublishFormPromise(env, argv, false);
328     } else if (argc > ARGS_SIZE_TWO) {
329         // callback, with form binding data
330         return RequestPublishFormCallback(env, argv, true);
331     } else {
332         napi_valuetype valueType = napi_undefined;
333         NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
334         if (valueType == napi_function) {
335             // callback, no form binding data
336             return RequestPublishFormCallback(env, argv, false);
337         } else {
338             // promise, with form binding data
339             return RequestPublishFormPromise(env, argv, true);
340         }
341     }
342 }
343 
CheckFormArgv(napi_env env,size_t argc,napi_value * argv,int32_t * errCode,int64_t * formId)344 static void CheckFormArgv(napi_env env, size_t argc, napi_value* argv, int32_t *errCode, int64_t *formId)
345 {
346     HILOG_INFO("asyncCallback");
347 
348     napi_valuetype paramZeroType = napi_undefined;
349     napi_typeof(env, argv[PARAM0], &paramZeroType);
350     if (paramZeroType != napi_string) {
351         HILOG_ERROR("formId is not napi_string.");
352         *errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
353     }
354 
355     std::string strFormId;
356     bool confirm = ConvertFromJsValue(env, argv[PARAM0], strFormId);
357     if (!confirm) {
358         HILOG_ERROR("ConvertFromJsValue failed.");
359         *errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
360     }
361     if (!ConvertStringToInt64(strFormId, *formId)) {
362         HILOG_ERROR("convert form string failed.");
363         *errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
364     }
365 }
366 
Finalizer(napi_env env,void * data,void * hint)367 void JsFormProvider::Finalizer(napi_env env, void* data, void* hint)
368 {
369     HILOG_INFO("Finalizer is called");
370     std::unique_ptr<JsFormProvider>(static_cast<JsFormProvider*>(data));
371 }
372 
GetFormsInfo(napi_env env,napi_callback_info info)373 napi_value JsFormProvider::GetFormsInfo(napi_env env, napi_callback_info info)
374 {
375     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetFormsInfo);
376 }
377 
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)378 napi_value JsFormProvider::OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
379 {
380     HILOG_INFO("call");
381     int32_t errCode = ERR_OK;
382     if (argc > ARGS_SIZE_TWO) {
383         HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
384         errCode = ERR_ADD_INVALID_PARAM;
385     }
386 
387     size_t convertArgc = 0;
388     FormInfoFilter formInfoFilter;
389     napi_valuetype type = napi_undefined;
390     napi_typeof(env, argv[0], &type);
391     if (argc > 0 && type != napi_function) {
392         if (!ConvertFormInfoFilter(env, argv[0], formInfoFilter)) {
393             HILOG_ERROR("%{public}s, convert form info filter failed.", __func__);
394             errCode = ERR_ADD_INVALID_PARAM;
395         }
396         convertArgc++;
397     }
398 
399     NapiAsyncTask::CompleteCallback complete =
400         [formInfoFilter, errCode](napi_env env, NapiAsyncTask &task, int32_t status) {
401             if (errCode != ERR_OK) {
402                 task.Reject(env, CreateJsError(env, errCode, QueryRetMsg(errCode)));
403                 return;
404             }
405 
406             std::vector<FormInfo> formInfos;
407             auto ret = FormMgr::GetInstance().GetFormsInfo(formInfoFilter, formInfos);
408             if (ret == ERR_OK) {
409                 task.Resolve(env, CreateFormInfos(env, formInfos));
410             } else {
411                 auto retCode = QueryRetCode(ret);
412                 task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
413             }
414         };
415 
416     napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
417     napi_value result = nullptr;
418     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetFormsInfo",
419         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
420     return result;
421 }
SetFormNextRefreshTime(napi_env env,napi_callback_info info)422 napi_value JsFormProvider::SetFormNextRefreshTime(napi_env env, napi_callback_info info)
423 {
424     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnSetFormNextRefreshTime);
425 }
426 
OnSetFormNextRefreshTime(napi_env env,size_t argc,napi_value * argv)427 napi_value JsFormProvider::OnSetFormNextRefreshTime(napi_env env, size_t argc, napi_value* argv)
428 {
429     HILOG_DEBUG("%{public}s is called", __FUNCTION__);
430     if (argc < ARGS_SIZE_TWO || argc > ARGS_SIZE_THREE) {
431         HILOG_ERROR("wrong number of arguments.");
432         napi_value jsNull = nullptr;
433         NAPI_CALL(env, napi_get_null(env, &jsNull));
434         return jsNull;
435     }
436     int32_t errCode = ERR_OK;
437     int64_t formId = 0;
438     CheckFormArgv(env, argc, argv, &errCode, &formId);
439 
440     napi_valuetype paramOneType = napi_undefined;
441     napi_typeof(env, argv[PARAM1], &paramOneType);
442     if (paramOneType != napi_number) {
443         errCode = ERR_APPEXECFWK_FORM_REFRESH_TIME_NUM_ERR;
444     }
445     int32_t time;
446     bool res = ConvertFromJsValue(env, argv[PARAM1], time);
447     if (!res) {
448         HILOG_ERROR("ConvertFromJsValue failed.");
449         errCode = ERR_APPEXECFWK_FORM_REFRESH_TIME_NUM_ERR;
450     }
451     NapiAsyncTask::CompleteCallback complete =
452         [errCode, formId, time](napi_env env, NapiAsyncTask &task, int32_t status) {
453         if (errCode != ERR_OK) {
454             auto retCode = QueryRetCode(errCode);
455             task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
456             return;
457         }
458         int32_t ret = FormMgr::GetInstance().SetNextRefreshTime(formId, time);
459         if (ret != ERR_OK) {
460             auto retCode = QueryRetCode(ret);
461             task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
462             return;
463         }
464         task.Resolve(env, CreateJsValue(env, ret));
465     };
466     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
467     napi_value result = nullptr;
468     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnSetFormNextRefreshTime",
469         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
470     return result;
471 }
472 
UpdateForm(napi_env env,napi_callback_info info)473 napi_value JsFormProvider::UpdateForm(napi_env env, napi_callback_info info)
474 {
475     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnUpdateForm);
476 }
477 
OnUpdateForm(napi_env env,size_t argc,napi_value * argv)478 napi_value JsFormProvider::OnUpdateForm(napi_env env, size_t argc, napi_value* argv)
479 {
480     HILOG_DEBUG("%{public}s is called", __FUNCTION__);
481     if (argc < ARGS_SIZE_TWO || argc > ARGS_SIZE_THREE) {
482         HILOG_ERROR("wrong number of arguments.");
483         napi_value jsNull = nullptr;
484         NAPI_CALL(env, napi_get_null(env, &jsNull));
485         return jsNull;
486     }
487     int32_t errCode = ERR_OK;
488     int64_t formId = 0;
489     CheckFormArgv(env, argc, argv, &errCode, &formId);
490 
491     napi_valuetype paramOneType = napi_undefined;
492     napi_typeof(env, argv[PARAM1], &paramOneType);
493     if (paramOneType != napi_object) {
494         HILOG_ERROR("formBindingData is not napi_object.");
495         errCode = ERR_APPEXECFWK_FORM_INVALID_PROVIDER_DATA;
496     }
497     auto formProviderData = std::make_shared<OHOS::AppExecFwk::FormProviderData>();
498     std::string formDataStr = GetStringByProp(env, argv[PARAM1], "data");
499     formProviderData->SetDataString(formDataStr);
500     formProviderData->ParseImagesData();
501     NapiAsyncTask::CompleteCallback complete =
502         [errCode, formId, data = formProviderData](napi_env env, NapiAsyncTask &task, int32_t status) {
503         if (errCode != ERR_OK) {
504             auto retCode = QueryRetCode(errCode);
505             task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
506             return;
507         }
508         int32_t ret = FormMgr::GetInstance().UpdateForm(formId, *data);
509         if (ret != ERR_OK) {
510             auto retCode = QueryRetCode(ret);
511             task.Reject(env, CreateJsError(env, retCode, QueryRetMsg(retCode)));
512             return;
513         }
514         task.Resolve(env, CreateJsValue(env, ret));
515     };
516     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
517     napi_value result = nullptr;
518     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnUpdateForm",
519         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
520     return result;
521 }
522 
IsRequestPublishFormSupported(napi_env env,napi_callback_info info)523 napi_value JsFormProvider::IsRequestPublishFormSupported(napi_env env, napi_callback_info info)
524 {
525     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnIsRequestPublishFormSupported);
526 }
527 
OnIsRequestPublishFormSupported(napi_env env,size_t argc,napi_value * argv)528 napi_value JsFormProvider::OnIsRequestPublishFormSupported(napi_env env, size_t argc, napi_value* argv)
529 {
530     HILOG_DEBUG("%{public}s is called", __FUNCTION__);
531     if (argc > ARGS_SIZE_ONE) {
532         HILOG_ERROR("wrong number of arguments.");
533         napi_value jsNull = nullptr;
534         NAPI_CALL(env, napi_get_null(env, &jsNull));
535         return jsNull;
536     }
537     struct OnIsRequestPublishFormSupported {
538         bool result;
539     };
540     std::shared_ptr<OnIsRequestPublishFormSupported> onIsRequestPublishFormSupported =
541         std::make_shared<OnIsRequestPublishFormSupported>();
542     auto execute = [data = onIsRequestPublishFormSupported] () {
543         if (data == nullptr) {
544             HILOG_ERROR("onIsRequestPublishFormSupported is nullptr.");
545             return;
546         }
547         data->result = FormMgr::GetInstance().IsRequestPublishFormSupported();
548     };
549     NapiAsyncTask::CompleteCallback complete = [data = onIsRequestPublishFormSupported](
550             napi_env env, NapiAsyncTask &task, int32_t status) {
551         auto retMsg = QueryRetMsg(ERR_OK);
552         task.ResolveWithCustomize(env, CreateJsError(env, ERR_OK, retMsg),
553             CreateJsValue(env, data->result));
554     };
555     napi_value lastParam = (argc <= ARGS_SIZE_ZERO) ? nullptr : argv[PARAM0];
556     napi_value result = nullptr;
557     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnIsRequestPublishFormSupported",
558         env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
559     return result;
560 }
561 }  // namespace AbilityRuntime
562 }  // namespace OHOS
563