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