• 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     { 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, &copyValue);
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