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 { ErrorCode::ERROR_IME_NOT_FOUND, EXCEPTION_IME_NOT_FOUND },
92 { ErrorCode::ERROR_OPERATE_SYSTEM_IME, EXCEPTION_OPERATE_DEFAULTIME },
93 { ErrorCode::ERROR_SWITCH_IME, EXCEPTION_IMMS },
94 { ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL, EXCEPTION_IMCLIENT },
95 { ErrorCode::ERROR_IMA_INVALID_IMMERSIVE_EFFECT, EXCEPTION_INVALID_IMMERSIVE_EFFECT },
96 { ErrorCode::ERROR_IMA_PRECONDITION_REQUIRED, EXCEPTION_PRECONDITION_REQUIRED },
97 };
98
99 const std::map<int32_t, std::string> JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = {
100 { EXCEPTION_PERMISSION, "the permissions check fails." },
101 { EXCEPTION_SYSTEM_PERMISSION, "not system application." },
102 { EXCEPTION_PARAMCHECK, "the parameters check fails." },
103 { EXCEPTION_UNSUPPORTED, "capability not supported." },
104 { EXCEPTION_PACKAGEMANAGER, "bundle manager error." },
105 { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\
106 2.the input method application does not subscribe to related events." },
107 { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\
108 2.no edit box is bound to current input method application." },
109 { EXCEPTION_IME, "not an input method application." },
110 { EXCEPTION_CONFPERSIST, "configuration persistence error." },
111 { EXCEPTION_CONTROLLER, "input method controller error.\
112 Possible cause: create InputmethodController object failed." },
113 { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." },
114 { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\
115 IPC exception." },
116 { EXCEPTION_DETACHED, "input method client detached." },
117 { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." },
118 { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." },
119 { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." },
120 { EXCEPTION_WINDOW_MANAGER, "window manager service error." },
121 { EXCEPTION_BASIC_MODE, "the input method is in basic mode." },
122 { EXCEPTION_REQUEST_NOT_ACCEPT, "the other side does not accept the request." },
123 { EXCEPTION_EDITABLE, "input method client is not editable." },
124 { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." },
125 { EXCEPTION_IME_NOT_FOUND, "the input method is not found." },
126 { EXCEPTION_OPERATE_DEFAULTIME, "current operation cannot be applied to the preconfigured default input method." },
127 { EXCEPTION_INVALID_IMMERSIVE_EFFECT, "invalid immersive effect. \n\
128 1.The gradient mode and the fluid light mode can only be used when the immersive mode is enabled.\n\
129 2.The fluid light mode can only be used when the gradient mode is enabled.\n\
130 3.When the gradient mode is not enabled, the gradient height can only be 0." },
131 { EXCEPTION_PRECONDITION_REQUIRED, "this operation must be called after adjustPanelRect or resize." },
132 };
133
134 const std::map<int32_t, std::string> JsUtils::PARAMETER_TYPE = {
135 { TYPE_UNDEFINED, "napi_undefine." },
136 { TYPE_NULL, "napi_null." },
137 { TYPE_BOOLEAN, "napi_boolean." },
138 { TYPE_NUMBER, "napi_number." },
139 { TYPE_STRING, "napi_string." },
140 { TYPE_SYMBOL, "napi_symbol." },
141 { TYPE_OBJECT, "napi_object." },
142 { TYPE_FUNCTION, "napi_function." },
143 { TYPE_EXTERNAL, "napi_external." },
144 { TYPE_BIGINT, "napi_bigint." },
145 { TYPE_ARRAY_BUFFER, "ArrayBuffer." },
146 { TYPE_ARRAY, "napi_array." },
147 };
148
ThrowException(napi_env env,int32_t err,const std::string & msg,TypeCode type)149 void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type)
150 {
151 std::string errMsg = ToMessage(err);
152 napi_value error;
153 napi_value code;
154 napi_value message;
155 if (type == TypeCode::TYPE_NONE) {
156 errMsg = errMsg + " " + msg;
157 IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str());
158 } else {
159 auto iter = PARAMETER_TYPE.find(type);
160 if (iter != PARAMETER_TYPE.end()) {
161 errMsg = errMsg + "The type of " + msg + " must be " + iter->second;
162 IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str());
163 }
164 }
165 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
166 NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error));
167 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code));
168 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code));
169 NAPI_CALL_RETURN_VOID(env, napi_throw(env, error));
170 }
171
ToError(napi_env env,int32_t code,const std::string & msg)172 napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg)
173 {
174 IMSA_HILOGD("ToError start");
175 napi_value errorObj;
176 NAPI_CALL(env, napi_create_object(env, &errorObj));
177 napi_value errorCode = nullptr;
178 NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode));
179 napi_value errorMessage = nullptr;
180 std::string errMsg = ToMessage(Convert(code)) + " " + msg;
181 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
182 NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode));
183 NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage));
184 IMSA_HILOGD("ToError end");
185 return errorObj;
186 }
187
Convert(int32_t code)188 int32_t JsUtils::Convert(int32_t code)
189 {
190 IMSA_HILOGD("Convert start.");
191 auto iter = ERROR_CODE_MAP.find(code);
192 if (iter != ERROR_CODE_MAP.end()) {
193 IMSA_HILOGD("ErrorCode: %{public}d", iter->second);
194 return iter->second;
195 }
196 IMSA_HILOGD("Convert end.");
197 return ERROR_CODE_QUERY_FAILED;
198 }
199
ToMessage(int32_t code)200 const std::string JsUtils::ToMessage(int32_t code)
201 {
202 IMSA_HILOGD("ToMessage start");
203 auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
204 if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
205 IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str());
206 return iter->second;
207 }
208 return "error is out of definition.";
209 }
210
Equals(napi_env env,napi_value value,napi_ref copy,std::thread::id threadId)211 bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
212 {
213 if (copy == nullptr) {
214 return value == nullptr;
215 }
216
217 if (threadId != std::this_thread::get_id()) {
218 IMSA_HILOGD("napi_value can not be compared");
219 return false;
220 }
221
222 napi_value copyValue = nullptr;
223 napi_get_reference_value(env, copy, ©Value);
224
225 bool isEquals = false;
226 napi_strict_equals(env, value, copyValue, &isEquals);
227 IMSA_HILOGD("value compare result: %{public}d", isEquals);
228 return isEquals;
229 }
230
GetNativeSelf(napi_env env,napi_callback_info info)231 void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info)
232 {
233 size_t argc = ARGC_MAX;
234 void *native = nullptr;
235 napi_value self = nullptr;
236 napi_value argv[ARGC_MAX] = { nullptr };
237 napi_status status = napi_invalid_arg;
238 napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
239 CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr);
240
241 status = napi_unwrap(env, self, &native);
242 CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr);
243 return native;
244 }
245
GetValue(napi_env env,napi_value in,int32_t & out)246 napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &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_number), "invalid type", napi_generic_failure);
251 return napi_get_value_int32(env, in, &out);
252 }
253
254 /* napi_value <-> uint32_t */
GetValue(napi_env env,napi_value in,uint32_t & out)255 napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out)
256 {
257 napi_valuetype type = napi_undefined;
258 napi_status status = napi_typeof(env, in, &type);
259 CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure);
260 return napi_get_value_uint32(env, in, &out);
261 }
262
GetValue(napi_env env,napi_value in,bool & out)263 napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out)
264 {
265 napi_valuetype type = napi_undefined;
266 napi_status status = napi_typeof(env, in, &type);
267 CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure);
268 return napi_get_value_bool(env, in, &out);
269 }
270
GetValue(napi_env env,napi_value in,double & out)271 napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out)
272 {
273 napi_valuetype type = napi_undefined;
274 napi_status status = napi_typeof(env, in, &type);
275 CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure);
276 return napi_get_value_double(env, in, &out);
277 }
278
279 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)280 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out)
281 {
282 IMSA_HILOGD("JsUtils get string value in.");
283 napi_valuetype type = napi_undefined;
284 napi_status status = napi_typeof(env, in, &type);
285 CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure);
286
287 size_t maxLen = STR_MAX_LENGTH;
288 status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
289 if (maxLen <= 0) {
290 return status;
291 }
292
293 if (maxLen > STR_MAX_LENGTH) {
294 IMSA_HILOGE("string length is too long.");
295 return napi_generic_failure;
296 }
297 IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen);
298 char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
299 if (buf != nullptr) {
300 size_t len = 0;
301 status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
302 if (status == napi_ok) {
303 buf[len] = 0;
304 out = std::string(buf);
305 }
306 delete[] buf;
307 } else {
308 status = napi_generic_failure;
309 }
310 return status;
311 }
312
313 /* napi_value <-> std::unordered_map<string, string> */
GetValue(napi_env env,napi_value in,std::unordered_map<std::string,PrivateDataValue> & out)314 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map<std::string, PrivateDataValue> &out)
315 {
316 napi_valuetype type = napi_undefined;
317 napi_status status = napi_typeof(env, in, &type);
318 PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure);
319
320 napi_value keys = nullptr;
321 napi_get_property_names(env, in, &keys);
322 uint32_t arrLen = 0;
323 status = napi_get_array_length(env, keys, &arrLen);
324 if (status != napi_ok) {
325 IMSA_HILOGE("napi_get_array_length error");
326 return status;
327 }
328 // 5 means max private command count.
329 PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE,
330 napi_generic_failure);
331 IMSA_HILOGD("length : %{public}u", arrLen);
332 for (size_t iter = 0; iter < arrLen; ++iter) {
333 napi_value key = nullptr;
334 status = napi_get_element(env, keys, iter, &key);
335 CHECK_RETURN(status == napi_ok, "napi_get_element error", status);
336
337 napi_value value = nullptr;
338 status = napi_get_property(env, in, key, &value);
339 CHECK_RETURN(status == napi_ok, "napi_get_property error", status);
340
341 std::string keyStr;
342 status = GetValue(env, key, keyStr);
343 CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status);
344
345 PrivateDataValue privateCommand;
346 status = GetValue(env, value, privateCommand);
347 CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status);
348 out.emplace(keyStr, privateCommand);
349 }
350 return status;
351 }
352
GetValue(napi_env env,napi_value in,PrivateDataValue & out)353 napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out)
354 {
355 napi_valuetype valueType = napi_undefined;
356 napi_status status = napi_typeof(env, in, &valueType);
357 CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure);
358 if (valueType == napi_string) {
359 std::string privateDataStr;
360 status = GetValue(env, in, privateDataStr);
361 CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure);
362 out.emplace<std::string>(privateDataStr);
363 } else if (valueType == napi_boolean) {
364 bool privateDataBool = false;
365 status = GetValue(env, in, privateDataBool);
366 CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure);
367 out.emplace<bool>(privateDataBool);
368 } else if (valueType == napi_number) {
369 int32_t privateDataInt = 0;
370 status = GetValue(env, in, privateDataInt);
371 CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure);
372 out.emplace<int32_t>(privateDataInt);
373 } else {
374 PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure);
375 }
376 return status;
377 }
378
GetValue(napi_env env,napi_value in,const std::string & type,napi_value & out)379 napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out)
380 {
381 napi_valuetype valueType = napi_undefined;
382 napi_status status = napi_typeof(env, in, &valueType);
383 if ((status == napi_ok) && (valueType == napi_object)) {
384 status = napi_get_named_property(env, in, type.c_str(), &out);
385 return status;
386 }
387 return napi_generic_failure;
388 }
389
390 /* napi_value <-> PanelInfo */
GetValue(napi_env env,napi_value in,PanelInfo & out)391 napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out)
392 {
393 IMSA_HILOGD("napi_value -> PanelInfo ");
394 napi_value propType = nullptr;
395 napi_status status = napi_get_named_property(env, in, "type", &propType);
396 CHECK_RETURN((status == napi_ok), "no property type ", status);
397 int32_t panelType = 0;
398 status = GetValue(env, propType, panelType);
399 CHECK_RETURN((status == napi_ok), "no value of type ", status);
400
401 // PanelFlag is optional, defaults to FLG_FIXED when empty.
402 int32_t panelFlag = static_cast<int32_t>(PanelFlag::FLG_FIXED);
403 napi_value panelFlagObj = nullptr;
404 status = napi_get_named_property(env, in, "flag", &panelFlagObj);
405 if (status == napi_ok) {
406 JsUtils::GetValue(env, panelFlagObj, panelFlag);
407 }
408
409 out.panelType = PanelType(panelType);
410 out.panelFlag = PanelFlag(panelFlag);
411 return napi_ok;
412 }
413
GetValue(napi_env env,const std::vector<InputWindowInfo> & in)414 napi_value JsUtils::GetValue(napi_env env, const std::vector<InputWindowInfo> &in)
415 {
416 napi_value array = nullptr;
417 uint32_t index = 0;
418 napi_create_array(env, &array);
419 if (array == nullptr) {
420 IMSA_HILOGE("create array failed");
421 return array;
422 }
423 for (const auto &info : in) {
424 napi_value jsInfo = GetValue(env, info);
425 napi_set_element(env, array, index, jsInfo);
426 ++index;
427 }
428 return array;
429 }
430
GetValue(napi_env env,const InputWindowInfo & in)431 napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in)
432 {
433 napi_value info = nullptr;
434 napi_create_object(env, &info);
435
436 napi_value name = nullptr;
437 napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name);
438 napi_set_named_property(env, info, "name", name);
439
440 napi_value left = nullptr;
441 napi_create_int32(env, in.left, &left);
442 napi_set_named_property(env, info, "left", left);
443
444 napi_value top = nullptr;
445 napi_create_int32(env, in.top, &top);
446 napi_set_named_property(env, info, "top", top);
447
448 napi_value width = nullptr;
449 napi_create_uint32(env, in.width, &width);
450 napi_set_named_property(env, info, "width", width);
451
452 napi_value height = nullptr;
453 napi_create_uint32(env, in.height, &height);
454 napi_set_named_property(env, info, "height", height);
455
456 return info;
457 }
458
GetValue(napi_env env,const std::string & in,napi_value & out)459 napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out)
460 {
461 return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
462 }
463
GetJsPrivateCommand(napi_env env,const std::unordered_map<std::string,PrivateDataValue> & in)464 napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map<std::string, PrivateDataValue> &in)
465 {
466 napi_value jsPrivateCommand = nullptr;
467 NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand));
468 for (const auto &iter : in) {
469 size_t idx = iter.second.index();
470 napi_value value = nullptr;
471 if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_STRING)) {
472 auto stringValue = std::get_if<std::string>(&iter.second);
473 if (stringValue != nullptr) {
474 NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value));
475 }
476 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_BOOL)) {
477 auto boolValue = std::get_if<bool>(&iter.second);
478 if (boolValue != nullptr) {
479 NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value));
480 }
481 } else if (idx == static_cast<size_t>(PrivateDataValueType::VALUE_TYPE_NUMBER)) {
482 auto numberValue = std::get_if<int32_t>(&iter.second);
483 if (numberValue != nullptr) {
484 NAPI_CALL(env, napi_create_int32(env, *numberValue, &value));
485 }
486 }
487 NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value));
488 }
489 return jsPrivateCommand;
490 }
491
GetValue(napi_env env,napi_value in,Rosen::Rect & out)492 napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out)
493 {
494 bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_);
495 ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_);
496 ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_);
497 ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_);
498 return ret ? napi_ok : napi_generic_failure;
499 }
500
GetValue(napi_env env,const Rosen::Rect & in)501 napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in)
502 {
503 napi_value jsObject = nullptr;
504 napi_create_object(env, &jsObject);
505 bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_);
506 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_);
507 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_);
508 ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_);
509 return ret ? jsObject : JsUtil::Const::Null(env);
510 }
511
GetValue(napi_env env,const std::vector<uint8_t> & in)512 napi_value JsUtils::GetValue(napi_env env, const std::vector<uint8_t> &in)
513 {
514 void *data = nullptr;
515 napi_value arrayBuffer = nullptr;
516 size_t length = in.size();
517 NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer));
518 // 0 means the size of data.
519 CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer);
520 if (memcpy_s(data, length, reinterpret_cast<const void *>(in.data()), length) != 0) {
521 return nullptr;
522 }
523 return arrayBuffer;
524 }
525
GetValue(napi_env env,napi_value in,std::vector<uint8_t> & out)526 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector<uint8_t> &out)
527 {
528 size_t length = 0;
529 void *data = nullptr;
530 auto status = napi_get_arraybuffer_info(env, in, &data, &length);
531 if (status != napi_ok) {
532 IMSA_HILOGE("Get ArrayBuffer info failed!");
533 return status;
534 }
535 if (data == nullptr && length == 0) {
536 IMSA_HILOGI("Empty ArrayBuffer!");
537 out.clear();
538 return napi_ok;
539 }
540 if (data == nullptr) {
541 IMSA_HILOGE("ArrayBuffer data is nullptr!");
542 return napi_generic_failure;
543 }
544 IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length);
545 out.assign(reinterpret_cast<const uint8_t *>(data), reinterpret_cast<const uint8_t *>(data) + length);
546 return napi_ok;
547 }
548
GetMessageHandlerCallbackParam(napi_value * argv,const std::shared_ptr<JSMsgHandlerCallbackObject> & jsMessageHandler,const ArrayBuffer & arrayBuffer,size_t size)549 napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv,
550 const std::shared_ptr<JSMsgHandlerCallbackObject> &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size)
551 {
552 if (argv == nullptr) {
553 IMSA_HILOGE("argv is nullptr!.");
554 return napi_generic_failure;
555 }
556 if (size <= ARGC_ONE) {
557 IMSA_HILOGE("argv size is less than 2!.");
558 return napi_generic_failure;
559 }
560 if (jsMessageHandler == nullptr) {
561 IMSA_HILOGE("jsMessageHandler is nullptr!.");
562 return napi_generic_failure;
563 }
564 napi_value jsMsgId = nullptr;
565 auto status = napi_create_string_utf8(
566 jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId);
567 if (status != napi_ok) {
568 IMSA_HILOGE("napi_create_string_utf8 failed!.");
569 return napi_generic_failure;
570 }
571 // 0 means the first param index of callback.
572 argv[0] = { jsMsgId };
573 if (arrayBuffer.jsArgc > ARGC_ONE) {
574 napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam);
575 if (jsMsgParam == nullptr) {
576 IMSA_HILOGE("Get js messageParam object failed!.");
577 return napi_generic_failure;
578 }
579 // 0 means the second param index of callback.
580 argv[1] = { jsMsgParam };
581 }
582 return napi_ok;
583 }
584 } // namespace MiscServices
585 } // namespace OHOS