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_utils.h"
17
18 #include "js_util.h"
19
20 namespace OHOS {
21 namespace MiscServices {
22 constexpr int32_t STR_MAX_LENGTH = 4096;
23 constexpr size_t STR_TAIL_LENGTH = 1;
24 constexpr size_t ARGC_MAX = 6;
25 constexpr size_t ARGC_ONE = 1;
26 const std::map<int32_t, int32_t> JsUtils::ERROR_CODE_MAP = {
27 { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER },
28 { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION },
29 { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION },
30 { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT },
31 { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT },
32 { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT },
33 { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT },
34 { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE },
35 { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED },
36 { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT },
37 { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS },
38 { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS },
39 { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS },
40 { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS },
41 { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS },
42 { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS },
43 { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS },
44 { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST },
45 { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER },
46 { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS },
47 { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS },
48 { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS },
49 { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS },
50 { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS },
51 { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS },
52 { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME },
53 { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE },
54 { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK },
55 { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME },
56 { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS },
57 { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS },
58 { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND },
59 { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER },
60 { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT },
61 { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK },
62 { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT },
63 { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED },
64 { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK },
65 { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE },
66 { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT },
67 { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT },
68 { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK },
69 { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG },
70 { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG },
71 { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT },
72 { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS },
73 { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS },
74 { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS },
75 { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS },
76 { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS },
77 { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS },
78 { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS },
79 { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS },
80 { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS },
81 { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS },
82 { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS },
83 { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS },
84 { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS },
85 { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS },
86 { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS },
87 { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS },
88 { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS },
89 { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS },
90 { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED },
91 };
92
93 const std::map<int32_t, std::string> JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = {
94 { EXCEPTION_PERMISSION, "the permissions check fails." },
95 { EXCEPTION_SYSTEM_PERMISSION, "not system application." },
96 { EXCEPTION_PARAMCHECK, "the parameters check fails." },
97 { EXCEPTION_UNSUPPORTED, "capability not supported." },
98 { EXCEPTION_PACKAGEMANAGER, "bundle manager error." },
99 { EXCEPTION_IMENGINE, "input method engine error." },
100 { EXCEPTION_IMCLIENT, "input method client error." },
101 { EXCEPTION_IME, "not an input method." },
102 { EXCEPTION_CONFPERSIST, "configuration persistence error." },
103 { EXCEPTION_CONTROLLER, "input method controller error." },
104 { EXCEPTION_SETTINGS, "input method setter error." },
105 { EXCEPTION_IMMS, "input method manager service error." },
106 { EXCEPTION_DETACHED, "input method client detached." },
107 { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." },
108 { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." },
109 { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." },
110 { EXCEPTION_WINDOW_MANAGER, "window manager service error." },
111 { EXCEPTION_BASIC_MODE, "the input method is basic mode." },
112 { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." },
113 { EXCEPTION_EDITABLE, "the edit mode need enable." },
114 { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." },
115 };
116
117 const std::map<int32_t, std::string> JsUtils::PARAMETER_TYPE = {
118 { TYPE_UNDEFINED, "napi_undefine." },
119 { TYPE_NULL, "napi_null." },
120 { TYPE_BOOLEAN, "napi_boolean." },
121 { TYPE_NUMBER, "napi_number." },
122 { TYPE_STRING, "napi_string." },
123 { TYPE_SYMBOL, "napi_symbol." },
124 { TYPE_OBJECT, "napi_object." },
125 { TYPE_FUNCTION, "napi_function." },
126 { TYPE_EXTERNAL, "napi_external." },
127 { TYPE_BIGINT, "napi_bigint." },
128 { TYPE_ARRAY_BUFFER, "ArrayBuffer." },
129 { TYPE_ARRAY, "napi_array." },
130 };
131
ThrowException(napi_env env,int32_t err,const std::string & msg,TypeCode type)132 void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type)
133 {
134 std::string errMsg = ToMessage(err);
135 napi_value error;
136 napi_value code;
137 napi_value message;
138 if (type == TypeCode::TYPE_NONE) {
139 errMsg = errMsg + " " + msg;
140 IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str());
141 } else {
142 auto iter = PARAMETER_TYPE.find(type);
143 if (iter != PARAMETER_TYPE.end()) {
144 errMsg = errMsg + "The type of " + msg + " must be " + iter->second;
145 IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str());
146 }
147 }
148 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
149 NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error));
150 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code));
151 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code));
152 NAPI_CALL_RETURN_VOID(env, napi_throw(env, error));
153 }
154
ToError(napi_env env,int32_t code,const std::string & msg)155 napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg)
156 {
157 IMSA_HILOGD("ToError start");
158 napi_value errorObj;
159 NAPI_CALL(env, napi_create_object(env, &errorObj));
160 napi_value errorCode = nullptr;
161 NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode));
162 napi_value errorMessage = nullptr;
163 std::string errMsg = ToMessage(Convert(code)) + " " + msg;
164 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
165 NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode));
166 NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage));
167 IMSA_HILOGD("ToError end");
168 return errorObj;
169 }
170
Convert(int32_t code)171 int32_t JsUtils::Convert(int32_t code)
172 {
173 IMSA_HILOGD("Convert start.");
174 auto iter = ERROR_CODE_MAP.find(code);
175 if (iter != ERROR_CODE_MAP.end()) {
176 IMSA_HILOGD("ErrorCode: %{public}d", iter->second);
177 return iter->second;
178 }
179 IMSA_HILOGD("Convert end.");
180 return ERROR_CODE_QUERY_FAILED;
181 }
182
ToMessage(int32_t code)183 const std::string JsUtils::ToMessage(int32_t code)
184 {
185 IMSA_HILOGD("ToMessage start");
186 auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
187 if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
188 IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str());
189 return iter->second;
190 }
191 return "error is out of definition.";
192 }
193
Equals(napi_env env,napi_value value,napi_ref copy,std::thread::id threadId)194 bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
195 {
196 if (copy == nullptr) {
197 return value == nullptr;
198 }
199
200 if (threadId != std::this_thread::get_id()) {
201 IMSA_HILOGD("napi_value can not be compared");
202 return false;
203 }
204
205 napi_value copyValue = nullptr;
206 napi_get_reference_value(env, copy, ©Value);
207
208 bool isEquals = false;
209 napi_strict_equals(env, value, copyValue, &isEquals);
210 IMSA_HILOGD("value compare result: %{public}d", isEquals);
211 return isEquals;
212 }
213
GetNativeSelf(napi_env env,napi_callback_info info)214 void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info)
215 {
216 size_t argc = ARGC_MAX;
217 void *native = nullptr;
218 napi_value self = nullptr;
219 napi_value argv[ARGC_MAX] = { nullptr };
220 napi_status status = napi_invalid_arg;
221 napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
222 CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr);
223
224 status = napi_unwrap(env, self, &native);
225 CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr);
226 return native;
227 }
228
GetValue(napi_env env,napi_value in,int32_t & out)229 napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out)
230 {
231 napi_valuetype type = napi_undefined;
232 napi_status status = napi_typeof(env, in, &type);
233 CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure);
234 return napi_get_value_int32(env, in, &out);
235 }
236
237 /* napi_value <-> uint32_t */
GetValue(napi_env env,napi_value in,uint32_t & out)238 napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out)
239 {
240 napi_valuetype type = napi_undefined;
241 napi_status status = napi_typeof(env, in, &type);
242 CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure);
243 return napi_get_value_uint32(env, in, &out);
244 }
245
GetValue(napi_env env,napi_value in,bool & out)246 napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out)
247 {
248 napi_valuetype type = napi_undefined;
249 napi_status status = napi_typeof(env, in, &type);
250 CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure);
251 return napi_get_value_bool(env, in, &out);
252 }
253
GetValue(napi_env env,napi_value in,double & out)254 napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out)
255 {
256 napi_valuetype type = napi_undefined;
257 napi_status status = napi_typeof(env, in, &type);
258 CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure);
259 return napi_get_value_double(env, in, &out);
260 }
261
262 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)263 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out)
264 {
265 IMSA_HILOGD("JsUtils get string value in.");
266 napi_valuetype type = napi_undefined;
267 napi_status status = napi_typeof(env, in, &type);
268 CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure);
269
270 size_t maxLen = STR_MAX_LENGTH;
271 status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
272 if (maxLen <= 0) {
273 return status;
274 }
275 IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen);
276 char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
277 if (buf != nullptr) {
278 size_t len = 0;
279 status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
280 if (status == napi_ok) {
281 buf[len] = 0;
282 out = std::string(buf);
283 }
284 delete[] buf;
285 } else {
286 status = napi_generic_failure;
287 }
288 return status;
289 }
290
291 /* napi_value <-> std::unordered_map<string, string> */
GetValue(napi_env env,napi_value in,std::unordered_map<std::string,PrivateDataValue> & out)292 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map<std::string, PrivateDataValue> &out)
293 {
294 napi_valuetype type = napi_undefined;
295 napi_status status = napi_typeof(env, in, &type);
296 PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure);
297
298 napi_value keys = nullptr;
299 napi_get_property_names(env, in, &keys);
300 uint32_t arrLen = 0;
301 status = napi_get_array_length(env, keys, &arrLen);
302 if (status != napi_ok) {
303 IMSA_HILOGE("napi_get_array_length error");
304 return status;
305 }
306 // 5 means max private command count.
307 PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE,
308 napi_generic_failure);
309 IMSA_HILOGD("length : %{public}u", arrLen);
310 for (size_t iter = 0; iter < arrLen; ++iter) {
311 napi_value key = nullptr;
312 status = napi_get_element(env, keys, iter, &key);
313 CHECK_RETURN(status == napi_ok, "napi_get_element error", status);
314
315 napi_value value = nullptr;
316 status = napi_get_property(env, in, key, &value);
317 CHECK_RETURN(status == napi_ok, "napi_get_property error", status);
318
319 std::string keyStr;
320 status = GetValue(env, key, keyStr);
321 CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status);
322
323 PrivateDataValue privateCommand;
324 status = GetValue(env, value, privateCommand);
325 CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status);
326 out.emplace(keyStr, privateCommand);
327 }
328 return status;
329 }
330
GetValue(napi_env env,napi_value in,PrivateDataValue & out)331 napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out)
332 {
333 napi_valuetype valueType = napi_undefined;
334 napi_status status = napi_typeof(env, in, &valueType);
335 CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure);
336 if (valueType == napi_string) {
337 std::string privateDataStr;
338 status = GetValue(env, in, privateDataStr);
339 CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure);
340 out.emplace<std::string>(privateDataStr);
341 } else if (valueType == napi_boolean) {
342 bool privateDataBool = false;
343 status = GetValue(env, in, privateDataBool);
344 CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure);
345 out.emplace<bool>(privateDataBool);
346 } else if (valueType == napi_number) {
347 int32_t privateDataInt = 0;
348 status = GetValue(env, in, privateDataInt);
349 CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure);
350 out.emplace<int32_t>(privateDataInt);
351 } else {
352 PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure);
353 }
354 return status;
355 }
356
GetValue(napi_env env,napi_value in,const std::string & type,napi_value & out)357 napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out)
358 {
359 napi_valuetype valueType = napi_undefined;
360 napi_status status = napi_typeof(env, in, &valueType);
361 if ((status == napi_ok) && (valueType == napi_object)) {
362 status = napi_get_named_property(env, in, type.c_str(), &out);
363 return status;
364 }
365 return napi_generic_failure;
366 }
367
368 /* napi_value <-> PanelInfo */
GetValue(napi_env env,napi_value in,PanelInfo & out)369 napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out)
370 {
371 IMSA_HILOGD("napi_value -> PanelInfo ");
372 napi_value propType = nullptr;
373 napi_status status = napi_get_named_property(env, in, "type", &propType);
374 CHECK_RETURN((status == napi_ok), "no property type ", status);
375 int32_t panelType = 0;
376 status = GetValue(env, propType, panelType);
377 CHECK_RETURN((status == napi_ok), "no value of type ", status);
378
379 // PanelFlag is optional, defaults to FLG_FIXED when empty.
380 int32_t panelFlag = static_cast<int32_t>(PanelFlag::FLG_FIXED);
381 napi_value panelFlagObj = nullptr;
382 status = napi_get_named_property(env, in, "flag", &panelFlagObj);
383 if (status == napi_ok) {
384 JsUtils::GetValue(env, panelFlagObj, panelFlag);
385 }
386
387 out.panelType = PanelType(panelType);
388 out.panelFlag = PanelFlag(panelFlag);
389 return napi_ok;
390 }
391
GetValue(napi_env env,const std::vector<InputWindowInfo> & in)392 napi_value JsUtils::GetValue(napi_env env, const std::vector<InputWindowInfo> &in)
393 {
394 napi_value array = nullptr;
395 uint32_t index = 0;
396 napi_create_array(env, &array);
397 if (array == nullptr) {
398 IMSA_HILOGE("create array failed");
399 return array;
400 }
401 for (const auto &info : in) {
402 napi_value jsInfo = GetValue(env, info);
403 napi_set_element(env, array, index, jsInfo);
404 ++index;
405 }
406 return array;
407 }
408
GetValue(napi_env env,const InputWindowInfo & in)409 napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in)
410 {
411 napi_value info = nullptr;
412 napi_create_object(env, &info);
413
414 napi_value name = nullptr;
415 napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name);
416 napi_set_named_property(env, info, "name", name);
417
418 napi_value left = nullptr;
419 napi_create_int32(env, in.left, &left);
420 napi_set_named_property(env, info, "left", left);
421
422 napi_value top = nullptr;
423 napi_create_int32(env, in.top, &top);
424 napi_set_named_property(env, info, "top", top);
425
426 napi_value width = nullptr;
427 napi_create_uint32(env, in.width, &width);
428 napi_set_named_property(env, info, "width", width);
429
430 napi_value height = nullptr;
431 napi_create_uint32(env, in.height, &height);
432 napi_set_named_property(env, info, "height", height);
433
434 return info;
435 }
436
GetValue(napi_env env,const std::string & in,napi_value & out)437 napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out)
438 {
439 return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
440 }
441
GetJsPrivateCommand(napi_env env,const std::unordered_map<std::string,PrivateDataValue> & in)442 napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map<std::string, PrivateDataValue> &in)
443 {
444 napi_value jsPrivateCommand = nullptr;
445 NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand));
446 for (const auto &iter : in) {
447 size_t idx = iter.second.index();
448 napi_value value = nullptr;
449 if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_STRING)) {
450 auto stringValue = std::get_if<std::string>(&iter.second);
451 if (stringValue != nullptr) {
452 NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value));
453 }
454 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_BOOL)) {
455 auto boolValue = std::get_if<bool>(&iter.second);
456 if (boolValue != nullptr) {
457 NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value));
458 }
459 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) {
460 auto numberValue = std::get_if<int32_t>(&iter.second);
461 if (numberValue != nullptr) {
462 NAPI_CALL(env, napi_create_int32(env, *numberValue, &value));
463 }
464 }
465 NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value));
466 }
467 return jsPrivateCommand;
468 }
469
GetValue(napi_env env,napi_value in,Rosen::Rect & out)470 napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out)
471 {
472 bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_);
473 ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_);
474 ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_);
475 ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_);
476 return ret ? napi_ok : napi_generic_failure;
477 }
478
GetValue(napi_env env,const Rosen::Rect & in)479 napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in)
480 {
481 napi_value jsObject = nullptr;
482 napi_create_object(env, &jsObject);
483 bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_);
484 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_);
485 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_);
486 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_);
487 return ret ? jsObject : JsUtil::Const::Null(env);
488 }
489
GetValue(napi_env env,const std::vector<uint8_t> & in)490 napi_value JsUtils::GetValue(napi_env env, const std::vector<uint8_t> &in)
491 {
492 void *data = nullptr;
493 napi_value arrayBuffer = nullptr;
494 size_t length = in.size();
495 NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer));
496 // 0 means the size of data.
497 CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer);
498 if (memcpy_s(data, length, reinterpret_cast<const void *>(in.data()), length) != 0) {
499 return nullptr;
500 }
501 return arrayBuffer;
502 }
503
GetValue(napi_env env,napi_value in,std::vector<uint8_t> & out)504 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector<uint8_t> &out)
505 {
506 size_t length = 0;
507 void *data = nullptr;
508 auto status = napi_get_arraybuffer_info(env, in, &data, &length);
509 if (status != napi_ok) {
510 IMSA_HILOGE("Get ArrayBuffer info failed!");
511 return status;
512 }
513 if (data == nullptr && length == 0) {
514 IMSA_HILOGI("Empty ArrayBuffer!");
515 out.clear();
516 return napi_ok;
517 }
518 if (data == nullptr) {
519 IMSA_HILOGE("ArrayBuffer data is nullptr!");
520 return napi_generic_failure;
521 }
522 IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length);
523 out.assign(reinterpret_cast<const uint8_t *>(data), reinterpret_cast<const uint8_t *>(data) + length);
524 return napi_ok;
525 }
526
GetMessageHandlerCallbackParam(napi_value * argv,const std::shared_ptr<JSMsgHandlerCallbackObject> & jsMessageHandler,const ArrayBuffer & arrayBuffer,size_t size)527 napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv,
528 const std::shared_ptr<JSMsgHandlerCallbackObject> &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size)
529 {
530 if (argv == nullptr) {
531 IMSA_HILOGE("argv is nullptr!.");
532 return napi_generic_failure;
533 }
534 if (size < ARGC_ONE) {
535 IMSA_HILOGE("argv size is less than 1!.");
536 return napi_generic_failure;
537 }
538 if (jsMessageHandler == nullptr) {
539 IMSA_HILOGE("jsMessageHandler is nullptr!.");
540 return napi_generic_failure;
541 }
542 napi_value jsMsgId = nullptr;
543 auto status = napi_create_string_utf8(
544 jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId);
545 if (status != napi_ok) {
546 IMSA_HILOGE("napi_create_string_utf8 failed!.");
547 return napi_generic_failure;
548 }
549 // 0 means the first param index of callback.
550 argv[0] = { jsMsgId };
551 if (arrayBuffer.jsArgc > ARGC_ONE) {
552 napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam);
553 if (jsMsgParam == nullptr) {
554 IMSA_HILOGE("Get js messageParam object failed!.");
555 return napi_generic_failure;
556 }
557 // 0 means the second param index of callback.
558 argv[1] = { jsMsgParam };
559 }
560 return napi_ok;
561 }
562 } // namespace MiscServices
563 } // namespace OHOS