• 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 const std::map<int32_t, int32_t> JsUtils::ERROR_CODE_MAP = {
26     { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER },
27     { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION },
28     { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION },
29     { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT },
30     { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT },
31     { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT },
32     { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT },
33     { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_IMCLIENT },
34     { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED },
35     { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT },
36     { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS },
37     { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS },
38     { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS },
39     { ErrorCode::ERROR_IME_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 };
59 
60 const std::map<int32_t, std::string> JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = {
61     { EXCEPTION_PERMISSION, "the permissions check fails." },
62     { EXCEPTION_SYSTEM_PERMISSION, "not system application." },
63     { EXCEPTION_PARAMCHECK, "the parameters check fails." },
64     { EXCEPTION_UNSUPPORTED, "call unsupported api." },
65     { EXCEPTION_PACKAGEMANAGER, "package manager error." },
66     { EXCEPTION_IMENGINE, "input method engine error." },
67     { EXCEPTION_IMCLIENT, "input method client error." },
68     { EXCEPTION_IME, "not an input method extension." },
69     { EXCEPTION_CONFPERSIST, "configuration persisting error." },
70     { EXCEPTION_CONTROLLER, "input method controller error." },
71     { EXCEPTION_SETTINGS, "input method settings extension error." },
72     { EXCEPTION_IMMS, "input method manager service error." },
73     { EXCEPTION_DETACHED, "input method not attached." },
74     { EXCEPTION_DEFAULTIME, "not default input method configured by system." },
75 };
76 
77 const std::map<int32_t, std::string> JsUtils::PARAMETER_TYPE = {
78     { TYPE_UNDEFINED, "napi_undefine." },
79     { TYPE_NULL, "napi_null." },
80     { TYPE_BOOLEAN, "napi_boolean." },
81     { TYPE_NUMBER, "napi_number." },
82     { TYPE_STRING, "napi_string." },
83     { TYPE_SYMBOL, "napi_symbol." },
84     { TYPE_OBJECT, "napi_object." },
85     { TYPE_FUNCTION, "napi_function." },
86     { TYPE_EXTERNAL, "napi_external." },
87     { TYPE_BIGINT, "napi_bigint." },
88 };
89 
ThrowException(napi_env env,int32_t err,const std::string & msg,TypeCode type)90 void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type)
91 {
92     std::string errMsg = ToMessage(err);
93     napi_value error;
94     napi_value code;
95     napi_value message;
96     if (type == TypeCode::TYPE_NONE) {
97         errMsg = errMsg + msg;
98         IMSA_HILOGE("THROW_ERROR message: %{public}s", errMsg.c_str());
99     } else {
100         auto iter = PARAMETER_TYPE.find(type);
101         if (iter != PARAMETER_TYPE.end()) {
102             errMsg = errMsg + "The type of " + msg + " must be " + iter->second;
103             IMSA_HILOGE("THROW_ERROR message: %{public}s", errMsg.c_str());
104         }
105     }
106     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
107     NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error));
108     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code));
109     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code));
110     NAPI_CALL_RETURN_VOID(env, napi_throw(env, error));
111 }
112 
ToError(napi_env env,int32_t code)113 napi_value JsUtils::ToError(napi_env env, int32_t code)
114 {
115     IMSA_HILOGD("ToError start");
116     napi_value errorObj;
117     NAPI_CALL(env, napi_create_object(env, &errorObj));
118     napi_value errorCode = nullptr;
119     NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode));
120     napi_value errorMessage = nullptr;
121     NAPI_CALL(env, napi_create_string_utf8(env, ToMessage(Convert(code)).c_str(), NAPI_AUTO_LENGTH, &errorMessage));
122     NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode));
123     NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage));
124     IMSA_HILOGD("ToError end");
125     return errorObj;
126 }
127 
Convert(int32_t code)128 int32_t JsUtils::Convert(int32_t code)
129 {
130     IMSA_HILOGD("Convert start");
131     auto iter = ERROR_CODE_MAP.find(code);
132     if (iter != ERROR_CODE_MAP.end()) {
133         IMSA_HILOGE("ErrorCode: %{public}d", iter->second);
134         return iter->second;
135     }
136     IMSA_HILOGD("Convert end");
137     return ERROR_CODE_QUERY_FAILED;
138 }
139 
ToMessage(int32_t code)140 const std::string JsUtils::ToMessage(int32_t code)
141 {
142     IMSA_HILOGD("ToMessage start");
143     auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
144     if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
145         IMSA_HILOGI("ErrorMessage: %{public}s", (iter->second).c_str());
146         return iter->second;
147     }
148     return "error is out of definition.";
149 }
150 
Equals(napi_env env,napi_value value,napi_ref copy,std::thread::id threadId)151 bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
152 {
153     if (copy == nullptr) {
154         return value == nullptr;
155     }
156 
157     if (threadId != std::this_thread::get_id()) {
158         IMSA_HILOGD("napi_value can not be compared");
159         return false;
160     }
161 
162     napi_value copyValue = nullptr;
163     napi_get_reference_value(env, copy, &copyValue);
164 
165     bool isEquals = false;
166     napi_strict_equals(env, value, copyValue, &isEquals);
167     IMSA_HILOGD("value compare result: %{public}d", isEquals);
168     return isEquals;
169 }
170 
GetNativeSelf(napi_env env,napi_callback_info info)171 void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info)
172 {
173     size_t argc = ARGC_MAX;
174     void *native = nullptr;
175     napi_value self = nullptr;
176     napi_value argv[ARGC_MAX] = { nullptr };
177     napi_status status = napi_invalid_arg;
178     napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
179     CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr);
180 
181     status = napi_unwrap(env, self, &native);
182     CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr);
183     return native;
184 }
185 
GetValue(napi_env env,napi_value in,int32_t & out)186 napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out)
187 {
188     napi_valuetype type = napi_undefined;
189     napi_status status = napi_typeof(env, in, &type);
190     CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure);
191     return napi_get_value_int32(env, in, &out);
192 }
193 
194 /* napi_value <-> uint32_t */
GetValue(napi_env env,napi_value in,uint32_t & out)195 napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out)
196 {
197     napi_valuetype type = napi_undefined;
198     napi_status status = napi_typeof(env, in, &type);
199     CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure);
200     return napi_get_value_uint32(env, in, &out);
201 }
202 
GetValue(napi_env env,napi_value in,bool & out)203 napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out)
204 {
205     napi_valuetype type = napi_undefined;
206     napi_status status = napi_typeof(env, in, &type);
207     CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure);
208     return napi_get_value_bool(env, in, &out);
209 }
210 
GetValue(napi_env env,napi_value in,double & out)211 napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out)
212 {
213     napi_valuetype type = napi_undefined;
214     napi_status status = napi_typeof(env, in, &type);
215     CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure);
216     return napi_get_value_double(env, in, &out);
217 }
218 
219 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)220 napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out)
221 {
222     IMSA_HILOGD("JsUtils get string value in.");
223     napi_valuetype type = napi_undefined;
224     napi_status status = napi_typeof(env, in, &type);
225     CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure);
226 
227     size_t maxLen = STR_MAX_LENGTH;
228     status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
229     if (maxLen <= 0) {
230         return status;
231     }
232     IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen);
233     char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
234     if (buf != nullptr) {
235         size_t len = 0;
236         status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
237         if (status == napi_ok) {
238             buf[len] = 0;
239             out = std::string(buf);
240         }
241         delete[] buf;
242     } else {
243         status = napi_generic_failure;
244     }
245     return status;
246 }
247 
GetValue(napi_env env,napi_value in,const std::string & type,napi_value & out)248 napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out)
249 {
250     napi_valuetype valueType = napi_undefined;
251     napi_status status = napi_typeof(env, in, &valueType);
252     if ((status == napi_ok) && (valueType == napi_object)) {
253         status = napi_get_named_property(env, in, type.c_str(), &out);
254         return status;
255     }
256     return napi_generic_failure;
257 }
258 
259 /* napi_value <-> PanelInfo */
GetValue(napi_env env,napi_value in,PanelInfo & out)260 napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out)
261 {
262     IMSA_HILOGD("napi_value -> PanelInfo ");
263     napi_value propType = nullptr;
264     napi_status status = napi_get_named_property(env, in, "type", &propType);
265     CHECK_RETURN((status == napi_ok), "no property type ", status);
266     int32_t panelType = 0;
267     status = GetValue(env, propType, panelType);
268     CHECK_RETURN((status == napi_ok), "no value of type ", status);
269 
270     // PanelFlag is optional, defaults to FLG_FIXED when empty.
271     int32_t panelFlag = static_cast<int32_t>(PanelFlag::FLG_FIXED);
272     napi_value panelFlagObj = nullptr;
273     status = napi_get_named_property(env, in, "flag", &panelFlagObj);
274     if (status == napi_ok) {
275         JsUtils::GetValue(env, panelFlagObj, panelFlag);
276     }
277 
278     out.panelType = PanelType(panelType);
279     out.panelFlag = PanelFlag(panelFlag);
280     return napi_ok;
281 }
282 
GetValue(napi_env env,const std::vector<InputWindowInfo> & in)283 napi_value JsUtils::GetValue(napi_env env, const std::vector<InputWindowInfo> &in)
284 {
285     napi_value array = nullptr;
286     uint32_t index = 0;
287     napi_create_array(env, &array);
288     if (array == nullptr) {
289         IMSA_HILOGE("create array failed");
290         return array;
291     }
292     for (const auto &info : in) {
293         napi_value jsInfo = GetValue(env, info);
294         napi_set_element(env, array, index, jsInfo);
295         ++index;
296     }
297     return array;
298 }
299 
GetValue(napi_env env,const InputWindowInfo & in)300 napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in)
301 {
302     napi_value info = nullptr;
303     napi_create_object(env, &info);
304 
305     napi_value name = nullptr;
306     napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name);
307     napi_set_named_property(env, info, "name", name);
308 
309     napi_value left = nullptr;
310     napi_create_int32(env, in.left, &left);
311     napi_set_named_property(env, info, "left", left);
312 
313     napi_value top = nullptr;
314     napi_create_int32(env, in.top, &top);
315     napi_set_named_property(env, info, "top", top);
316 
317     napi_value width = nullptr;
318     napi_create_uint32(env, in.width, &width);
319     napi_set_named_property(env, info, "width", width);
320 
321     napi_value height = nullptr;
322     napi_create_uint32(env, in.height, &height);
323     napi_set_named_property(env, info, "height", height);
324 
325     return info;
326 }
327 
GetValue(napi_env env,const InputAttribute & attribute)328 napi_value JsUtils::GetValue(napi_env env, const InputAttribute &attribute)
329 {
330     napi_value editorAttribute = nullptr;
331     napi_create_object(env, &editorAttribute);
332 
333     auto ret = JsUtil::Object::WriteProperty(env, editorAttribute, "inputPattern", attribute.inputPattern);
334     ret = ret && JsUtil::Object::WriteProperty(env, editorAttribute, "enterKeyType", attribute.enterKeyType);
335     return ret ? editorAttribute : JsUtil::Const::Null(env);
336 }
337 
GetValue(napi_env env,const std::string & in,napi_value & out)338 napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out)
339 {
340     return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
341 }
342 } // namespace MiscServices
343 } // namespace OHOS
344