• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &copyValue);
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