1 /*
2 * Copyright (c) 2021-2022 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 "form_mgr_errors.h"
22 #include "form_mgr.h"
23 #include "js_form_info_util.h"
24 #include "js_runtime_utils.h"
25 #include "hilog_wrapper.h"
26 #include "napi_common_util.h"
27 #include "napi_common_want.h"
28 #include "napi_form_util.h"
29 #include "napi/native_api.h"
30 #include "napi/native_node_api.h"
31 #include "runtime.h"
32
33 namespace OHOS {
34 namespace AbilityRuntime {
35 using namespace OHOS;
36 using namespace OHOS::AAFwk;
37 using namespace OHOS::AppExecFwk;
38
39 namespace {
40 constexpr size_t ARGS_SIZE_ZERO = 0;
41 constexpr size_t ARGS_SIZE_ONE = 1;
42 constexpr size_t ARGS_SIZE_TWO = 2;
43 constexpr size_t ARGS_SIZE_THREE = 3;
44 constexpr int REF_COUNT = 1;
45 constexpr int CALLBACK_FLG = 1;
46 constexpr int PROMISE_FLG = 2;
47 const std::string MODULE_NAME = "moduleName";
48 }
49
ExecuteAsyncCallbackWork(napi_env env,AsyncCallbackInfoBase * asyncCallbackInfo)50 napi_value ExecuteAsyncCallbackWork(napi_env env, AsyncCallbackInfoBase* asyncCallbackInfo)
51 {
52 if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != 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(env, asyncCallbackInfo->asyncWork) != 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 ErrCode errCode = FormMgr::GetInstance().RequestPublishForm(asyncCallbackInfo->want,
128 asyncCallbackInfo->withFormBindingData, asyncCallbackInfo->formProviderData, asyncCallbackInfo->formId);
129 if (errCode != ERR_OK) {
130 HILOG_ERROR("Failed to RequestPublishForm, error code is %{public}d.", errCode);
131 }
132 asyncCallbackInfo->result = errCode;
133 HILOG_DEBUG("%{public}s, end", __func__);
134 }
135
RequestPublishFormParse(napi_env env,napi_value * argv,AsyncRequestPublishFormCallbackInfo * asyncCallbackInfo)136 static ErrCode RequestPublishFormParse(napi_env env, napi_value *argv,
137 AsyncRequestPublishFormCallbackInfo *asyncCallbackInfo)
138 {
139 bool parseResult = UnwrapWant(env, argv[0], asyncCallbackInfo->want);
140 if (!parseResult) {
141 HILOG_ERROR("%{public}s, failed to parse want.", __func__);
142 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
143 }
144
145 if (asyncCallbackInfo->withFormBindingData) {
146 napi_valuetype valueType = napi_undefined;
147 napi_typeof(env, argv[1], &valueType);
148 if (valueType != napi_object) {
149 HILOG_ERROR("%{public}s, wrong type for argv[1].", __func__);
150 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
151 }
152 auto formProviderData = std::make_unique<FormProviderData>();
153 std::string formDataStr = GetStringByProp(env, argv[1], "data");
154 formProviderData->SetDataString(formDataStr);
155 formProviderData->ParseImagesData();
156 asyncCallbackInfo->formProviderData = std::move(formProviderData);
157 }
158
159 return ERR_OK;
160 }
161
RequestPublishFormCallback(napi_env env,napi_value * argv,bool withFormBindingData)162 static napi_value RequestPublishFormCallback(napi_env env, napi_value *argv, bool withFormBindingData)
163 {
164 HILOG_INFO("%{public}s, asyncCallback.", __func__);
165
166 int32_t callbackIdx = 1;
167 if (withFormBindingData) {
168 callbackIdx++;
169 }
170 napi_valuetype valueType = napi_undefined;
171 NAPI_CALL(env, napi_typeof(env, argv[callbackIdx], &valueType));
172 if (valueType != napi_function) {
173 HILOG_ERROR("The arguments[1] type of requestPublishForm is incorrect, expected type is function.");
174 return nullptr;
175 }
176
177 auto *asyncCallbackInfo = new (std::nothrow) AsyncRequestPublishFormCallbackInfo {
178 .env = env,
179 .withFormBindingData = withFormBindingData,
180 };
181 if (asyncCallbackInfo == nullptr) {
182 HILOG_ERROR("asyncCallbackInfo == nullptr");
183 return nullptr;
184 }
185
186 ErrCode errCode = RequestPublishFormParse(env, argv, asyncCallbackInfo);
187 if (errCode != ERR_OK) {
188 delete asyncCallbackInfo;
189 return RetErrMsg(InitErrMsg(env, errCode, CALLBACK_FLG, argv[callbackIdx]));
190 }
191 napi_create_reference(env, argv[callbackIdx], REF_COUNT, &asyncCallbackInfo->callback);
192
193 napi_value resourceName;
194 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
195 napi_create_async_work(
196 env,
197 nullptr,
198 resourceName,
199 [](napi_env env, void *data) {
200 HILOG_INFO("%{public}s, napi_create_async_work running", __func__);
201 auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
202 InnerRequestPublishForm(env, asyncCallbackInfo);
203 },
204 [](napi_env env, napi_status status, void *data) {
205 HILOG_INFO("%{public}s, napi_create_async_work complete", __func__);
206 auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
207
208 if (asyncCallbackInfo->callback != nullptr) {
209 napi_value callback;
210 napi_value callbackValues[ARGS_SIZE_TWO] = {nullptr, nullptr};
211 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->result, callbackValues);
212 if (asyncCallbackInfo->result == ERR_OK) {
213 std::string strFormId = std::to_string(asyncCallbackInfo->formId);
214 napi_value formId;
215 napi_create_string_utf8(env, strFormId.c_str(), strFormId.length(), &formId);
216 callbackValues[1] = formId;
217 }
218
219 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
220 napi_value callResult;
221 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
222 napi_delete_reference(env, asyncCallbackInfo->callback);
223 }
224
225 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
226 delete asyncCallbackInfo;
227 },
228 (void *) asyncCallbackInfo,
229 &asyncCallbackInfo->asyncWork);
230 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
231 return NapiGetResult(env, 1);
232 }
233
RequestPublishFormPromise(napi_env env,napi_value * argv,bool withFormBindingData)234 static napi_value RequestPublishFormPromise(napi_env env, napi_value *argv, bool withFormBindingData)
235 {
236 HILOG_INFO("%{public}s, promise.", __func__);
237 napi_deferred deferred;
238 napi_value promise;
239 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
240
241 auto *asyncCallbackInfo = new (std::nothrow) AsyncRequestPublishFormCallbackInfo {
242 .env = env,
243 .deferred = deferred,
244 .withFormBindingData = withFormBindingData,
245 };
246 if (asyncCallbackInfo == nullptr) {
247 HILOG_ERROR("asyncCallbackInfo == nullptr");
248 return nullptr;
249 }
250
251 ErrCode errCode = RequestPublishFormParse(env, argv, asyncCallbackInfo);
252 if (errCode != ERR_OK) {
253 delete asyncCallbackInfo;
254 return RetErrMsg(InitErrMsg(env, errCode, PROMISE_FLG, nullptr));
255 }
256
257 napi_value resourceName;
258 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
259 napi_create_async_work(
260 env,
261 nullptr,
262 resourceName,
263 [](napi_env env, void *data) {
264 HILOG_INFO("%{public}s, promise running", __func__);
265 auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
266 if (asyncCallbackInfo) {
267 InnerRequestPublishForm(env, asyncCallbackInfo);
268 }
269 },
270 [](napi_env env, napi_status status, void *data) {
271 HILOG_INFO("%{public}s, promise complete", __func__);
272 auto *asyncCallbackInfo = (AsyncRequestPublishFormCallbackInfo *) data;
273 napi_value result;
274 if (asyncCallbackInfo) {
275 if (asyncCallbackInfo->result == ERR_OK) {
276 std::string strFormId = std::to_string(asyncCallbackInfo->formId);
277 napi_create_string_utf8(env, strFormId.c_str(), strFormId.length(), &result);
278 napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
279 } else {
280 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->result, &result);
281 napi_reject_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, result);
282 }
283 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
284 delete asyncCallbackInfo;
285 }
286 },
287 (void *) asyncCallbackInfo,
288 &asyncCallbackInfo->asyncWork);
289 napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
290 return promise;
291 }
292
293 /**
294 * @brief The implementation of Node-API interface: requestPinForm
295 *
296 * @param[in] env The environment that the Node-API call is invoked under
297 * @param[out] info An opaque datatype that is passed to a callback function
298 *
299 * @return This is an opaque pointer that is used to represent a JavaScript value
300 */
NAPI_RequestPublishForm(napi_env env,napi_callback_info info)301 napi_value NAPI_RequestPublishForm(napi_env env, napi_callback_info info)
302 {
303 HILOG_INFO("%{public}s called.", __func__);
304 // Check the number of the arguments
305 size_t argc = ARGS_SIZE_THREE;
306 napi_value argv[ARGS_SIZE_THREE] = {nullptr, nullptr, nullptr};
307 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
308 if (argc > ARGS_SIZE_THREE) {
309 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
310 return nullptr;
311 }
312 HILOG_INFO("%{public}s, argc = [%{public}zu]", __func__, argc);
313
314 if (argc < ARGS_SIZE_TWO) {
315 // promise, no form binding data
316 return RequestPublishFormPromise(env, argv, false);
317 } else if (argc > ARGS_SIZE_TWO) {
318 // callback, with form binding data
319 return RequestPublishFormCallback(env, argv, true);
320 } else {
321 napi_valuetype valueType = napi_undefined;
322 NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
323 if (valueType == napi_function) {
324 // callback, no form binding data
325 return RequestPublishFormCallback(env, argv, false);
326 } else {
327 // promise, with form binding data
328 return RequestPublishFormPromise(env, argv, true);
329 }
330 }
331 }
332
InnerIsRequestPublishFormSupported(napi_env env,AsyncIsRequestPublishFormSupportedCallbackInfo * asyncCallbackInfo)333 static void InnerIsRequestPublishFormSupported(napi_env env,
334 AsyncIsRequestPublishFormSupportedCallbackInfo *asyncCallbackInfo)
335 {
336 HILOG_INFO("InnerIsRequestPublishFormSupported called");
337 if (asyncCallbackInfo == nullptr) {
338 HILOG_ERROR("InnerIsRequestPublishFormSupported data is a nullptr");
339 return;
340 }
341 bool value = FormMgr::GetInstance().IsRequestPublishFormSupported();
342 asyncCallbackInfo->result = value;
343 }
344
345 // callback version of NAPI_IsRequestPublishFormSupported
IsRequestPublishFormSupportedCallback(napi_env env,napi_value argv,AsyncIsRequestPublishFormSupportedCallbackInfo * asyncCallbackInfo)346 static napi_value IsRequestPublishFormSupportedCallback(napi_env env, napi_value argv,
347 AsyncIsRequestPublishFormSupportedCallbackInfo *asyncCallbackInfo)
348 {
349 HILOG_INFO("%{public}s starts.", __func__);
350 // Check the type of the argv, expect to be a callback function.
351 napi_valuetype valueType;
352 NAPI_CALL(env, napi_typeof(env, argv, &valueType));
353 if (valueType != napi_function) {
354 HILOG_ERROR("IsRequestPublishFormSupportedCallback callback is not a function");
355 return nullptr;
356 }
357 // store callback function that user passed in.
358 napi_create_reference(env, argv, REF_COUNT, &asyncCallbackInfo->callback);
359 // create resource name as Identifier to provide diagnostic information.
360 napi_value resourceName;
361 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
362 napi_create_async_work(
363 env,
364 nullptr,
365 resourceName,
366 [](napi_env env, void *data) {
367 // entry to the core of this functionality.
368 auto *asyncCallbackInfo = static_cast<AsyncIsRequestPublishFormSupportedCallbackInfo *>(data);
369 InnerIsRequestPublishFormSupported(env, asyncCallbackInfo);
370 },
371 [](napi_env env, napi_status status, void *data) {
372 HILOG_INFO("IsRequestPublishFormSupportedCallback callback completed");
373 if (data == nullptr) {
374 HILOG_ERROR("IsRequestPublishFormSupportedCallback data is a nullptr");
375 return;
376 }
377 AsyncIsRequestPublishFormSupportedCallbackInfo *asyncCallbackInfo =
378 static_cast<AsyncIsRequestPublishFormSupportedCallbackInfo *>(data);
379
380 // call user provided callback function.
381 if (asyncCallbackInfo->callback != nullptr) {
382 napi_value callbackValues[ARGS_SIZE_TWO] = {0};
383 napi_value callback;
384 // store return-message to callbackValues[0].
385 InnerCreateCallbackRetMsg(env, ERR_OK, callbackValues);
386 // store result
387 napi_value result;
388 napi_get_boolean(env, asyncCallbackInfo->result, &result);
389 callbackValues[1] = result;
390 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
391 napi_value callResult;
392 // call.
393 napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, callbackValues, &callResult);
394 napi_delete_reference(env, asyncCallbackInfo->callback);
395 }
396 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
397 delete asyncCallbackInfo;
398 asyncCallbackInfo = nullptr;
399 },
400 (void *)asyncCallbackInfo,
401 &asyncCallbackInfo->asyncWork);
402 return ExecuteAsyncCallbackWork(env, asyncCallbackInfo);
403 }
404
IsRequestPublishFormSupportedPromise(napi_env env,AsyncIsRequestPublishFormSupportedCallbackInfo * asyncCallbackInfo)405 static napi_value IsRequestPublishFormSupportedPromise(napi_env env,
406 AsyncIsRequestPublishFormSupportedCallbackInfo *asyncCallbackInfo)
407 {
408 HILOG_INFO("%{public}s calls.", __func__);
409 napi_deferred deferred;
410 napi_value promise;
411 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
412 asyncCallbackInfo->deferred = deferred;
413 // create resource name as Identifier to provide diagnostic information.
414 napi_value resourceName;
415 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
416 napi_create_async_work(
417 env,
418 nullptr,
419 resourceName,
420 [](napi_env env, void *data) {
421 auto *asyncCallbackInfo = static_cast<AsyncIsRequestPublishFormSupportedCallbackInfo *>(data);
422 InnerIsRequestPublishFormSupported(env, asyncCallbackInfo);
423 },
424 [](napi_env env, napi_status status, void *data) {
425 HILOG_INFO("IsRequestPublishFormSupportedPromise completed");
426 if (data == nullptr) {
427 HILOG_ERROR("IsRequestPublishFormSupportedPromise data is a nullptr");
428 return;
429 }
430 AsyncIsRequestPublishFormSupportedCallbackInfo *asyncCallbackInfo =
431 static_cast<AsyncIsRequestPublishFormSupportedCallbackInfo *>(data);
432 napi_value result;
433 napi_get_boolean(env, asyncCallbackInfo->result, &result);
434 napi_resolve_deferred(
435 asyncCallbackInfo->env,
436 asyncCallbackInfo->deferred,
437 result);
438 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
439 delete asyncCallbackInfo;
440 asyncCallbackInfo = nullptr;
441 },
442 (void *)asyncCallbackInfo,
443 &asyncCallbackInfo->asyncWork);
444 ExecuteAsyncPromiseWork(env, asyncCallbackInfo);
445 return promise;
446 }
447
NAPI_IsRequestPublishFormSupported(napi_env env,napi_callback_info info)448 napi_value NAPI_IsRequestPublishFormSupported(napi_env env, napi_callback_info info)
449 {
450 HILOG_INFO("%{public}s starts.", __func__);
451 // Check the number of the arguments.
452 size_t argc = ARGS_SIZE_ONE;
453 napi_value argv[ARGS_SIZE_ONE] = {nullptr};
454 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
455 if (argc > ARGS_SIZE_ONE) {
456 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
457 return nullptr;
458 }
459
460 auto *asyncCallbackInfo = new (std::nothrow) AsyncIsRequestPublishFormSupportedCallbackInfo(env);
461 if (asyncCallbackInfo == nullptr) {
462 HILOG_ERROR("asyncCallbackInfo == nullptr");
463 return nullptr;
464 }
465 // callback
466 if (argc == ARGS_SIZE_ONE) {
467 return IsRequestPublishFormSupportedCallback(env, argv[ARGS_SIZE_ZERO], asyncCallbackInfo);
468 }
469 return IsRequestPublishFormSupportedPromise(env, asyncCallbackInfo);
470 }
471
Finalizer(NativeEngine * engine,void * data,void * hint)472 void JsFormProvider::Finalizer(NativeEngine* engine, void* data, void* hint)
473 {
474 HILOG_INFO("JsFormProvider::Finalizer is called");
475 std::unique_ptr<JsFormProvider>(static_cast<JsFormProvider*>(data));
476 }
477
GetFormsInfo(NativeEngine * engine,NativeCallbackInfo * info)478 NativeValue* JsFormProvider::GetFormsInfo(NativeEngine* engine, NativeCallbackInfo* info)
479 {
480 JsFormProvider* me = CheckParamsAndGetThis<JsFormProvider>(engine, info);
481 return (me != nullptr) ? me->OnGetFormsInfo(*engine, *info) : nullptr;
482 }
483
OnGetFormsInfo(NativeEngine & engine,NativeCallbackInfo & info)484 NativeValue* JsFormProvider::OnGetFormsInfo(NativeEngine &engine, NativeCallbackInfo &info)
485 {
486 HILOG_INFO("%{public}s is called", __FUNCTION__);
487 int32_t errCode = ERR_OK;
488 if (info.argc > ARGS_SIZE_TWO) {
489 HILOG_ERROR("%{public}s, wrong number of arguments.", __func__);
490 errCode = ERR_ADD_INVALID_PARAM;
491 }
492
493 size_t convertArgc = 0;
494 FormInfoFilter formInfoFilter;
495 if (info.argc > 0 && info.argv[0]->TypeOf() != NATIVE_FUNCTION) {
496 if (!ConvertFormInfoFilter(engine, info.argv[0], formInfoFilter)) {
497 HILOG_ERROR("%{public}s, convert form info filter failed.", __func__);
498 errCode = ERR_ADD_INVALID_PARAM;
499 }
500 convertArgc++;
501 }
502
503 AsyncTask::CompleteCallback complete =
504 [formInfoFilter, errCode](NativeEngine &engine, AsyncTask &task, int32_t status) {
505 if (errCode != ERR_OK) {
506 task.Reject(engine, CreateJsError(engine, errCode, QueryRetMsg(errCode)));
507 return;
508 }
509
510 std::vector<FormInfo> formInfos;
511 auto ret = FormMgr::GetInstance().GetFormsInfo(formInfoFilter, formInfos);
512 if (ret == ERR_OK) {
513 task.Resolve(engine, CreateJsFormInfoArray(engine, formInfos));
514 } else {
515 auto retCode = QueryRetCode(ret);
516 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
517 }
518 };
519
520 NativeValue* lastParam = (info.argc <= convertArgc) ? nullptr : info.argv[convertArgc];
521 NativeValue* result = nullptr;
522 AsyncTask::Schedule("JsFormProvider::OnGetFormsInfo",
523 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
524 return result;
525 }
SetFormNextRefreshTime(NativeEngine * engine,NativeCallbackInfo * info)526 NativeValue* JsFormProvider::SetFormNextRefreshTime(NativeEngine *engine, NativeCallbackInfo *info)
527 {
528 JsFormProvider *me = CheckParamsAndGetThis<JsFormProvider>(engine, info);
529 return (me != nullptr) ? me->OnSetFormNextRefreshTime(*engine, *info) : nullptr;
530 }
531
OnSetFormNextRefreshTime(NativeEngine & engine,NativeCallbackInfo & info)532 NativeValue* JsFormProvider::OnSetFormNextRefreshTime(NativeEngine &engine, NativeCallbackInfo &info)
533 {
534 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
535 int32_t errCode = ERR_OK;
536 if (info.argc < ARGS_SIZE_TWO || info.argc > ARGS_SIZE_THREE) {
537 HILOG_ERROR("wrong number of arguments.");
538 return engine.CreateNull();
539 }
540 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
541 HILOG_ERROR("formId is not napi_string.");
542 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
543 }
544 int64_t formId = 0;
545 std::string strFormId;
546 bool confirm = ConvertFromJsValue(engine, info.argv[PARAM0], strFormId);
547 if (!confirm) {
548 HILOG_ERROR("ConvertFromJsValue failed.");
549 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
550 }
551 if (!ConvertStringToInt64(strFormId, formId)) {
552 HILOG_ERROR("convert form string failed.");
553 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
554 }
555 if (info.argv[PARAM1]->TypeOf() != NATIVE_NUMBER) {
556 errCode = ERR_APPEXECFWK_FORM_REFRESH_TIME_NUM_ERR;
557 }
558 int32_t time;
559 bool res = ConvertFromJsValue(engine, info.argv[PARAM1], time);
560 if (!res) {
561 HILOG_ERROR("ConvertFromJsValue failed.");
562 errCode = ERR_APPEXECFWK_FORM_REFRESH_TIME_NUM_ERR;
563 }
564 AsyncTask::CompleteCallback complete =
565 [errCode, formId, time](NativeEngine &engine, AsyncTask &task, int32_t status) {
566 if (errCode != ERR_OK) {
567 auto retCode = QueryRetCode(errCode);
568 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
569 return;
570 }
571 int32_t ret = FormMgr::GetInstance().SetNextRefreshTime(formId, time);
572 if (ret != ERR_OK) {
573 auto retCode = QueryRetCode(ret);
574 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
575 return;
576 }
577 task.Resolve(engine, CreateJsValue(engine, ret));
578 };
579 NativeValue *lastParam = (info.argc == ARGS_SIZE_THREE) ? info.argv[PARAM2] : nullptr;
580 NativeValue *result = nullptr;
581 AsyncTask::Schedule("JsFormProvider::OnSetFormNextRefreshTime",
582 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
583 return result;
584 }
585
UpdateForm(NativeEngine * engine,NativeCallbackInfo * info)586 NativeValue* JsFormProvider::UpdateForm(NativeEngine *engine, NativeCallbackInfo *info)
587 {
588 JsFormProvider *me = CheckParamsAndGetThis<JsFormProvider>(engine, info);
589 return (me != nullptr) ? me->OnUpdateForm(*engine, *info) : nullptr;
590 }
591
OnUpdateForm(NativeEngine & engine,NativeCallbackInfo & info)592 NativeValue* JsFormProvider::OnUpdateForm(NativeEngine &engine, NativeCallbackInfo &info)
593 {
594 HILOG_DEBUG("%{public}s is called", __FUNCTION__);
595 int32_t errCode = ERR_OK;
596 auto env = reinterpret_cast<napi_env>(&engine);
597 if (info.argc < ARGS_SIZE_TWO || info.argc > ARGS_SIZE_THREE) {
598 HILOG_ERROR("wrong number of arguments.");
599 return engine.CreateNull();
600 }
601 if (info.argv[PARAM0]->TypeOf() != NATIVE_STRING) {
602 HILOG_ERROR("formId is not napi_string.");
603 errCode = ERR_APPEXECFWK_FORM_INVALID_FORM_ID;
604 }
605 int64_t formId = 0;
606 std::string strFormId;
607 bool confirm = ConvertFromJsValue(engine, info.argv[PARAM0], strFormId);
608 if (!confirm) {
609 HILOG_ERROR("ConvertFromJsValue failed.");
610 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
611 }
612 if (!ConvertStringToInt64(strFormId, formId)) {
613 HILOG_ERROR("convert form string failed.");
614 errCode = ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR;
615 }
616 if (info.argv[PARAM1]->TypeOf() != NATIVE_OBJECT) {
617 HILOG_ERROR("formBindingData is not napi_object.");
618 errCode = ERR_APPEXECFWK_FORM_INVALID_PROVIDER_DATA;
619 }
620 auto formProviderData = std::make_shared<OHOS::AppExecFwk::FormProviderData>();
621 auto arg1 = reinterpret_cast<napi_value>(info.argv[PARAM1]);
622 std::string formDataStr = GetStringByProp(env, arg1, "data");
623 formProviderData->SetDataString(formDataStr);
624 formProviderData->ParseImagesData();
625 AsyncTask::CompleteCallback complete =
626 [errCode, formId, data = formProviderData](NativeEngine &engine, AsyncTask &task, int32_t status) {
627 if (errCode != ERR_OK) {
628 auto retCode = QueryRetCode(errCode);
629 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
630 return;
631 }
632 int32_t ret = FormMgr::GetInstance().UpdateForm(formId, *data);
633 if (ret != ERR_OK) {
634 auto retCode = QueryRetCode(ret);
635 task.Reject(engine, CreateJsError(engine, retCode, QueryRetMsg(retCode)));
636 return;
637 }
638 task.Resolve(engine, CreateJsValue(engine, ret));
639 };
640 NativeValue *lastParam = (info.argc == ARGS_SIZE_THREE) ? info.argv[PARAM2] : nullptr;
641 NativeValue *result = nullptr;
642 AsyncTask::Schedule("JsFormProvider::OnUpdateForm",
643 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
644 return result;
645 }
646 } // namespace AbilityRuntime
647 } // namespace OHOS
648