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_mgr_errors.h"
23 #include "form_mgr.h"
24 #include "js_runtime_utils.h"
25 #include "ipc_skeleton.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 #include "tokenid_kit.h"
33 
34 namespace OHOS {
35 namespace AbilityRuntime {
36 using namespace OHOS;
37 using namespace OHOS::AAFwk;
38 using namespace OHOS::AppExecFwk;
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 const std::string IS_FORM_AGENT = "isFormAgent";
45 
CheckParamNum(napi_env env,size_t argc,size_t minParamNum,size_t maxParamNum)46 bool CheckParamNum(napi_env env, size_t argc, size_t minParamNum, size_t maxParamNum)
47 {
48     HILOG_DEBUG("argc is %{public}zu,param range is [%{public}zu,%{public}zu]",
49         argc, minParamNum, maxParamNum);
50     if (argc > maxParamNum || argc < minParamNum) {
51         HILOG_ERROR("invalid param number %{public}zu", argc);
52         std::string errMsg = "[" + std::to_string(minParamNum) + ", " + std::to_string(maxParamNum) + "]";
53         NapiFormUtil::ThrowParamNumError(env, std::to_string(argc), errMsg);
54         return false;
55     }
56     return true;
57 }
58 
ConvertFormInfoFilterThrow(napi_env env,napi_value jsValue,AppExecFwk::FormInfoFilter & formInfoFilter)59 bool ConvertFormInfoFilterThrow(napi_env env, napi_value jsValue, AppExecFwk::FormInfoFilter &formInfoFilter)
60 {
61     napi_valuetype jsValueType = napi_undefined;
62     napi_typeof(env, jsValue, &jsValueType);
63     if (jsValueType != napi_object) {
64         HILOG_ERROR("an object is expected, but an argument of different type is passed in");
65         NapiFormUtil::ThrowParamTypeError(env, "filter", "formInfo.FormInfoFilter");
66         return false;
67     }
68 
69     napi_value nativeDataValue = nullptr;
70     napi_status ret = napi_get_named_property(env, jsValue, "moduleName", &nativeDataValue);
71     if (ret != napi_ok) {
72         HILOG_ERROR("get property failed");
73         NapiFormUtil::ThrowParamError(env, "Failed to get property.");
74         return false;
75     }
76     napi_valuetype nativeDataValueType = napi_undefined;
77     napi_typeof(env, nativeDataValue, &nativeDataValueType);
78     if (nativeDataValue == nullptr || (nativeDataValueType != napi_undefined &&
79         !ConvertFromJsValue(env, nativeDataValue, formInfoFilter.moduleName))) {
80         HILOG_ERROR("convert nativeDataValue failed");
81         NapiFormUtil::ThrowParamError(env, "Failed to convert FormInfoFilter.");
82         return false;
83     }
84 
85     HILOG_INFO("module:%{public}s", formInfoFilter.moduleName.c_str());
86 
87     return true;
88 }
89 }
90 
GetStringByProp(napi_env env,napi_value value,const std::string & prop)91 static std::string GetStringByProp(napi_env env, napi_value value, const std::string &prop)
92 {
93     HILOG_DEBUG("GetStringByProp start");
94     std::string result;
95     bool propExist = false;
96     napi_value propValue = nullptr;
97     napi_valuetype valueType = napi_undefined;
98     napi_has_named_property(env, value, prop.c_str(), &propExist);
99     if (!propExist) {
100         HILOG_ERROR("prop[%{public}s] absent", prop.c_str());
101         return result;
102     }
103     napi_get_named_property(env, value, prop.c_str(), &propValue);
104     if (propValue == nullptr) {
105         HILOG_ERROR("prop[%{public}s] get error", prop.c_str());
106         return result;
107     }
108     napi_typeof(env, propValue, &valueType);
109     if (valueType != napi_string) {
110         HILOG_ERROR("prop[%{public}s] not string", prop.c_str());
111         return result;
112     }
113     size_t size = 0;
114     if (napi_get_value_string_utf8(env, propValue, nullptr, 0, &size) != napi_ok) {
115         HILOG_ERROR("prop[%{public}s] get size error", prop.c_str());
116         return result;
117     }
118     result.reserve(size + 1);
119     result.resize(size);
120     if (napi_get_value_string_utf8(env, propValue, result.data(), (size + 1), &size) != napi_ok) {
121         HILOG_ERROR("prop[%{public}s] get value error", prop.c_str());
122         return "";
123     }
124     return result;
125 }
126 
Finalizer(napi_env env,void * data,void * hint)127 void JsFormProvider::Finalizer(napi_env env, void *data, void *hint)
128 {
129     HILOG_INFO("call");
130     std::unique_ptr<JsFormProvider>(static_cast<JsFormProvider *>(data));
131 }
132 
GetFormsInfo(napi_env env,napi_callback_info info)133 napi_value JsFormProvider::GetFormsInfo(napi_env env, napi_callback_info info)
134 {
135     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnGetFormsInfo);
136 }
137 
OnGetFormsInfoParseParam(NapiParamPackage & napiParam,size_t & convertArgc,bool & isPromise,AppExecFwk::FormInfoFilter & formInfoFilter)138 bool JsFormProvider::OnGetFormsInfoParseParam(NapiParamPackage &napiParam,
139     size_t &convertArgc, bool &isPromise, AppExecFwk::FormInfoFilter &formInfoFilter)
140 {
141     napi_env env = napiParam.env;
142     size_t argc  = napiParam.argc;
143     napi_value* argv = napiParam.argv;
144     // GetformsInfo()
145     if (argc == ARGS_SIZE_ZERO) {
146         isPromise = true;
147     }
148     if (argc == ARGS_SIZE_ONE) {
149         napi_valuetype argvZeroType = napi_undefined;
150         napi_typeof(env, argv[PARAM0], &argvZeroType);
151         if (argvZeroType != napi_undefined) {
152             // GetformsInfo(*)
153             if (argvZeroType == napi_function) {
154                 // GetformsInfo(callback)
155                 isPromise = false;
156             } else {
157                 // GetformsInfo(*);GetformsInfo(fliter)
158                 if (ConvertFormInfoFilterThrow(env, argv[PARAM0], formInfoFilter)) {
159                     convertArgc++;
160                     isPromise = true;
161                 } else {
162                     // no default value
163                     return false;
164                 }
165             }
166         } else {
167             isPromise = true;
168         }
169     }
170 
171     if (argc >= ARGS_SIZE_TWO) {
172         napi_valuetype argvType = napi_undefined;
173         napi_typeof(env, argv[PARAM0], &argvType);
174         if (argvType != napi_undefined) {
175             if (argvType == napi_function) {
176                 // GetformsInfo(callback, *)
177                 isPromise = false;
178             } else {
179                 // GetformsInfo(fliter, *) || GetformsInfo(fliter, callback)
180                 if (ConvertFormInfoFilterThrow(env, argv[PARAM0], formInfoFilter)) {
181                     convertArgc++;
182                     // GetformsInfo(fliter, callback)
183                     napi_valuetype paramTwoType = napi_undefined;
184                     napi_typeof(env, argv[PARAM1], &paramTwoType);
185                     isPromise = paramTwoType != napi_function;
186                 } else {
187                     HILOG_ERROR("convert form info filter failed");
188                     return false;
189                 }
190             }
191         } else {
192             isPromise = true;
193         }
194     }
195     return true;
196 }
197 
OnGetFormsInfo(napi_env env,size_t argc,napi_value * argv)198 napi_value JsFormProvider::OnGetFormsInfo(napi_env env, size_t argc, napi_value* argv)
199 {
200     HILOG_DEBUG("call");
201 
202     size_t convertArgc = 0;
203     bool isPromise = false;
204     FormInfoFilter formInfoFilter;
205 
206     NapiParamPackage napiParam(env, argc, argv);
207 
208     if (!OnGetFormsInfoParseParam(napiParam, convertArgc, isPromise, formInfoFilter)) {
209         HILOG_ERROR("parse param failed");
210         return CreateJsUndefined(env);
211     }
212 
213     NapiAsyncTask::CompleteCallback complete =
214         [formInfoFilter](napi_env env, NapiAsyncTask &task, int32_t status) {
215             std::vector<FormInfo> formInfos;
216             auto ret = FormMgr::GetInstance().GetFormsInfo(formInfoFilter, formInfos);
217             if (ret != ERR_OK) {
218                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
219                 return;
220             }
221             task.ResolveWithNoError(env, CreateFormInfos(env, formInfos));
222         };
223 
224     napi_value lastParam = isPromise ? nullptr : argv[convertArgc];
225     napi_value result = nullptr;
226     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnGetFormsInfo",
227         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
228     return result;
229 }
230 
SetFormNextRefreshTime(napi_env env,napi_callback_info info)231 napi_value JsFormProvider::SetFormNextRefreshTime(napi_env env, napi_callback_info info)
232 {
233     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnSetFormNextRefreshTime);
234 }
235 
OnSetFormNextRefreshTime(napi_env env,size_t argc,napi_value * argv)236 napi_value JsFormProvider::OnSetFormNextRefreshTime(napi_env env, size_t argc, napi_value* argv)
237 {
238     HILOG_DEBUG("call");
239     if (CheckParamNum(env, argc, ARGS_SIZE_TWO, ARGS_SIZE_THREE) == false) {
240         return CreateJsUndefined(env);
241     }
242     napi_valuetype paramZeroType = napi_undefined;
243     napi_typeof(env, argv[PARAM0], &paramZeroType);
244     if (paramZeroType != napi_string) {
245         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
246         return CreateJsUndefined(env);
247     }
248     int64_t formId = 0;
249     std::string strFormId;
250     if (!ConvertFromJsValue(env, argv[PARAM0], strFormId)) {
251         HILOG_ERROR("ConvertFromJsValue failed");
252         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
253         return CreateJsUndefined(env);
254     }
255     if (!ConvertStringToInt64(strFormId, formId)) {
256         HILOG_ERROR("convert form string failed");
257         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
258         return CreateJsUndefined(env);
259     }
260     napi_valuetype paramOneType = napi_undefined;
261     napi_typeof(env, argv[PARAM1], &paramOneType);
262     if (paramOneType != napi_number) {
263         NapiFormUtil::ThrowParamTypeError(env, "minute", "number");
264         return CreateJsUndefined(env);
265     }
266     int32_t time;
267     if (!ConvertFromJsValue(env, argv[PARAM1], time)) {
268         NapiFormUtil::ThrowParamTypeError(env, "minute", "number");
269         return CreateJsUndefined(env);
270     }
271     NapiAsyncTask::CompleteCallback complete = [formId, time](napi_env env, NapiAsyncTask &task, int32_t status) {
272         int32_t ret = FormMgr::GetInstance().SetNextRefreshTime(formId, time);
273         if (ret != ERR_OK) {
274             task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
275             return;
276         }
277         task.ResolveWithNoError(env, CreateJsUndefined(env));
278     };
279     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
280     napi_value result = nullptr;
281     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnSetFormNextRefreshTime",
282         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
283     return result;
284 }
285 
UpdateForm(napi_env env,napi_callback_info info)286 napi_value JsFormProvider::UpdateForm(napi_env env, napi_callback_info info)
287 {
288     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnUpdateForm);
289 }
290 
OnUpdateFormParseParam(napi_env env,size_t argc,napi_value * argv,int64_t & formId)291 napi_value JsFormProvider::OnUpdateFormParseParam(napi_env env, size_t argc, napi_value* argv, int64_t &formId)
292 {
293     if (CheckParamNum(env, argc, ARGS_SIZE_TWO, ARGS_SIZE_THREE) == false) {
294         return CreateJsUndefined(env);
295     }
296     napi_valuetype paramZeroType = napi_undefined;
297     napi_typeof(env, argv[PARAM0], &paramZeroType);
298     if (paramZeroType != napi_string) {
299         HILOG_ERROR("formId not napi_string");
300         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
301         return CreateJsUndefined(env);
302     }
303     std::string strFormId;
304     bool confirm = ConvertFromJsValue(env, argv[PARAM0], strFormId);
305     if (!confirm) {
306         HILOG_ERROR("ConvertFromJsValue failed");
307         NapiFormUtil::ThrowParamTypeError(env, "formId", "string");
308         return CreateJsUndefined(env);
309     }
310     if (!ConvertStringToInt64(strFormId, formId)) {
311         HILOG_ERROR("convert form string failed");
312         NapiFormUtil::ThrowParamError(env, "Failed to convert formId.");
313         return CreateJsUndefined(env);
314     }
315     napi_valuetype paramOneType = napi_undefined;
316     napi_typeof(env, argv[PARAM1], &paramOneType);
317     if (paramOneType != napi_object) {
318         HILOG_ERROR("formBindingData not napi_object");
319         NapiFormUtil::ThrowParamTypeError(env, "formBindingData", "formBindingData.FormBindingData");
320         return CreateJsUndefined(env);
321     }
322     return nullptr;
323 }
324 
OnUpdateForm(napi_env env,size_t argc,napi_value * argv)325 napi_value JsFormProvider::OnUpdateForm(napi_env env, size_t argc, napi_value* argv)
326 {
327     HILOG_DEBUG("call");
328 
329     int64_t formId = 0;
330     napi_value parseResult = OnUpdateFormParseParam(env, argc, argv, formId);
331     if (parseResult != nullptr) {
332         HILOG_ERROR("parse param failed");
333         return parseResult;
334     }
335 
336     auto formProviderData = std::make_shared<OHOS::AppExecFwk::FormProviderData>();
337     std::string formDataStr = GetStringByProp(env, argv[PARAM1], "data");
338     formProviderData->SetDataString(formDataStr);
339     formProviderData->ParseImagesData();
340 
341     std::vector<AppExecFwk::FormDataProxy> formDataProxies;
342     napi_value nativeProxies = nullptr;
343     napi_get_named_property(env, argv[PARAM1], "proxies", &nativeProxies);
344     if (nativeProxies != nullptr) {
345         ConvertFromDataProxies(env, nativeProxies, formDataProxies);
346     }
347 
348     NapiAsyncTask::CompleteCallback complete =
349         [formId, data = formProviderData, formDataProxies](napi_env env, NapiAsyncTask &task, int32_t status) {
350             int32_t ret = FormMgr::GetInstance().UpdateForm(formId, *data, formDataProxies);
351             if (ret != ERR_OK) {
352                 task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
353                 return;
354             }
355             task.ResolveWithNoError(env, CreateJsUndefined(env));
356         };
357     napi_value lastParam = (argc == ARGS_SIZE_THREE) ? argv[PARAM2] : nullptr;
358     napi_value result = nullptr;
359     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnUpdateForm",
360         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
361     return result;
362 }
363 
IsRequestPublishFormSupported(napi_env env,napi_callback_info info)364 napi_value JsFormProvider::IsRequestPublishFormSupported(napi_env env, napi_callback_info info)
365 {
366     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnIsRequestPublishFormSupported);
367 }
368 
OnIsRequestPublishFormSupported(napi_env env,size_t argc,napi_value * argv)369 napi_value JsFormProvider::OnIsRequestPublishFormSupported(napi_env env, size_t argc, napi_value* argv)
370 {
371     HILOG_DEBUG("call");
372     if (CheckParamNum(env, argc, ARGS_SIZE_ZERO, ARGS_SIZE_ONE) == false) {
373         return CreateJsUndefined(env);
374     }
375 
376     auto selfToken = IPCSkeleton::GetSelfTokenID();
377     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
378         HILOG_ERROR("The application not system-app,can't use system-api");
379         NapiFormUtil::ThrowByExternalErrorCode(env, ERR_FORM_EXTERNAL_NOT_SYSTEM_APP);
380         return CreateJsUndefined(env);
381     }
382 
383     NapiAsyncTask::CompleteCallback complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
384         bool value = FormMgr::GetInstance().IsRequestPublishFormSupported();
385         napi_value jsValue = nullptr;
386         napi_get_boolean(env, value, &jsValue);
387         task.ResolveWithNoError(env, jsValue);
388     };
389     napi_value lastParam = (argc == ARGS_SIZE_ONE) ? argv[PARAM0] : nullptr;
390     napi_value result = nullptr;
391     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnIsRequestPublishFormSupported",
392         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
393     return result;
394 }
395 
RequestPublishForm(napi_env env,napi_callback_info info)396 napi_value JsFormProvider::RequestPublishForm(napi_env env, napi_callback_info info)
397 {
398     GET_CB_INFO_AND_CALL(env, info, JsFormProvider, OnRequestPublishForm);
399 }
400 
OnRequestPublishForm(napi_env env,size_t argc,napi_value * argv)401 napi_value JsFormProvider::OnRequestPublishForm(napi_env env, size_t argc, napi_value* argv)
402 {
403     HILOG_DEBUG("call");
404     if (CheckParamNum(env, argc, ARGS_SIZE_ONE, ARGS_SIZE_THREE) == false) {
405         return CreateJsUndefined(env);
406     }
407 
408     auto asyncCallbackInfo = std::make_shared<RequestPublishFormCallbackInfo>();
409     decltype(argc) convertArgc = 0;
410     napi_valuetype paramZeroType = napi_undefined;
411     napi_typeof(env, argv[PARAM0], &paramZeroType);
412     if (paramZeroType != napi_object) {
413         HILOG_ERROR("formId not napi_object");
414         NapiFormUtil::ThrowParamTypeError(env, "want", "Want");
415         return CreateJsUndefined(env);
416     }
417     if (!AppExecFwk::UnwrapWant(env, argv[PARAM0], asyncCallbackInfo->want)) {
418         HILOG_ERROR("fail convert want");
419         NapiFormUtil::ThrowParamError(env, "Failed to convert want.");
420         return CreateJsUndefined(env);
421     }
422     convertArgc++;
423 
424     if (argc > ARGS_SIZE_ONE) {
425         napi_valuetype paramOneType = napi_undefined;
426         napi_typeof(env, argv[PARAM1], &paramOneType);
427         if (paramOneType == napi_object) {
428             asyncCallbackInfo->withFormBindingData = true;
429             auto formProviderData = std::make_unique<FormProviderData>();
430             std::string formDataStr = GetStringByProp(env, argv[PARAM1], "data");
431             formProviderData->SetDataString(formDataStr);
432             formProviderData->ParseImagesData();
433             asyncCallbackInfo->formProviderData = std::move(formProviderData);
434 
435             napi_value nativeProxies = nullptr;
436             napi_get_named_property(env, argv[PARAM1], "proxies", &nativeProxies);
437             if (nativeProxies != nullptr) {
438                 ConvertFromDataProxies(env, nativeProxies, asyncCallbackInfo->formDataProxies);
439             }
440             convertArgc++;
441         } else if (paramOneType == napi_function) {
442             asyncCallbackInfo->withFormBindingData = false;
443         } else {
444             HILOG_ERROR("formBindingData not napi_object");
445             NapiFormUtil::ThrowParamTypeError(env, "formBindingData", "formBindingData.FormBindingData");
446             return CreateJsUndefined(env);
447         }
448     }
449 
450     NapiAsyncTask::CompleteCallback complete = [asyncCallbackInfo](napi_env env, NapiAsyncTask &task, int32_t status) {
451         int64_t formId = 0;
452         asyncCallbackInfo->want.SetParam(IS_FORM_AGENT, false);
453         ErrCode ret = FormMgr::GetInstance().RequestPublishForm(asyncCallbackInfo->want,
454             asyncCallbackInfo->withFormBindingData, asyncCallbackInfo->formProviderData, formId,
455             asyncCallbackInfo->formDataProxies);
456         if (ret != ERR_OK) {
457             task.Reject(env, NapiFormUtil::CreateErrorByInternalErrorCode(env, ret));
458             return;
459         }
460         std::string formIdStr = std::to_string(formId);
461         napi_value result = nullptr;
462         napi_create_string_utf8(env, formIdStr.c_str(), formIdStr.size(), &result);
463         task.ResolveWithNoError(env, result);
464     };
465     napi_value lastParam = (argc <= convertArgc) ? nullptr : argv[convertArgc];
466     napi_value result = nullptr;
467     NapiAsyncTask::ScheduleWithDefaultQos("JsFormProvider::OnRequestPublishForm",
468         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
469     return result;
470 }
471 
ConvertFromDataProxies(napi_env env,napi_value value,std::vector<AppExecFwk::FormDataProxy> & formDataProxies)472 bool JsFormProvider::ConvertFromDataProxies(napi_env env, napi_value value,
473     std::vector<AppExecFwk::FormDataProxy> &formDataProxies)
474 {
475     bool result = false;
476     napi_is_array(env, value, &result);
477     if (value == nullptr || !result) {
478         HILOG_WARN("null jsValue not array");
479         return false;
480     }
481 
482     uint32_t length = 0;
483     napi_get_array_length(env, value, &length);
484     napi_value element = nullptr;
485     for (uint32_t i = 0; i < length; i++) {
486         AppExecFwk::FormDataProxy formDataProxy("", "");
487         napi_get_element(env, value, i, &element);
488         if (!ConvertFormDataProxy(env, element, formDataProxy)) {
489             HILOG_ERROR("GetElement from array [%{public}u] error", i);
490             continue;
491         }
492         formDataProxies.push_back(formDataProxy);
493     }
494     return true;
495 }
496 
ConvertFormDataProxy(napi_env env,napi_value value,AppExecFwk::FormDataProxy & formDataProxy)497 bool JsFormProvider::ConvertFormDataProxy(napi_env env, napi_value value,
498     AppExecFwk::FormDataProxy &formDataProxy)
499 {
500     napi_valuetype valueType = napi_undefined;
501     napi_typeof(env, value, &valueType);
502     if (value == nullptr || valueType != napi_object) {
503         HILOG_WARN("null jsValue,not object");
504         return false;
505     }
506 
507     napi_value key = nullptr;
508     napi_get_named_property(env, value, "key", &key);
509     if (!ConvertFromJsValue(env, key, formDataProxy.key)) {
510         HILOG_ERROR("Parse key error");
511         return false;
512     }
513 
514     napi_value subscribeId = nullptr;
515     napi_get_named_property(env, value, "subscriberId", &subscribeId);
516     if (subscribeId != nullptr && !ConvertFromJsValue(env, subscribeId, formDataProxy.subscribeId)) {
517         HILOG_WARN("Parse subscribeId failed, use empty as default value");
518         formDataProxy.subscribeId = "";
519     }
520     HILOG_INFO("key:%{public}s,subscribeId:%{public}s", formDataProxy.key.c_str(),
521         formDataProxy.subscribeId.c_str());
522     return true;
523 }
524 }  // namespace AbilityRuntime
525 }  // namespace OHOS
526