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 = std::stoll(strInfo);
258 return true;
259 }
260 int maxSubValue = std::stoi(strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1));
261 if (strLength == INT_64_LENGTH && maxSubValue < BASE_NUMBER) {
262 int64Value = std::stoll(strInfo);
263 return true;
264 }
265 // Means 0x7FFFFFFFFFFFFFFF remove the first number:(2^63 - 1 - 9 * 10 ^ 19)
266 int64_t subValue = std::stoll(strInfo.substr(ZERO_VALUE + 1, INT_64_LENGTH - 1));
267 if (strLength == INT_64_LENGTH && subValue <= (INT64_MAX - HEAD_BIT_NUM)) {
268 int64Value = std::stoll(strInfo);
269 return true;
270 }
271 return false;
272 }
273 if (strLength < INT_64_LENGTH + 1) { // The minimum value: -9223372036854775808
274 int64Value = std::stoll(strInfo);
275 return true;
276 }
277 if (strLength == INT_64_LENGTH + 1) {
278 int minSubValue = std::stoi(strInfo.substr(1, 1));
279 if (minSubValue < BASE_NUMBER) {
280 int64Value = std::stoll(strInfo);
281 return true;
282 }
283
284 // Means 0x8000000000000000 remove the first number:-(2^63 - 9 * 10 ^ 19)
285 int64_t subValue = std::stoll(strInfo.substr(ZERO_VALUE + 2, INT_64_LENGTH - 1));
286 if (subValue <= (INT64_MAX - HEAD_BIT_NUM + 1)) {
287 int64Value = std::stoll(strInfo);
288 return true;
289 }
290 }
291 }
292 HILOG_DEBUG("regex_match failed");
293 return false;
294 }
295
296 /**
297 * @brief Create return message(callback)
298 *
299 * @param[in] env The environment that the Node-API call is invoked under
300 * @param[in] code result code
301 * @param[out] result result message
302 *
303 * @return void
304 */
InnerCreateCallbackRetMsg(napi_env env,int32_t code,napi_value (& result)[CALLBACK_RETURN_MSG_SIZE])305 void InnerCreateCallbackRetMsg(napi_env env, int32_t code, napi_value (&result)[CALLBACK_RETURN_MSG_SIZE])
306 {
307 HILOG_DEBUG("code:%{public}d", code);
308 napi_value error = nullptr;
309 napi_create_object(env, &error);
310
311 auto retCode = QueryRetCode(code);
312 auto retMsg = QueryRetMsg(retCode);
313
314 // create error code
315 napi_value errCode = nullptr;
316 napi_create_int32(env, retCode, &errCode);
317 napi_set_named_property(env, error, "code", errCode);
318
319 // create error message
320 napi_value errMsg = nullptr;
321 napi_create_string_utf8(env, retMsg.c_str(), NAPI_AUTO_LENGTH, &errMsg);
322 napi_set_named_property(env, error, "message", errMsg);
323
324 result[0] = error;
325 napi_get_undefined(env, &result[1]);
326 HILOG_DEBUG("end");
327 }
328
329 /**
330 * @brief Create return message(promise)
331 *
332 * @param[in] env The environment that the Node-API call is invoked under
333 * @param[in] code result code
334 * @param[out] result result message
335 *
336 * @return void
337 */
InnerCreatePromiseRetMsg(napi_env env,int32_t code,napi_value * result)338 void InnerCreatePromiseRetMsg(napi_env env, int32_t code, napi_value* result)
339 {
340 HILOG_DEBUG("code:%{public}d", code);
341 if (code == ERR_OK) {
342 napi_get_undefined(env, result);
343 return;
344 }
345 napi_value errInfo = nullptr;
346 napi_create_object(env, &errInfo);
347
348 auto retCode = QueryRetCode(code);
349 auto retMsg = QueryRetMsg(retCode);
350
351 // create error code
352 napi_value errCode = nullptr;
353 napi_create_int32(env, retCode, &errCode);
354 napi_set_named_property(env, errInfo, "code", errCode);
355
356 // create error message
357 napi_value errMsg = nullptr;
358 napi_create_string_utf8(env, retMsg.c_str(), NAPI_AUTO_LENGTH, &errMsg);
359 napi_set_named_property(env, errInfo, "message", errMsg);
360
361 *result = errInfo;
362 HILOG_DEBUG("end");
363 }
364
RetErrMsgForCallback(AsyncErrMsgCallbackInfo * asyncCallbackInfo)365 napi_value RetErrMsgForCallback(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
366 {
367 HILOG_INFO("call");
368
369 napi_env env = asyncCallbackInfo->env;
370 napi_value value = asyncCallbackInfo->callbackValue;
371
372 // Check the value type of the arguments
373 napi_valuetype valueType = napi_undefined;
374 NAPI_CALL(env, napi_typeof(env, value, &valueType));
375 NAPI_ASSERT(env, valueType == napi_function, "The arguments[1] type of deleteForm is incorrect,\
376 expected type is function.");
377
378 napi_create_reference(env, value, REF_COUNT, &asyncCallbackInfo->callback);
379
380 napi_value resourceName;
381 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
382 napi_create_async_work(
383 env,
384 nullptr,
385 resourceName,
386 [](napi_env env, void *data) {},
387 [](napi_env env, napi_status status, void *data) {
388 AsyncErrMsgCallbackInfo *asyncCallbackInfo = (AsyncErrMsgCallbackInfo *)data;
389 HILOG_INFO("complete");
390 if (asyncCallbackInfo->callback != nullptr) {
391 napi_value callback;
392 napi_value undefined;
393 napi_value result[ARGS_SIZE_TWO] = {0};
394 InnerCreateCallbackRetMsg(env, asyncCallbackInfo->code, result);
395 napi_get_undefined(env, &undefined);
396 napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
397 napi_value callResult;
398 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
399 napi_delete_reference(env, asyncCallbackInfo->callback);
400 }
401 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
402 delete asyncCallbackInfo;
403 },
404 (void *)asyncCallbackInfo,
405 &asyncCallbackInfo->asyncWork);
406 NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default));
407 return NapiGetResult(env, 1);
408 }
409
RetErrMsgForPromise(AsyncErrMsgCallbackInfo * asyncCallbackInfo)410 napi_value RetErrMsgForPromise(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
411 {
412 HILOG_INFO("call");
413
414 napi_env env = asyncCallbackInfo->env;
415 napi_deferred deferred;
416 napi_value promise;
417 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
418 asyncCallbackInfo->deferred = deferred;
419
420 napi_value resourceName;
421 napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
422 napi_create_async_work(
423 env,
424 nullptr,
425 resourceName,
426 [](napi_env env, void *data) {},
427 [](napi_env env, napi_status status, void *data) {
428 HILOG_INFO("promise complete");
429 AsyncErrMsgCallbackInfo *asyncCallbackInfo = (AsyncErrMsgCallbackInfo *)data;
430 napi_value result;
431 InnerCreatePromiseRetMsg(env, asyncCallbackInfo->code, &result);
432 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
433 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
434 delete asyncCallbackInfo;
435 },
436 (void *)asyncCallbackInfo,
437 &asyncCallbackInfo->asyncWork);
438 napi_queue_async_work_with_qos(env, asyncCallbackInfo->asyncWork, napi_qos_default);
439 return promise;
440 }
441
442 /**
443 * @brief Send error message.
444 *
445 * @param[in] env The environment that the Node-API call is invoked under
446 * @param[in] asyncCallbackInfo Reference, callback info via Node-API
447 * @param[out] result result message
448 *
449 * @return void
450 */
RetErrMsg(AsyncErrMsgCallbackInfo * asyncCallbackInfo)451 napi_value RetErrMsg(AsyncErrMsgCallbackInfo* asyncCallbackInfo)
452 {
453 HILOG_INFO("call");
454 if (asyncCallbackInfo == nullptr) {
455 HILOG_ERROR("null asyncCallback");
456 return nullptr;
457 }
458 if (asyncCallbackInfo->type == CALLBACK_FLG) {
459 return RetErrMsgForCallback(asyncCallbackInfo);
460 }
461 return RetErrMsgForPromise(asyncCallbackInfo);
462 }
463
InitErrMsg(napi_env env,int32_t code,int32_t type,napi_value callbackValue)464 AsyncErrMsgCallbackInfo *InitErrMsg(napi_env env, int32_t code, int32_t type, napi_value callbackValue)
465 {
466 auto *asyncErrorInfo = new (std::nothrow) AsyncErrMsgCallbackInfo {
467 .env = env,
468 .asyncWork = nullptr,
469 .deferred = nullptr,
470 .callback = nullptr,
471 .callbackValue = callbackValue,
472 .code = code,
473 .type = type
474 };
475 return asyncErrorInfo;
476 }
477
ParseRunningFormInfoIntoNapi(napi_env env,const RunningFormInfo & runningFormInfo,napi_value & result)478 void ParseRunningFormInfoIntoNapi(napi_env env, const RunningFormInfo &runningFormInfo, napi_value &result)
479 {
480 napi_create_object(env, &result);
481
482 napi_set_named_property(env, result, "formId", CreateJsValue(env, std::to_string(runningFormInfo.formId)));
483 napi_set_named_property(env, result, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
484 napi_set_named_property(env, result, "hostBundleName", CreateJsValue(env, runningFormInfo.hostBundleName));
485 napi_set_named_property(env, result, "visibilityType", CreateJsValue(env, (int32_t)runningFormInfo.formVisiblity));
486 napi_set_named_property(env, result, "moduleName", CreateJsValue(env, runningFormInfo.moduleName));
487 napi_set_named_property(env, result, "abilityName", CreateJsValue(env, runningFormInfo.abilityName));
488 napi_set_named_property(env, result, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
489 napi_set_named_property(env, result, "formName", CreateJsValue(env, runningFormInfo.formName));
490 napi_set_named_property(env, result, "dimension", CreateJsValue(env, runningFormInfo.dimension));
491 napi_set_named_property(env, result, "formUsageState", CreateJsValue(env, runningFormInfo.formUsageState));
492 napi_set_named_property(env, result, "formDescription", CreateJsValue(env, runningFormInfo.description));
493 napi_set_named_property(env, result, "formLocation", CreateJsValue(env, (int32_t)runningFormInfo.formLocation));
494 }
495
GetFormType(const FormInfo & formInfo)496 inline FormType GetFormType(const FormInfo &formInfo)
497 {
498 if (formInfo.uiSyntax == FormType::ETS) {
499 return FormType::ETS;
500 }
501 return formInfo.type;
502 }
503
CreateFormInfos(napi_env env,const std::vector<FormInfo> & formInfos)504 napi_value CreateFormInfos(napi_env env, const std::vector<FormInfo> &formInfos)
505 {
506 napi_value arrayValue = nullptr;
507 napi_create_array_with_length(env, formInfos.size(), &arrayValue);
508 uint32_t index = 0;
509 for (const auto &formInfo : formInfos) {
510 napi_set_element(env, arrayValue, index++, CreateFormInfo(env, formInfo));
511 }
512 return arrayValue;
513 }
514
CreateFormInfo(napi_env env,const FormInfo & formInfo)515 napi_value CreateFormInfo(napi_env env, const FormInfo &formInfo)
516 {
517 HILOG_DEBUG("call");
518
519 napi_value objContext = nullptr;
520 napi_create_object(env, &objContext);
521
522 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, formInfo.bundleName));
523 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, formInfo.moduleName));
524 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, formInfo.abilityName));
525 napi_set_named_property(env, objContext, "name", CreateJsValue(env, formInfo.name));
526 napi_set_named_property(env, objContext, "displayName", CreateJsValue(env, formInfo.displayName));
527 napi_set_named_property(env, objContext, "displayNameId", CreateJsValue(env, formInfo.displayNameId));
528 napi_set_named_property(env, objContext, "description", CreateJsValue(env, formInfo.description));
529 napi_set_named_property(env, objContext, "descriptionId", CreateJsValue(env, formInfo.descriptionId));
530 napi_set_named_property(env, objContext, "type", CreateJsValue(env, GetFormType(formInfo)));
531 napi_set_named_property(env, objContext, "jsComponentName", CreateJsValue(env, formInfo.jsComponentName));
532 napi_set_named_property(env, objContext, "colorMode", CreateJsValue(env, formInfo.colorMode));
533 napi_set_named_property(env, objContext, "isDefault", CreateJsValue(env, formInfo.defaultFlag));
534 napi_set_named_property(env, objContext, "updateEnabled", CreateJsValue(env, formInfo.updateEnabled));
535 napi_set_named_property(env, objContext, "formVisibleNotify", CreateJsValue(env, formInfo.formVisibleNotify));
536 napi_set_named_property(env, objContext, "formConfigAbility", CreateJsValue(env, formInfo.formConfigAbility));
537 napi_set_named_property(env, objContext, "updateDuration", CreateJsValue(env, formInfo.updateDuration));
538 napi_set_named_property(env, objContext, "scheduledUpdateTime", CreateJsValue(env, formInfo.scheduledUpdateTime));
539 napi_set_named_property(env, objContext, "defaultDimension", CreateJsValue(env, formInfo.defaultDimension));
540 napi_set_named_property(env, objContext, "relatedBundleName", CreateJsValue(env, formInfo.relatedBundleName));
541 napi_set_named_property(env, objContext, "supportDimensions", CreateNativeArray(env, formInfo.supportDimensions));
542 napi_set_named_property(env, objContext, "customizeData", CreateFormCustomizeDatas(env, formInfo.customizeDatas));
543 napi_set_named_property(env, objContext, "isDynamic", CreateJsValue(env, formInfo.isDynamic));
544 napi_set_named_property(env, objContext, "transparencyEnabled", CreateJsValue(env, formInfo.transparencyEnabled));
545 napi_set_named_property(env, objContext, "fontScaleFollowSystem",
546 CreateJsValue(env, formInfo.fontScaleFollowSystem));
547 napi_set_named_property(env, objContext, "supportedShapes", CreateNativeArray(env, formInfo.supportShapes));
548
549 return objContext;
550 }
551
CreateRunningFormInfos(napi_env env,const std::vector<RunningFormInfo> & runningFormInfos)552 napi_value CreateRunningFormInfos(napi_env env, const std::vector<RunningFormInfo> &runningFormInfos)
553 {
554 napi_value arrayValue = nullptr;
555 napi_create_array_with_length(env, runningFormInfos.size(), &arrayValue);
556 uint32_t index = 0;
557 for (const auto &runningFormInfo : runningFormInfos) {
558 napi_set_element(env, arrayValue, index++, CreateRunningFormInfo(env, runningFormInfo));
559 }
560 return arrayValue;
561 }
562
CreateRunningFormInfo(napi_env env,const RunningFormInfo & runningFormInfo)563 napi_value CreateRunningFormInfo(napi_env env, const RunningFormInfo &runningFormInfo)
564 {
565 HILOG_DEBUG("call");
566
567 napi_value objContext = nullptr;
568 napi_create_object(env, &objContext);
569
570 std::string formStr = std::to_string(runningFormInfo.formId);
571 napi_set_named_property(env, objContext, "formId", CreateJsValue(env, formStr));
572 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, runningFormInfo.bundleName));
573 napi_set_named_property(env, objContext, "hostBundleName", CreateJsValue(env, runningFormInfo.hostBundleName));
574 napi_set_named_property(env, objContext, "visibilityType", CreateJsValue(env, runningFormInfo.formVisiblity));
575 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, runningFormInfo.moduleName));
576 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, runningFormInfo.abilityName));
577 napi_set_named_property(env, objContext, "formName", CreateJsValue(env, runningFormInfo.formName));
578 napi_set_named_property(env, objContext, "dimension", CreateJsValue(env, runningFormInfo.dimension));
579 napi_set_named_property(env, objContext, "formUsageState", CreateJsValue(env, runningFormInfo.formUsageState));
580 napi_set_named_property(env, objContext, "formDescription", CreateJsValue(env, runningFormInfo.description));
581 napi_set_named_property(env, objContext, "formLocation", CreateJsValue(env, (int32_t)runningFormInfo.formLocation));
582
583 return objContext;
584 }
585
CreateFormCustomizeDatas(napi_env env,const std::vector<FormCustomizeData> & customizeDatas)586 napi_value CreateFormCustomizeDatas(napi_env env, const std::vector<FormCustomizeData> &customizeDatas)
587 {
588 napi_value objContext = nullptr;
589 napi_create_object(env, &objContext);
590
591 for (const auto& data : customizeDatas) {
592 napi_set_named_property(env, objContext, data.name.c_str(), CreateJsValue(env, data.value));
593 }
594
595 return objContext;
596 }
597
ParseParam(napi_env env,napi_value args,FormInstancesFilter & filter)598 bool ParseParam(napi_env env, napi_value args, FormInstancesFilter &filter)
599 {
600 napi_valuetype valueType;
601 NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
602 if (valueType != napi_object) {
603 HILOG_ERROR("args not object type");
604 return false;
605 }
606 napi_value prop = nullptr;
607 napi_get_named_property(env, args, "bundleName", &prop);
608 napi_typeof(env, prop, &valueType);
609 if (valueType != napi_string) {
610 HILOG_ERROR("input bundleName not string");
611 return false;
612 }
613 filter.bundleName = GetStringFromNapi(env, prop);
614 if (filter.bundleName.empty()) {
615 HILOG_ERROR("empty inputBundleName");
616 return false;
617 }
618 prop = nullptr;
619 napi_get_named_property(env, args, "formName", &prop);
620 filter.formName = GetStringFromNapi(env, prop);
621 prop = nullptr;
622 napi_get_named_property(env, args, "moduleName", &prop);
623 filter.moduleName = GetStringFromNapi(env, prop);
624 prop = nullptr;
625 napi_get_named_property(env, args, "abilityName", &prop);
626 filter.abilityName = GetStringFromNapi(env, prop);
627 bool hasIsUnusedIncluded = false;
628 napi_has_named_property(env, args, "isUnusedIncluded", &hasIsUnusedIncluded);
629 if (hasIsUnusedIncluded) {
630 prop = nullptr;
631 napi_get_named_property(env, args, "isUnusedIncluded", &prop);
632 if (napi_get_value_bool(env, prop, &filter.isUnusedIncluded) != napi_ok) {
633 return false;
634 }
635 }
636 return true;
637 }
638
GetStringFromNapi(napi_env env,napi_value value)639 std::string GetStringFromNapi(napi_env env, napi_value value)
640 {
641 std::string result;
642 size_t size = 0;
643
644 if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok) {
645 HILOG_ERROR("can't get stringSize");
646 return "";
647 }
648 result.reserve(size + 1);
649 result.resize(size);
650 if (napi_get_value_string_utf8(env, value, result.data(), (size + 1), &size) != napi_ok) {
651 HILOG_ERROR("can't get string value");
652 return "";
653 }
654 return result;
655 }
656
CreateFormInstances(napi_env env,const std::vector<FormInstance> & formInstances)657 napi_value CreateFormInstances(napi_env env, const std::vector<FormInstance> &formInstances)
658 {
659 napi_value arrayValue = nullptr;
660 napi_create_array_with_length(env, formInstances.size(), &arrayValue);
661 uint32_t index = 0;
662 for (const auto &formInstance : formInstances) {
663 napi_set_element(env, arrayValue, index++, CreateFormInstance(env, formInstance));
664 }
665 return arrayValue;
666 }
667
CreateFormInstance(napi_env env,const FormInstance & formInstance)668 napi_value CreateFormInstance(napi_env env, const FormInstance &formInstance)
669 {
670 HILOG_DEBUG("call");
671
672 napi_value objContext = nullptr;
673 napi_create_object(env, &objContext);
674
675 std::string formStr = std::to_string(formInstance.formId);
676 napi_set_named_property(env, objContext, "formId", CreateJsValue(env, formStr));
677 napi_set_named_property(env, objContext, "hostBundleName", CreateJsValue(env, formInstance.formHostName));
678 napi_set_named_property(env, objContext, "visibilityType", CreateJsValue(env, formInstance.formVisiblity));
679 napi_set_named_property(env, objContext, "dimension", CreateJsValue(env, formInstance.specification));
680 napi_set_named_property(env, objContext, "bundleName", CreateJsValue(env, formInstance.bundleName));
681 napi_set_named_property(env, objContext, "moduleName", CreateJsValue(env, formInstance.moduleName));
682 napi_set_named_property(env, objContext, "abilityName", CreateJsValue(env, formInstance.abilityName));
683 napi_set_named_property(env, objContext, "formName", CreateJsValue(env, formInstance.formName));
684 napi_set_named_property(env, objContext, "formUsageState", CreateJsValue(env, formInstance.formUsageState));
685 napi_set_named_property(env, objContext, "formDescription", CreateJsValue(env, formInstance.description));
686 return objContext;
687 }
688
ConvertFormInfoFilter(napi_env env,napi_value value,AppExecFwk::FormInfoFilter & formInfoFilter)689 bool ConvertFormInfoFilter(napi_env env, napi_value value, AppExecFwk::FormInfoFilter &formInfoFilter)
690 {
691 napi_valuetype type = napi_undefined;
692 napi_typeof(env, value, &type);
693 if (type != napi_object) {
694 HILOG_ERROR("type not napi_object");
695 return false;
696 }
697
698 napi_value nativeDataValue = nullptr;
699 napi_get_named_property(env, value, "moduleName", &nativeDataValue);
700 napi_valuetype nativeDataValueType = napi_undefined;
701 napi_typeof(env, nativeDataValue, &nativeDataValueType);
702 if (nativeDataValue == nullptr || (nativeDataValueType != napi_undefined &&
703 !ConvertFromJsValue(env, nativeDataValue, formInfoFilter.moduleName))) {
704 HILOG_ERROR("convert nativeDataValue failed");
705 return false;
706 }
707 HILOG_INFO("module:%{public}s", formInfoFilter.moduleName.c_str());
708
709 return true;
710 }
711 } // namespace AbilityRuntime
712 } // namespace OHOS
713