1 /*
2 * Copyright (c) 2021-2024 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_util.h"
17
18 #include <cinttypes>
19 #include <regex>
20 #include <uv.h>
21 #include <vector>
22
23 #include "fms_log_wrapper.h"
24 #include "form_mgr.h"
25 #include "form_mgr_errors.h"
26 #include "napi/native_api.h"
27 #include "napi/native_node_api.h"
28 #include "running_form_info.h"
29 #include "runtime.h"
30
31 using namespace OHOS;
32 using namespace OHOS::AAFwk;
33 using namespace OHOS::AppExecFwk;
34
35 namespace OHOS {
36 namespace AbilityRuntime {
37 namespace {
38 constexpr size_t ARGS_SIZE_TWO = 2;
39 constexpr int INT_64_LENGTH = 19;
40 constexpr int ZERO_VALUE = 0;
41 constexpr int REF_COUNT = 1;
42 constexpr int BASE_NUMBER = 9;
43 constexpr int CALLBACK_FLG = 1;
44 constexpr int64_t HEAD_BIT_NUM = 9000000000000000000;
45 const std::map<int32_t, int32_t> ERROR_CODE_MAP = {
46 { ERR_OK, ERR_OK },
47 { ERR_APPEXECFWK_FORM_COMMON_CODE, ERR_COMMON },
48 { ERR_APPEXECFWK_FORM_PERMISSION_DENY, ERR_PERMISSION_DENY },
49 { ERR_APPEXECFWK_FORM_PERMISSION_DENY_BUNDLE, ERR_PERMISSION_DENY },
50 { ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS, ERR_PERMISSION_DENY },
51 { ERR_APPEXECFWK_FORM_GET_INFO_FAILED, ERR_GET_INFO_FAILED },
52 { ERR_APPEXECFWK_FORM_GET_BUNDLE_FAILED, ERR_GET_BUNDLE_FAILED },
53 { ERR_APPEXECFWK_FORM_INVALID_PARAM, ERR_ADD_INVALID_PARAM },
54 { ERR_APPEXECFWK_FORM_INVALID_FORM_ID, ERR_ADD_INVALID_PARAM },
55 { ERR_APPEXECFWK_FORM_FORM_ID_NUM_ERR, ERR_ADD_INVALID_PARAM },
56 { ERR_APPEXECFWK_FORM_FORM_ARRAY_ERR, ERR_ADD_INVALID_PARAM },
57 { ERR_APPEXECFWK_FORM_RELEASE_FLG_ERR, ERR_COMMON },
58 { ERR_APPEXECFWK_FORM_REFRESH_TIME_NUM_ERR, ERR_COMMON },
59 { ERR_APPEXECFWK_FORM_INVALID_BUNDLENAME, ERR_ADD_INVALID_PARAM },
60 { ERR_APPEXECFWK_FORM_INVALID_MODULENAME, ERR_ADD_INVALID_PARAM },
61 { ERR_APPEXECFWK_FORM_INVALID_PROVIDER_DATA, ERR_ADD_INVALID_PARAM },
62 { ERR_APPEXECFWK_FORM_INVALID_REFRESH_TIME, ERR_ADD_INVALID_PARAM },
63 { ERR_APPEXECFWK_FORM_FORM_ID_ARRAY_ERR, ERR_ADD_INVALID_PARAM },
64 { ERR_APPEXECFWK_FORM_SERVER_STATUS_ERR, ERR_COMMON },
65 { ERR_APPEXECFWK_FORM_CFG_NOT_MATCH_ID, ERR_CFG_NOT_MATCH_ID },
66 { ERR_APPEXECFWK_FORM_NOT_EXIST_ID, ERR_NOT_EXIST_ID },
67 { ERR_APPEXECFWK_FORM_PROVIDER_DATA_EMPTY, ERR_ADD_INVALID_PARAM },
68 { ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED, ERR_BIND_PROVIDER_FAILED },
69 { ERR_APPEXECFWK_FORM_MAX_SYSTEM_FORMS, ERR_MAX_SYSTEM_FORMS },
70 { ERR_APPEXECFWK_FORM_EXCEED_INSTANCES_PER_FORM, ERR_MAX_INSTANCES_PER_FORM },
71 { ERR_APPEXECFWK_FORM_OPERATION_NOT_SELF, ERR_OPERATION_FORM_NOT_SELF },
72 { ERR_APPEXECFWK_FORM_PROVIDER_DEL_FAIL, ERR_PROVIDER_DEL_FAIL },
73 { ERR_APPEXECFWK_FORM_MAX_FORMS_PER_CLIENT, ERR_MAX_FORMS_PER_CLIENT },
74 { ERR_APPEXECFWK_FORM_MAX_SYSTEM_TEMP_FORMS, ERR_MAX_SYSTEM_TEMP_FORMS },
75 { ERR_APPEXECFWK_FORM_NO_SUCH_MODULE, ERR_FORM_NO_SUCH_MODULE },
76 { ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY, ERR_FORM_NO_SUCH_ABILITY },
77 { ERR_APPEXECFWK_FORM_NO_SUCH_DIMENSION, ERR_FORM_NO_SUCH_DIMENSION },
78 { ERR_APPEXECFWK_FORM_FA_NOT_INSTALLED, ERR_FORM_FA_NOT_INSTALLED },
79 { ERR_APPEXECFWK_FORM_MAX_REQUEST, ERR_MAX_SYSTEM_FORMS },
80 { ERR_APPEXECFWK_FORM_MAX_REFRESH, ERR_MAX_SYSTEM_FORMS },
81 { ERR_APPEXECFWK_FORM_GET_BMS_FAILED, ERR_COMMON },
82 { ERR_APPEXECFWK_FORM_GET_HOST_FAILED, ERR_COMMON },
83 { ERR_APPEXECFWK_FORM_GET_FMS_FAILED, ERR_COMMON },
84 { ERR_APPEXECFWK_FORM_SEND_FMS_MSG, ERR_COMMON },
85 { ERR_APPEXECFWK_FORM_FORM_DUPLICATE_ADDED, ERR_FORM_DUPLICATE_ADDED },
86 { ERR_APPEXECFWK_FORM_IN_RECOVER, ERR_IN_RECOVERY },
87 { ERR_APPEXECFWK_FORM_DISTRIBUTED_SCHEDULE_FAILED, ERR_DISTRIBUTED_SCHEDULE_FAILED },
88 { ERR_APPEXECFWK_FORM_GET_SYSMGR_FAILED, ERR_SYSTEM_RESPONSES_FAILED }
89 };
90 const std::map<int32_t, std::string> CODE_MSG_MAP = {
91 { ERR_OK, "success" },
92 { ERR_COMMON, "internal error" },
93 { ERR_PERMISSION_DENY, "does not have permission to use forms" },
94 { ERR_GET_INFO_FAILED, "failed to obtain the configuration information" },
95 { ERR_GET_BUNDLE_FAILED, "failed to obtain the bundle information" },
96 { ERR_GET_LAYOUT_FAILED, "failed to initialize the form layout" },
97 { ERR_ADD_INVALID_PARAM, "invalid input parameter during form operation" },
98 { ERR_CFG_NOT_MATCH_ID, "the form id is different from that obtained for the first time" },
99 { ERR_NOT_EXIST_ID, "the ID of the form to be operated does not exist" },
100 { ERR_BIND_PROVIDER_FAILED, "failed to bind the Form Manager Service to the provider service" },
101 { ERR_MAX_SYSTEM_FORMS, "the total number of added forms exceeds the maximum allowed by the system" },
102 { ERR_MAX_INSTANCES_PER_FORM, "the number of form instances exceeds the maximum allowed by the system" },
103 { ERR_OPERATION_FORM_NOT_SELF, "can not be operated by the current application" },
104 { ERR_PROVIDER_DEL_FAIL, "failed to instruct the form provider to delete the form" },
105 { ERR_MAX_FORMS_PER_CLIENT, "the total number of added forms exceeds the maximum per client" },
106 { ERR_MAX_SYSTEM_TEMP_FORMS, "the total number of added temp forms exceeds the maximum in system" },
107 { ERR_FORM_NO_SUCH_MODULE, "the module can not be find in system" },
108 { ERR_FORM_NO_SUCH_ABILITY, "the ability can not be find in system" },
109 { ERR_FORM_NO_SUCH_DIMENSION, "the dimension is not exist in the form" },
110 { ERR_FORM_FA_NOT_INSTALLED, "the ability is not installed" },
111 { ERR_SYSTEM_RESPONSES_FAILED, "failed to obtain the RPC object" },
112 { ERR_FORM_DUPLICATE_ADDED, "failed to obtain the form requested by the client" },
113 { ERR_DISTRIBUTED_SCHEDULE_FAILED, "failed to distributed schedule" },
114 { ERR_IN_RECOVERY, "the form is being restored" }
115 };
116 }
117
Throw(napi_env env,int32_t errCode,const std::string & errMessage)118 bool NapiFormUtil::Throw(napi_env env, int32_t errCode, const std::string &errMessage)
119 {
120 napi_value error = CreateJsError(env, errCode, errMessage);
121 napi_throw(env, error);
122 return true;
123 }
124
ThrowByInternalErrorCode(napi_env env,int32_t internalErrorCode)125 bool NapiFormUtil::ThrowByInternalErrorCode(napi_env env, int32_t internalErrorCode)
126 {
127 int32_t externalErrorCode = 0;
128 std::string externalErrorMessage;
129 FormMgr::GetInstance().GetExternalError(internalErrorCode, externalErrorCode, externalErrorMessage);
130 return Throw(env, externalErrorCode, externalErrorMessage);
131 }
132
ThrowByExternalErrorCode(napi_env env,int32_t externalErrorCode)133 bool NapiFormUtil::ThrowByExternalErrorCode(napi_env env, int32_t externalErrorCode)
134 {
135 std::string externalErrorMessage = FormMgr::GetInstance().GetErrorMsgByExternalErrorCode(externalErrorCode);
136 return Throw(env, externalErrorCode, externalErrorMessage);
137 }
138
CreateErrorByInternalErrorCode(napi_env env,int32_t internalErrorCode)139 napi_value NapiFormUtil::CreateErrorByInternalErrorCode(napi_env env, int32_t internalErrorCode)
140 {
141 int32_t externalErrorCode = 0;
142 std::string externalErrorMessage;
143 FormMgr::GetInstance().GetExternalError(internalErrorCode, externalErrorCode, externalErrorMessage);
144 return CreateJsError(env, externalErrorCode, externalErrorMessage);
145 }
146
CreateErrorByExternalErrorCode(napi_env env,int32_t externalErrorCode)147 napi_value NapiFormUtil::CreateErrorByExternalErrorCode(napi_env env, int32_t externalErrorCode)
148 {
149 std::string externalErrorMessage = FormMgr::GetInstance().GetErrorMsgByExternalErrorCode(externalErrorCode);
150 return CreateJsError(env, externalErrorCode, externalErrorMessage);
151 }
152
ThrowParamTypeError(napi_env env,const std::string & paramName,const std::string & type)153 bool NapiFormUtil::ThrowParamTypeError(napi_env env, const std::string ¶mName, const std::string &type)
154 {
155 return Throw(env, ERR_FORM_EXTERNAL_PARAM_INVALID, CreateParamTypeErrorMessage(paramName, type));
156 }
157
ThrowParamNumError(napi_env env,const std::string & gotNum,const std::string & expectedNum)158 bool NapiFormUtil::ThrowParamNumError(napi_env env, const std::string &gotNum, const std::string &expectedNum)
159 {
160 std::string errorMessage = "Parameter error. Got " + gotNum + ", expected " + expectedNum;
161 return Throw(env, ERR_FORM_EXTERNAL_PARAM_INVALID, errorMessage);
162 }
163
ThrowParamError(napi_env env,const std::string & extraMessage)164 bool NapiFormUtil::ThrowParamError(napi_env env, const std::string &extraMessage)
165 {
166 std::string errorMessage = "Parameter error. " + extraMessage;
167 return Throw(env, ERR_FORM_EXTERNAL_PARAM_INVALID, errorMessage);
168 }
169
CreateParamTypeErrorMessage(const std::string & paramName,const std::string & type)170 std::string NapiFormUtil::CreateParamTypeErrorMessage(const std::string ¶mName, const std::string &type)
171 {
172 std::string errorMessage = "Parameter error.";
173 if (paramName.empty()) {
174 // Parameter error.
175 return errorMessage;
176 }
177 errorMessage += " The type of \"" + paramName + "\"";
178 if (type.empty()) {
179 errorMessage += " is invalid.";
180 // Parameter error. The type of "paramName" is invalid.
181 return errorMessage;
182 }
183 errorMessage += " must be " + type + ".";
184 // Parameter error. The type of "${paramName}" must be ${type}.
185 return errorMessage;
186 }
187
188 /**
189 * @brief query the error message by error code
190 *
191 * @param[in] errorCode the error code return by form JS API.
192 *
193 * @return the error detail message
194 */
QueryRetMsg(int32_t errorCode)195 std::string QueryRetMsg(int32_t errorCode)
196 {
197 auto iter = CODE_MSG_MAP.find(errorCode);
198 if (iter != CODE_MSG_MAP.end()) {
199 return iter->second;
200 } else {
201 return CODE_MSG_MAP.at(ERR_COMMON);
202 }
203 }
204
205 /**
206 * @brief query the error code by FMS errcode
207 *
208 * @param[in] innerErrorCode the error code return by form native API.
209 *
210 * @return the error detail message
211 */
QueryRetCode(int32_t innerErrorCode)212 int32_t QueryRetCode(int32_t innerErrorCode)
213 {
214 auto iter = ERROR_CODE_MAP.find(innerErrorCode);
215 if (iter != ERROR_CODE_MAP.end()) {
216 return iter->second;
217 } else {
218 return ERR_COMMON;
219 }
220 }
221
222 /**
223 * @brief NapiGetResult
224 *
225 * @param[in] env The environment that the Node-API call is invoked under
226 *
227 * @return napi_value
228 */
NapiGetResult(napi_env env,int iResult)229 napi_value NapiGetResult(napi_env env, int iResult)
230 {
231 napi_value result;
232 NAPI_CALL(env, napi_create_int32(env, iResult, &result));
233 return result;
234 }
235
236 /**
237 * @brief Convert string to int64_t
238 *
239 * @param[in] strInfo The string information
240 * @param[out] int64Value Convert string to int64_t
241 *
242 * @return Return the convert result
243 */
ConvertStringToInt64(const std::string & strInfo,int64_t & int64Value)244 bool ConvertStringToInt64(const std::string &strInfo, int64_t &int64Value)
245 {
246 size_t strLength = strInfo.size();
247 if (strLength == ZERO_VALUE) {
248 int64Value = ZERO_VALUE;
249 return true;
250 }
251 std::regex pattern("^0|-?[1-9][0-9]{0,18}$"); // "^-?[0-9]{1,19}$"
252 std::smatch match;
253 if (regex_match(strInfo, match, pattern)) {
254 HILOG_DEBUG("regex_match successed");
255 if (strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1) != "-") { // maximum: 9223372036854775807
256 if (strLength < INT_64_LENGTH) {
257 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
258 return true;
259 }
260 int maxSubValue = NapiFormUtil::ConvertStringToInt(strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1));
261 if (strLength == INT_64_LENGTH && maxSubValue < BASE_NUMBER) {
262 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
263 return true;
264 }
265 // Means 0x7FFFFFFFFFFFFFFF remove the first number:(2^63 - 1 - 9 * 10 ^ 19)
266 int64_t subValue = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo.substr(ZERO_VALUE + 1,
267 INT_64_LENGTH - 1)));
268 if (strLength == INT_64_LENGTH && subValue <= (INT64_MAX - HEAD_BIT_NUM)) {
269 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
270 return true;
271 }
272 return false;
273 }
274 if (strLength < INT_64_LENGTH + 1) { // The minimum value: -9223372036854775808
275 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
276 return true;
277 }
278 if (strLength == INT_64_LENGTH + 1) {
279 int minSubValue = NapiFormUtil::ConvertStringToInt(strInfo.substr(1, 1));
280 if (minSubValue < BASE_NUMBER) {
281 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
282 return true;
283 }
284
285 // Means 0x8000000000000000 remove the first number:-(2^63 - 9 * 10 ^ 19)
286 int64_t subValue = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo.substr(ZERO_VALUE + 2,
287 INT_64_LENGTH - 1)));
288 if (subValue <= (INT64_MAX - HEAD_BIT_NUM + 1)) {
289 int64Value = static_cast<int64_t>(NapiFormUtil::ConvertStringToLongLong(strInfo));
290 return true;
291 }
292 }
293 }
294 HILOG_DEBUG("regex_match failed");
295 return false;
296 }
297
298 /**
299 * @brief Create return message(callback)
300 *
301 * @param[in] env The environment that the Node-API call is invoked under
302 * @param[in] code result code
303 * @param[out] result result message
304 *
305 * @return void
306 */
InnerCreateCallbackRetMsg(napi_env env,int32_t code,napi_value (& result)[CALLBACK_RETURN_MSG_SIZE])307 void InnerCreateCallbackRetMsg(napi_env env, int32_t code, napi_value (&result)[CALLBACK_RETURN_MSG_SIZE])
308 {
309 HILOG_DEBUG("code:%{public}d", code);
310 napi_value error = nullptr;
311 napi_create_object(env, &error);
312
313 auto retCode = QueryRetCode(code);
314 auto retMsg = QueryRetMsg(retCode);
315
316 // create error code
317 napi_value errCode = nullptr;
318 napi_create_int32(env, retCode, &errCode);
319 napi_set_named_property(env, error, "code", errCode);
320
321 // create error message
322 napi_value errMsg = nullptr;
323 napi_create_string_utf8(env, retMsg.c_str(), NAPI_AUTO_LENGTH, &errMsg);
324 napi_set_named_property(env, error, "message", errMsg);
325
326 result[0] = error;
327 napi_get_undefined(env, &result[1]);
328 HILOG_DEBUG("end");
329 }
330
331 /**
332 * @brief Create return message(promise)
333 *
334 * @param[in] env The environment that the Node-API call is invoked under
335 * @param[in] code result code
336 * @param[out] result result message
337 *
338 * @return void
339 */
InnerCreatePromiseRetMsg(napi_env env,int32_t code,napi_value * result)340 void InnerCreatePromiseRetMsg(napi_env env, int32_t code, napi_value* result)
341 {
342 HILOG_DEBUG("code:%{public}d", code);
343 if (code == ERR_OK) {
344 napi_get_undefined(env, result);
345 return;
346 }
347 napi_value errInfo = nullptr;
348 napi_create_object(env, &errInfo);
349
350 auto retCode = QueryRetCode(code);
351 auto retMsg = QueryRetMsg(retCode);
352
353 // create error code
354 napi_value errCode = nullptr;
355 napi_create_int32(env, retCode, &errCode);
356 napi_set_named_property(env, errInfo, "code", errCode);
357
358 // create error message
359 napi_value errMsg = nullptr;
360 napi_create_string_utf8(env, retMsg.c_str(), NAPI_AUTO_LENGTH, &errMsg);
361 napi_set_named_property(env, errInfo, "message", errMsg);
362
363 *result = errInfo;
364 HILOG_DEBUG("end");
365 }
366
RetErrMsgForCallback(AsyncErrMsgCallbackInfo * asyncCallbackInfo)367 napi_value RetErrMsgForCallback(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
368 {
369 HILOG_INFO("call");
370
371 napi_env env = asyncCallbackInfo->env;
372 napi_value value = asyncCallbackInfo->callbackValue;
373
374 // Check the value type of the arguments
375 napi_valuetype valueType = napi_undefined;
376 NAPI_CALL(env, napi_typeof(env, value, &valueType));
377 NAPI_ASSERT(env, valueType == napi_function, "The arguments[1] type of deleteForm is incorrect,\
378 expected type is function.");
379
380 napi_create_reference(env, value, REF_COUNT, &asyncCallbackInfo->callback);
381
382 napi_value resourceName;
383 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
384 napi_create_async_work(
385 env,
386 nullptr,
387 resourceName,
388 [](napi_env env, void *data) {},
389 [](napi_env env, napi_status status, void *data) {
390 AsyncErrMsgCallbackInfo *asyncCallbackInfo = (AsyncErrMsgCallbackInfo *)data;
391 HILOG_INFO("complete");
392 if (asyncCallbackInfo->callback != nullptr) {
393 napi_value callback;
394 napi_value undefined;
395 napi_value result[ARGS_SIZE_TWO] = {0};
396 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->code, result);
397 napi_get_undefined(env, &undefined);
398 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
399 napi_value callResult;
400 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
401 napi_delete_reference(env, asyncCallbackInfo->callback);
402 }
403 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
404 delete asyncCallbackInfo;
405 },
406 (void *)asyncCallbackInfo,
407 &asyncCallbackInfo->asyncWork);
408 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
409 return NapiGetResult(env, 1);
410 }
411
RetErrMsgForPromise(AsyncErrMsgCallbackInfo * asyncCallbackInfo)412 napi_value RetErrMsgForPromise(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
413 {
414 HILOG_INFO("call");
415
416 napi_env env = asyncCallbackInfo->env;
417 napi_deferred deferred;
418 napi_value promise;
419 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
420 asyncCallbackInfo->deferred = deferred;
421
422 napi_value resourceName;
423 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
424 napi_create_async_work(
425 env,
426 nullptr,
427 resourceName,
428 [](napi_env env, void *data) {},
429 [](napi_env env, napi_status status, void *data) {
430 HILOG_INFO("promise complete");
431 AsyncErrMsgCallbackInfo *asyncCallbackInfo = (AsyncErrMsgCallbackInfo *)data;
432 napi_value result;
433 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->code, &result);
434 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
435 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
436 delete asyncCallbackInfo;
437 },
438 (void *)asyncCallbackInfo,
439 &asyncCallbackInfo->asyncWork);
440 napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
441 return promise;
442 }
443
444 /**
445 * @brief Send error message.
446 *
447 * @param[in] env The environment that the Node-API call is invoked under
448 * @param[in] asyncCallbackInfo Reference, callback info via Node-API
449 * @param[out] result result message
450 *
451 * @return void
452 */
RetErrMsg(AsyncErrMsgCallbackInfo * asyncCallbackInfo)453 napi_value RetErrMsg(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
454 {
455 HILOG_INFO("call");
456 if (asyncCallbackInfo == nullptr) {
457 HILOG_ERROR("null asyncCallback");
458 return nullptr;
459 }
460 if (asyncCallbackInfo->type == CALLBACK_FLG) {
461 return RetErrMsgForCallback(asyncCallbackInfo);
462 }
463 return RetErrMsgForPromise(asyncCallbackInfo);
464 }
465
InitErrMsg(napi_env env,int32_t code,int32_t type,napi_value callbackValue)466 AsyncErrMsgCallbackInfo *InitErrMsg(napi_env env, int32_t code, int32_t type, napi_value callbackValue)
467 {
468 auto *asyncErrorInfo = new (std::nothrow) AsyncErrMsgCallbackInfo {
469 .env = env,
470 .asyncWork = nullptr,
471 .deferred = nullptr,
472 .callback = nullptr,
473 .callbackValue = callbackValue,
474 .code = code,
475 .type = type
476 };
477 return asyncErrorInfo;
478 }
479
ParseRunningFormInfoIntoNapi(napi_env env,const RunningFormInfo & runningFormInfo,napi_value & result)480 void ParseRunningFormInfoIntoNapi(napi_env env, const RunningFormInfo &runningFormInfo, napi_value &result)
481 {
482 napi_create_object(env, &result);
483
484 napi_set_named_property(env, result, "formId", CreateJsValue(env, std::to_string(runningFormInfo.formId)));
485 napi_set_named_property(env, result, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
486 napi_set_named_property(env, result, "hostBundleName", CreateJsValue(env, runningFormInfo.hostBundleName));
487 napi_set_named_property(env, result, "visibilityType", CreateJsValue(env, (int32_t)runningFormInfo.formVisiblity));
488 napi_set_named_property(env, result, "moduleName", CreateJsValue(env, runningFormInfo.moduleName));
489 napi_set_named_property(env, result, "abilityName", CreateJsValue(env, runningFormInfo.abilityName));
490 napi_set_named_property(env, result, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
491 napi_set_named_property(env, result, "formName", CreateJsValue(env, runningFormInfo.formName));
492 napi_set_named_property(env, result, "dimension", CreateJsValue(env, runningFormInfo.dimension));
493 napi_set_named_property(env, result, "formUsageState", CreateJsValue(env, runningFormInfo.formUsageState));
494 napi_set_named_property(env, result, "formDescription", CreateJsValue(env, runningFormInfo.description));
495 napi_set_named_property(env, result, "formLocation", CreateJsValue(env, (int32_t)runningFormInfo.formLocation));
496 }
497
GetFormType(const FormInfo & formInfo)498 inline FormType GetFormType(const FormInfo &formInfo)
499 {
500 if (formInfo.uiSyntax == FormType::ETS) {
501 return FormType::ETS;
502 }
503 return formInfo.type;
504 }
505
CreateFormInfos(napi_env env,const std::vector<FormInfo> & formInfos)506 napi_value CreateFormInfos(napi_env env, const std::vector<FormInfo> &formInfos)
507 {
508 napi_value arrayValue = nullptr;
509 napi_create_array_with_length(env, formInfos.size(), &arrayValue);
510 uint32_t index = 0;
511 for (const auto &formInfo : formInfos) {
512 napi_set_element(env, arrayValue, index++, CreateFormInfo(env, formInfo));
513 }
514 return arrayValue;
515 }
516
CreateFormInfo(napi_env env,const FormInfo & formInfo)517 napi_value CreateFormInfo(napi_env env, const FormInfo &formInfo)
518 {
519 HILOG_DEBUG("call");
520
521 napi_value objContext = nullptr;
522 napi_create_object(env, &objContext);
523
524 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, formInfo.bundleName));
525 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, formInfo.moduleName));
526 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, formInfo.abilityName));
527 napi_set_named_property(env, objContext, "name", CreateJsValue(env, formInfo.name));
528 napi_set_named_property(env, objContext, "displayName", CreateJsValue(env, formInfo.displayName));
529 napi_set_named_property(env, objContext, "displayNameId", CreateJsValue(env, formInfo.displayNameId));
530 napi_set_named_property(env, objContext, "description", CreateJsValue(env, formInfo.description));
531 napi_set_named_property(env, objContext, "descriptionId", CreateJsValue(env, formInfo.descriptionId));
532 napi_set_named_property(env, objContext, "type", CreateJsValue(env, GetFormType(formInfo)));
533 napi_set_named_property(env, objContext, "jsComponentName", CreateJsValue(env, formInfo.jsComponentName));
534 napi_set_named_property(env, objContext, "colorMode", CreateJsValue(env, formInfo.colorMode));
535 napi_set_named_property(env, objContext, "isDefault", CreateJsValue(env, formInfo.defaultFlag));
536 napi_set_named_property(env, objContext, "updateEnabled", CreateJsValue(env, formInfo.updateEnabled));
537 napi_set_named_property(env, objContext, "formVisibleNotify", CreateJsValue(env, formInfo.formVisibleNotify));
538 napi_set_named_property(env, objContext, "formConfigAbility", CreateJsValue(env, formInfo.formConfigAbility));
539 napi_set_named_property(env, objContext, "updateDuration", CreateJsValue(env, formInfo.updateDuration));
540 napi_set_named_property(env, objContext, "scheduledUpdateTime", CreateJsValue(env, formInfo.scheduledUpdateTime));
541 napi_set_named_property(env, objContext, "defaultDimension", CreateJsValue(env, formInfo.defaultDimension));
542 napi_set_named_property(env, objContext, "relatedBundleName", CreateJsValue(env, formInfo.relatedBundleName));
543 napi_set_named_property(env, objContext, "supportDimensions", CreateNativeArray(env, formInfo.supportDimensions));
544 napi_set_named_property(env, objContext, "customizeData", CreateFormCustomizeDatas(env, formInfo.customizeDatas));
545 napi_set_named_property(env, objContext, "isDynamic", CreateJsValue(env, formInfo.isDynamic));
546 napi_set_named_property(env, objContext, "transparencyEnabled", CreateJsValue(env, formInfo.transparencyEnabled));
547 napi_set_named_property(env, objContext, "fontScaleFollowSystem",
548 CreateJsValue(env, formInfo.fontScaleFollowSystem));
549 napi_set_named_property(env, objContext, "supportedShapes", CreateNativeArray(env, formInfo.supportShapes));
550 napi_set_named_property(env, objContext, "previewImages", CreateNativeArray(env, formInfo.formPreviewImages));
551 napi_set_named_property(env, objContext, "renderingMode", CreateJsValue(env, formInfo.renderingMode));
552 napi_set_named_property(env, objContext, "enableBlurBackground", CreateJsValue(env, formInfo.enableBlurBackground));
553 napi_set_named_property(env, objContext, "funInteractionParams",
554 CreateFunInteractionParamsDatas(env, formInfo.funInteractionParams));
555 napi_set_named_property(env, objContext, "sceneAnimationParams",
556 CreateSceneAnimationParamsDatas(env, formInfo.sceneAnimationParams));
557 napi_set_named_property(env, objContext, "resizable", CreateJsValue(env, formInfo.resizable));
558 napi_set_named_property(env, objContext, "groupId", CreateJsValue(env, formInfo.groupId));
559
560 return objContext;
561 }
562
CreateRunningFormInfos(napi_env env,const std::vector<RunningFormInfo> & runningFormInfos)563 napi_value CreateRunningFormInfos(napi_env env, const std::vector<RunningFormInfo> &runningFormInfos)
564 {
565 napi_value arrayValue = nullptr;
566 napi_create_array_with_length(env, runningFormInfos.size(), &arrayValue);
567 uint32_t index = 0;
568 for (const auto &runningFormInfo : runningFormInfos) {
569 napi_set_element(env, arrayValue, index++, CreateRunningFormInfo(env, runningFormInfo));
570 }
571 return arrayValue;
572 }
573
CreateRunningFormInfo(napi_env env,const RunningFormInfo & runningFormInfo)574 napi_value CreateRunningFormInfo(napi_env env, const RunningFormInfo &runningFormInfo)
575 {
576 HILOG_DEBUG("call");
577
578 napi_value objContext = nullptr;
579 napi_create_object(env, &objContext);
580
581 std::string formStr = std::to_string(runningFormInfo.formId);
582 napi_set_named_property(env, objContext, "formId", CreateJsValue(env, formStr));
583 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
584 napi_set_named_property(env, objContext, "hostBundleName", CreateJsValue(env, runningFormInfo.hostBundleName));
585 napi_set_named_property(env, objContext, "visibilityType", CreateJsValue(env, runningFormInfo.formVisiblity));
586 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, runningFormInfo.moduleName));
587 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, runningFormInfo.abilityName));
588 napi_set_named_property(env, objContext, "formName", CreateJsValue(env, runningFormInfo.formName));
589 napi_set_named_property(env, objContext, "dimension", CreateJsValue(env, runningFormInfo.dimension));
590 napi_set_named_property(env, objContext, "formUsageState", CreateJsValue(env, runningFormInfo.formUsageState));
591 napi_set_named_property(env, objContext, "formDescription", CreateJsValue(env, runningFormInfo.description));
592 napi_set_named_property(env, objContext, "formLocation", CreateJsValue(env, (int32_t)runningFormInfo.formLocation));
593
594 return objContext;
595 }
596
CreateNewRunningFormInfos(napi_env env,const std::vector<RunningFormInfo> & runningFormInfos)597 napi_value CreateNewRunningFormInfos(napi_env env, const std::vector<RunningFormInfo> &runningFormInfos)
598 {
599 napi_value arrayValue = nullptr;
600 napi_create_array_with_length(env, runningFormInfos.size(), &arrayValue);
601 uint32_t index = 0;
602 for (const auto &runningFormInfo : runningFormInfos) {
603 napi_set_element(env, arrayValue, index++, CreateNewRunningFormInfo(env, runningFormInfo));
604 }
605 return arrayValue;
606 }
607
CreateNewRunningFormInfo(napi_env env,const RunningFormInfo & runningFormInfo)608 napi_value CreateNewRunningFormInfo(napi_env env, const RunningFormInfo &runningFormInfo)
609 {
610 HILOG_DEBUG("call");
611
612 napi_value objContext = nullptr;
613 napi_create_object(env, &objContext);
614
615 std::string formStr = std::to_string(runningFormInfo.formId);
616 napi_set_named_property(env, objContext, "formId", CreateJsValue(env, formStr));
617 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
618 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, runningFormInfo.moduleName));
619 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, runningFormInfo.abilityName));
620 napi_set_named_property(env, objContext, "formName", CreateJsValue(env, runningFormInfo.formName));
621 napi_set_named_property(env, objContext, "dimension", CreateJsValue(env, runningFormInfo.dimension));
622 napi_set_named_property(env, objContext, "formLocation", CreateJsValue(env, (int32_t)runningFormInfo.formLocation));
623
624 return objContext;
625 }
626
CreateFormCustomizeDatas(napi_env env,const std::vector<FormCustomizeData> & customizeDatas)627 napi_value CreateFormCustomizeDatas(napi_env env, const std::vector<FormCustomizeData> &customizeDatas)
628 {
629 napi_value objContext = nullptr;
630 napi_create_object(env, &objContext);
631
632 for (const auto& data : customizeDatas) {
633 napi_set_named_property(env, objContext, data.name.c_str(), CreateJsValue(env, data.value));
634 }
635
636 return objContext;
637 }
638
CreateFunInteractionParamsDatas(napi_env env,const FormFunInteractionParams & funInteractionParamsDatas)639 napi_value CreateFunInteractionParamsDatas(napi_env env, const FormFunInteractionParams &funInteractionParamsDatas)
640 {
641 napi_value objContext = nullptr;
642 napi_create_object(env, &objContext);
643 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, funInteractionParamsDatas.abilityName));
644 napi_set_named_property(env, objContext, "targetBundleName",
645 CreateJsValue(env, funInteractionParamsDatas.targetBundleName));
646 napi_set_named_property(env, objContext, "subBundleName",
647 CreateJsValue(env, funInteractionParamsDatas.subBundleName));
648 napi_set_named_property(env, objContext, "keepStateDuration",
649 CreateJsValue(env, funInteractionParamsDatas.keepStateDuration));
650 return objContext;
651 }
652
CreateSceneAnimationParamsDatas(napi_env env,const FormSceneAnimationParams & sceneAnimationParamsDatas)653 napi_value CreateSceneAnimationParamsDatas(napi_env env, const FormSceneAnimationParams &sceneAnimationParamsDatas)
654 {
655 napi_value objContext = nullptr;
656 napi_create_object(env, &objContext);
657 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, sceneAnimationParamsDatas.abilityName));
658 napi_set_named_property(env, objContext, "disabledDesktopBehaviors",
659 CreateJsValue(env, sceneAnimationParamsDatas.disabledDesktopBehaviors));
660 return objContext;
661 }
662
ParseParam(napi_env env,napi_value args,FormInstancesFilter & filter)663 bool ParseParam(napi_env env, napi_value args, FormInstancesFilter &filter)
664 {
665 napi_valuetype valueType;
666 NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
667 if (valueType != napi_object) {
668 HILOG_ERROR("args not object type");
669 return false;
670 }
671 napi_value prop = nullptr;
672 napi_get_named_property(env, args, "bundleName", &prop);
673 napi_typeof(env, prop, &valueType);
674 if (valueType != napi_string) {
675 HILOG_ERROR("input bundleName not string");
676 return false;
677 }
678 filter.bundleName = GetStringFromNapi(env, prop);
679 if (filter.bundleName.empty()) {
680 HILOG_ERROR("empty inputBundleName");
681 return false;
682 }
683 prop = nullptr;
684 napi_get_named_property(env, args, "formName", &prop);
685 filter.formName = GetStringFromNapi(env, prop);
686 prop = nullptr;
687 napi_get_named_property(env, args, "moduleName", &prop);
688 filter.moduleName = GetStringFromNapi(env, prop);
689 prop = nullptr;
690 napi_get_named_property(env, args, "abilityName", &prop);
691 filter.abilityName = GetStringFromNapi(env, prop);
692 bool hasIsUnusedIncluded = false;
693 napi_has_named_property(env, args, "isUnusedIncluded", &hasIsUnusedIncluded);
694 if (hasIsUnusedIncluded) {
695 prop = nullptr;
696 napi_get_named_property(env, args, "isUnusedIncluded", &prop);
697 if (napi_get_value_bool(env, prop, &filter.isUnusedIncluded) != napi_ok) {
698 return false;
699 }
700 }
701 return true;
702 }
703
GetStringFromNapi(napi_env env,napi_value value)704 std::string GetStringFromNapi(napi_env env, napi_value value)
705 {
706 std::string result;
707 size_t size = 0;
708
709 if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok) {
710 HILOG_ERROR("can't get stringSize");
711 return "";
712 }
713 result.reserve(size + 1);
714 result.resize(size);
715 if (napi_get_value_string_utf8(env, value, result.data(), (size + 1), &size) != napi_ok) {
716 HILOG_ERROR("can't get string value");
717 return "";
718 }
719 return result;
720 }
721
CreateFormInstances(napi_env env,const std::vector<FormInstance> & formInstances)722 napi_value CreateFormInstances(napi_env env, const std::vector<FormInstance> &formInstances)
723 {
724 napi_value arrayValue = nullptr;
725 napi_create_array_with_length(env, formInstances.size(), &arrayValue);
726 uint32_t index = 0;
727 for (const auto &formInstance : formInstances) {
728 napi_set_element(env, arrayValue, index++, CreateFormInstance(env, formInstance));
729 }
730 return arrayValue;
731 }
732
CreateFormInstance(napi_env env,const FormInstance & formInstance)733 napi_value CreateFormInstance(napi_env env, const FormInstance &formInstance)
734 {
735 HILOG_DEBUG("call");
736
737 napi_value objContext = nullptr;
738 napi_create_object(env, &objContext);
739
740 std::string formStr = std::to_string(formInstance.formId);
741 napi_set_named_property(env, objContext, "formId", CreateJsValue(env, formStr));
742 napi_set_named_property(env, objContext, "hostBundleName", CreateJsValue(env, formInstance.formHostName));
743 napi_set_named_property(env, objContext, "visibilityType", CreateJsValue(env, formInstance.formVisiblity));
744 napi_set_named_property(env, objContext, "dimension", CreateJsValue(env, formInstance.specification));
745 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, formInstance.bundleName));
746 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, formInstance.moduleName));
747 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, formInstance.abilityName));
748 napi_set_named_property(env, objContext, "formName", CreateJsValue(env, formInstance.formName));
749 napi_set_named_property(env, objContext, "formUsageState", CreateJsValue(env, formInstance.formUsageState));
750 napi_set_named_property(env, objContext, "formDescription", CreateJsValue(env, formInstance.description));
751 return objContext;
752 }
753
ConvertFormInfoFilter(napi_env env,napi_value value,AppExecFwk::FormInfoFilter & formInfoFilter)754 bool ConvertFormInfoFilter(napi_env env, napi_value value, AppExecFwk::FormInfoFilter &formInfoFilter)
755 {
756 napi_valuetype type = napi_undefined;
757 napi_typeof(env, value, &type);
758 if (type != napi_object) {
759 HILOG_ERROR("type not napi_object");
760 return false;
761 }
762
763 napi_value nativeDataValue = nullptr;
764 napi_get_named_property(env, value, "moduleName", &nativeDataValue);
765 napi_valuetype nativeDataValueType = napi_undefined;
766 napi_typeof(env, nativeDataValue, &nativeDataValueType);
767 if (nativeDataValue == nullptr || (nativeDataValueType != napi_undefined &&
768 !ConvertFromJsValue(env, nativeDataValue, formInfoFilter.moduleName))) {
769 HILOG_ERROR("convert nativeDataValue failed");
770 return false;
771 }
772 HILOG_INFO("module:%{public}s", formInfoFilter.moduleName.c_str());
773
774 return true;
775 }
776
ConvertStringToInt(const std::string & strInfo,int radix)777 int NapiFormUtil::ConvertStringToInt(const std::string &strInfo, int radix)
778 {
779 return static_cast<int>(strtol(strInfo.c_str(), nullptr, radix));
780 }
781
ConvertStringToLongLong(const std::string & strInfo,int radix)782 long long NapiFormUtil::ConvertStringToLongLong(const std::string &strInfo, int radix)
783 {
784 return static_cast<long long>(strtoll(strInfo.c_str(), nullptr, radix));
785 }
786
GetPropertyValueByPropertyName(napi_env env,napi_value value,const char * propertyName,double & result)787 bool GetPropertyValueByPropertyName(napi_env env, napi_value value, const char *propertyName, double &result)
788 {
789 napi_value propertyValue;
790 napi_status status = napi_get_named_property(env, value, propertyName, &propertyValue);
791 if (status != napi_ok) {
792 HILOG_ERROR("GetPropertyValueByPropertyName, get property value fail, propertyName:%{public}s",
793 propertyName);
794 return false;
795 }
796 if (!ConvertFromJsValue(env, propertyValue, result)) {
797 HILOG_ERROR("GetPropertyValueByPropertyName, convertFromJsValue property fail, propertyName:%{public}s",
798 propertyName);
799 return false;
800 }
801 return true;
802 }
803
CreateFormRectInfo(napi_env env,napi_value value,AppExecFwk::Rect & rect)804 bool CreateFormRectInfo(napi_env env, napi_value value, AppExecFwk::Rect &rect)
805 {
806 double rectLeft;
807 if (!GetPropertyValueByPropertyName(env, value, "left", rectLeft)) {
808 return false;
809 }
810 double rectTop;
811 if (!GetPropertyValueByPropertyName(env, value, "top", rectTop)) {
812 return false;
813 }
814 double rectWidth;
815 if (!GetPropertyValueByPropertyName(env, value, "width", rectWidth)) {
816 return false;
817 }
818 double rectHeight;
819 if (!GetPropertyValueByPropertyName(env, value, "height", rectHeight)) {
820 return false;
821 }
822 rect.left = rectLeft;
823 rect.top = rectTop;
824 rect.width = rectWidth;
825 rect.height = rectHeight;
826 return true;
827 }
828 } // namespace AbilityRuntime
829 } // namespace OHOS
830