1 /*
2 * Copyright (c) 2022-2022 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 namespace OHOS {
19 namespace MiscServices {
20 const std::map<int32_t, int32_t> JsUtils::ERROR_CODE_MAP = {
21 { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER},
22 { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION },
23 { ErrorCode::ERROR_REMOTE_IME_DIED, EXCEPTION_IMENGINE },
24 { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT },
25 { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT },
26 { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT },
27 { ErrorCode::ERROR_NOT_IME_PACKAGE, EXCEPTION_SETTINGS },
28 { ErrorCode::ERROR_IME_PACKAGE_DUPLICATED, EXCEPTION_SETTINGS },
29 { ErrorCode::ERROR_SETTING_SAME_VALUE, EXCEPTION_SETTINGS },
30 { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS },
31 { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS },
32 { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS },
33 { ErrorCode::ERROR_USER_NOT_STARTED, EXCEPTION_IMMS },
34 { ErrorCode::ERROR_USER_ALREADY_STARTED, EXCEPTION_IMMS },
35 { ErrorCode::ERROR_USER_NOT_UNLOCKED, EXCEPTION_IMMS },
36 { ErrorCode::ERROR_USER_NOT_LOCKED, EXCEPTION_IMMS },
37 { ErrorCode::ERROR_IME_NOT_AVAILABLE, EXCEPTION_IMMS },
38 { ErrorCode::ERROR_SECURITY_IME_NOT_AVAILABLE, EXCEPTION_IMMS },
39 { ErrorCode::ERROR_TOKEN_CREATE_FAILED, EXCEPTION_IMMS },
40 { ErrorCode::ERROR_TOKEN_DESTROY_FAILED, EXCEPTION_IMMS },
41 { ErrorCode::ERROR_IME_BIND_FAILED, EXCEPTION_IMMS },
42 { ErrorCode::ERROR_IME_UNBIND_FAILED, EXCEPTION_IMMS },
43 { ErrorCode::ERROR_IME_START_FAILED, EXCEPTION_IMMS },
44 { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS },
45 { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS },
46 { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS },
47 { ErrorCode::ERROR_KBD_IS_OCCUPIED, EXCEPTION_IMMS },
48 { ErrorCode::ERROR_KBD_IS_NOT_SHOWING, EXCEPTION_IMMS },
49 { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS },
50 { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST },
51 { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER },
52 { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS },
53 { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS },
54 { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS },
55 { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS },
56 { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS },
57 { ErrorCode::ERROR_EX_NETWORK_MAIN_THREAD, EXCEPTION_IMMS },
58 { ErrorCode::ERROR_STATUS_UNKNOWN_ERROR, EXCEPTION_OTHERS },
59 { ErrorCode::ERROR_STATUS_NO_MEMORY, EXCEPTION_OTHERS },
60 { ErrorCode::ERROR_STATUS_INVALID_OPERATION, EXCEPTION_OTHERS },
61 { ErrorCode::ERROR_STATUS_BAD_VALUE, EXCEPTION_OTHERS },
62 { ErrorCode::ERROR_STATUS_BAD_TYPE, EXCEPTION_OTHERS },
63 { ErrorCode::ERROR_STATUS_NAME_NOT_FOUND, EXCEPTION_OTHERS },
64 { ErrorCode::ERROR_STATUS_ALREADY_EXISTS, EXCEPTION_OTHERS },
65 { ErrorCode::ERROR_STATUS_DEAD_OBJECT, EXCEPTION_OTHERS },
66 { ErrorCode::ERROR_STATUS_FAILED_TRANSACTION, EXCEPTION_OTHERS },
67 { ErrorCode::ERROR_STATUS_BAD_INDEX, EXCEPTION_OTHERS },
68 { ErrorCode::ERROR_STATUS_NOT_ENOUGH_DATA, EXCEPTION_OTHERS },
69 { ErrorCode::ERROR_STATUS_WOULD_BLOCK, EXCEPTION_OTHERS },
70 { ErrorCode::ERROR_STATUS_TIMED_OUT, EXCEPTION_OTHERS },
71 { ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION, EXCEPTION_OTHERS },
72 { ErrorCode::ERROR_STATUS_FDS_NOT_ALLOWED, EXCEPTION_OTHERS },
73 { ErrorCode::ERROR_STATUS_UNEXPECTED_NULL, EXCEPTION_OTHERS },
74 };
75
76 const std::map<int32_t, std::string> JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = {
77 { EXCEPTION_PERMISSION, "the permissions check fails." },
78 { EXCEPTION_PARAMCHECK, "the parameters check fails." },
79 { EXCEPTION_UNSUPPORTED, "call unsupported api." },
80 { EXCEPTION_PACKAGEMANAGER, "package manager error." },
81 { EXCEPTION_IMENGINE, "input method engine error." },
82 { EXCEPTION_IMCLIENT, "input method client error." },
83 { EXCEPTION_KEYEVENT, "key event processing error." },
84 { EXCEPTION_CONFPERSIST, "configuration persisting error." },
85 { EXCEPTION_CONTROLLER, "input method controller error." },
86 { EXCEPTION_SETTINGS, "input method settings extension error." },
87 { EXCEPTION_IMMS, "input method manager service error." },
88 { EXCEPTION_OTHERS, "others error." },
89 };
90
91 const std::map<int32_t, std::string> JsUtils::PARAMETER_TYPE = {
92 { TYPE_UNDEFINED, "napi_undefine." },
93 { TYPE_NULL, "napi_null." },
94 { TYPE_BOOLEAN, "napi_boolean." },
95 { TYPE_NUMBER, "napi_number." },
96 { TYPE_STRING, "napi_string." },
97 { TYPE_SYMBOL, "napi_symbol." },
98 { TYPE_OBJECT, "napi_object." },
99 { TYPE_FUNCTION, "napi_function." },
100 { TYPE_EXTERNAL, "napi_external." },
101 { TYPE_BIGINT, "napi_bigint." },
102 };
103
ThrowException(napi_env env,int32_t err,const std::string & msg,TypeCode type)104 void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type)
105 {
106 std::string errMsg = ToMessage(err);
107 napi_value error;
108 napi_value code;
109 napi_value message;
110 if (type == TypeCode::TYPE_NONE) {
111 errMsg = errMsg + msg;
112 IMSA_HILOGE("THROW_PARAMTER_ERROR message: %{public}s", errMsg.c_str());
113 } else {
114 auto iter = PARAMETER_TYPE.find(type);
115 if (iter != PARAMETER_TYPE.end()) {
116 errMsg = errMsg + "The type of " + msg + " must be " + iter->second;
117 IMSA_HILOGE("THROW_PARAMTER_TYPE_ERROR message: %{public}s", errMsg.c_str());
118 }
119 }
120 NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
121 NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error));
122 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code));
123 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code));
124 NAPI_CALL_RETURN_VOID(env, napi_throw(env, error));
125 }
126
ToError(napi_env env,int32_t code)127 napi_value JsUtils::ToError(napi_env env, int32_t code)
128 {
129 IMSA_HILOGE("ToError start");
130 napi_value errorObj;
131 NAPI_CALL(env, napi_create_object(env, &errorObj));
132 napi_value errorCode = nullptr;
133 NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode));
134 napi_value errorMessage = nullptr;
135 NAPI_CALL(env, napi_create_string_utf8(env, ToMessage(Convert(code)).c_str(), NAPI_AUTO_LENGTH, &errorMessage));
136 NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode));
137 NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage));
138 IMSA_HILOGE("ToError end");
139 return errorObj;
140 }
141
Convert(int32_t code)142 int32_t JsUtils::Convert(int32_t code)
143 {
144 IMSA_HILOGI("Convert start");
145 auto iter = ERROR_CODE_MAP.find(code);
146 if (iter != ERROR_CODE_MAP.end()) {
147 IMSA_HILOGE("ErrorCode: %{public}d", iter->second);
148 return iter->second;
149 }
150 IMSA_HILOGI("Convert end");
151 return ERROR_CODE_QUERY_FAILED;
152 }
153
ToMessage(int32_t code)154 const std::string JsUtils::ToMessage(int32_t code)
155 {
156 IMSA_HILOGI("ToMessage start");
157 auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
158 if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
159 IMSA_HILOGI("ErrorMessage: %{public}s", (iter->second).c_str());
160 return iter->second;
161 }
162 return "error is out of definition.";
163 }
164
TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObject>> & vecCopy,size_t paramNum,ArgsProvider argsProvider)165 bool JsUtils::TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObject>> &vecCopy, size_t paramNum,
166 ArgsProvider argsProvider)
167 {
168 bool isResult = false;
169 bool isOnKeyEvent = false;
170 for (const auto &item : vecCopy) {
171 napi_handle_scope scope = nullptr;
172 napi_open_handle_scope(item->env_, &scope);
173 if (item->threadId_ != std::this_thread::get_id()) {
174 napi_close_handle_scope(item->env_, scope);
175 continue;
176 }
177 napi_value args[MAX_ARGMENT_COUNT];
178 if (!argsProvider(args, MAX_ARGMENT_COUNT, item)) {
179 napi_close_handle_scope(item->env_, scope);
180 continue;
181 }
182 napi_value callback = nullptr;
183 napi_value global = nullptr;
184 napi_value result = nullptr;
185 napi_get_reference_value(item->env_, item->callback_, &callback);
186 if (callback != nullptr) {
187 IMSA_HILOGD("callback is not nullptr");
188 napi_get_global(item->env_, &global);
189 napi_status callStatus = napi_call_function(item->env_, global, callback, paramNum, args, &result);
190 if (callStatus != napi_ok) {
191 IMSA_HILOGE("notify data change failed callStatus:%{public}d", callStatus);
192 result = nullptr;
193 }
194 }
195 if (result != nullptr && !isOnKeyEvent) {
196 napi_valuetype valueType = napi_undefined;
197 napi_typeof(item->env_, result, &valueType);
198 if (valueType != napi_boolean) {
199 continue;
200 }
201 napi_get_value_bool(item->env_, result, &isResult);
202 if (isResult) {
203 isOnKeyEvent = true;
204 }
205 }
206 napi_close_handle_scope(item->env_, scope);
207 }
208 return isOnKeyEvent;
209 }
210 } // namespace MiscServices
211 } // namespace OHOS