1 /*
2 * Copyright (c) 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_short_key_context.h"
17
18 #undef MMI_LOG_TAG
19 #define MMI_LOG_TAG "JsShortKeyContext"
20
21 namespace OHOS {
22 namespace MMI {
23 namespace {
24 constexpr int32_t MAX_DELAY { 4000 };
25 constexpr int32_t MIN_DELAY { 0 };
26 const std::string SHORT_KEY_CLASS { "multimodalinput_short_key_class" };
27 const std::string SHORT_KEY_INSTANCE { "multimodalinput_short_key" };
28
29 enum class FingerprintAction : int32_t {
30 DOWN = 0,
31 UP = 1,
32 SLIDE = 2,
33 RETOUCH = 3,
34 CLICK = 4,
35 CANCEL = 5,
36 };
37
38 enum class XKeyAction : int32_t {
39 X_KEY_DOWN = 0,
40 X_KEY_UP = 1,
41 SINGLE_CLICK = 2,
42 DOUBLE_CLICK = 3,
43 LONG_PRESS = 4,
44 };
45 } // namespace
46
JsShortKeyContext()47 JsShortKeyContext::JsShortKeyContext() : mgr_(std::make_shared<JsShortKeyManager>()) {}
48
CreateInstance(napi_env env)49 napi_value JsShortKeyContext::CreateInstance(napi_env env)
50 {
51 CALL_DEBUG_ENTER;
52 napi_value global = nullptr;
53 CHKRP(napi_get_global(env, &global), GET_GLOBAL);
54
55 constexpr char className[] = "JsShortKeyContext";
56 napi_value jsClass = nullptr;
57 napi_property_descriptor desc[] = {};
58 napi_status status = napi_define_class(env, className, sizeof(className), JsShortKeyContext::CreateJsObject,
59 nullptr, sizeof(desc) / sizeof(desc[0]), nullptr, &jsClass);
60 CHKRP(status, DEFINE_CLASS);
61
62 status = napi_set_named_property(env, global, SHORT_KEY_CLASS.c_str(), jsClass);
63 CHKRP(status, SET_NAMED_PROPERTY);
64
65 napi_value jsInstance = nullptr;
66 CHKRP(napi_new_instance(env, jsClass, 0, nullptr, &jsInstance), NEW_INSTANCE);
67 CHKRP(napi_set_named_property(env, global, SHORT_KEY_INSTANCE.c_str(), jsInstance), SET_NAMED_PROPERTY);
68
69 JsShortKeyContext *jsContext = nullptr;
70 CHKRP(napi_unwrap(env, jsInstance, (void**)&jsContext), UNWRAP);
71 CHKPP(jsContext);
72 CHKRP(napi_create_reference(env, jsInstance, 1, &(jsContext->contextRef_)), CREATE_REFERENCE);
73
74 uint32_t refCount = 0;
75 if (napi_reference_ref(env, jsContext->contextRef_, &refCount) != napi_ok) {
76 CHKRP(napi_delete_reference(env, jsContext->contextRef_), DELETE_REFERENCE);
77 return nullptr;
78 }
79 return jsInstance;
80 }
81
CreateJsObject(napi_env env,napi_callback_info info)82 napi_value JsShortKeyContext::CreateJsObject(napi_env env, napi_callback_info info)
83 {
84 CALL_DEBUG_ENTER;
85 napi_value thisVar = nullptr;
86 void *data = nullptr;
87 CHKRP(napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data), GET_CB_INFO);
88
89 JsShortKeyContext *jsContext = new (std::nothrow) JsShortKeyContext();
90 CHKPP(jsContext);
91 napi_status status = napi_wrap(env, thisVar, jsContext, [](napi_env env, void* data, void* hin) {
92 MMI_HILOGI("jsvm ends");
93 JsShortKeyContext *context = static_cast<JsShortKeyContext*>(data);
94 delete context;
95 context = nullptr;
96 }, nullptr, nullptr);
97 if (status != napi_ok) {
98 delete jsContext;
99 jsContext = nullptr;
100 THROWERR(env, "Failed to wrap native instance");
101 return nullptr;
102 }
103 return thisVar;
104 }
105
GetInstance(napi_env env)106 JsShortKeyContext* JsShortKeyContext::GetInstance(napi_env env)
107 {
108 CALL_DEBUG_ENTER;
109 napi_value global = nullptr;
110 CHKRP(napi_get_global(env, &global), GET_GLOBAL);
111
112 bool result = false;
113 CHKRP(napi_has_named_property(env, global, SHORT_KEY_INSTANCE.c_str(), &result), HAS_NAMED_PROPERTY);
114 if (!result) {
115 THROWERR(env, "multimodal_short_key was not found");
116 return nullptr;
117 }
118
119 napi_value object = nullptr;
120 CHKRP(napi_get_named_property(env, global, SHORT_KEY_INSTANCE.c_str(), &object), SET_NAMED_PROPERTY);
121 if (object == nullptr) {
122 THROWERR(env, "Object is nullptr");
123 return nullptr;
124 }
125
126 JsShortKeyContext *instance = nullptr;
127 CHKRP(napi_unwrap(env, object, (void**)&instance), UNWRAP);
128 if (instance == nullptr) {
129 THROWERR(env, "Instance is nullptr");
130 return nullptr;
131 }
132 return instance;
133 }
134
GetJsShortKeyMgr() const135 std::shared_ptr<JsShortKeyManager> JsShortKeyContext::GetJsShortKeyMgr() const
136 {
137 return mgr_;
138 }
139
SetKeyDownDuration(napi_env env,napi_callback_info info)140 napi_value JsShortKeyContext::SetKeyDownDuration(napi_env env, napi_callback_info info)
141 {
142 CALL_DEBUG_ENTER;
143 size_t argc = 3;
144 napi_value argv[3];
145 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
146 size_t paramsNum = 2;
147 if (argc < paramsNum) {
148 MMI_HILOGE("At least 2 parameter is required");
149 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "businessId", "string");
150 return nullptr;
151 }
152 if (!JsCommon::TypeOf(env, argv[0], napi_string)) {
153 MMI_HILOGE("businessId parameter type is invalid");
154 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "businessId", "string");
155 return nullptr;
156 }
157
158 char businessId[MAX_STRING_LEN] = { 0 };
159 size_t ret = 0;
160 CHKRP(napi_get_value_string_utf8(env, argv[0], businessId, MAX_STRING_LEN - 1, &ret), GET_VALUE_STRING_UTF8);
161 if (ret <= 0) {
162 MMI_HILOGE("Invalid businessId");
163 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "businessId is invalid");
164 return nullptr;
165 }
166
167 int32_t delay = 0;
168 CHKRP(napi_get_value_int32(env, argv[1], &delay), GET_VALUE_INT32);
169 if (delay < MIN_DELAY || delay > MAX_DELAY) {
170 MMI_HILOGE("Invalid delay");
171 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Delay is invalid");
172 return nullptr;
173 }
174 if (!JsCommon::TypeOf(env, argv[1], napi_number)) {
175 MMI_HILOGE("Delay parameter type is invalid");
176 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "delay", "number");
177 return nullptr;
178 }
179 JsShortKeyContext *jsShortKey = JsShortKeyContext::GetInstance(env);
180 CHKPP(jsShortKey);
181 auto jsShortKeyMgr = jsShortKey->GetJsShortKeyMgr();
182 if (argc == paramsNum) {
183 return jsShortKeyMgr->SetKeyDownDuration(env, businessId, delay);
184 }
185 if (!JsCommon::TypeOf(env, argv[paramsNum], napi_function)) {
186 MMI_HILOGE("Callback parameter type is invalid");
187 THROWERR_API9(env, COMMON_PARAMETER_ERROR, "callback", "function");
188 return nullptr;
189 }
190 return jsShortKeyMgr->SetKeyDownDuration(env, businessId, delay, argv[paramsNum]);
191 }
192
GetNapiInt32(napi_env env,int32_t code)193 napi_value JsShortKeyContext::GetNapiInt32(napi_env env, int32_t code)
194 {
195 CALL_DEBUG_ENTER;
196 napi_value ret = nullptr;
197 CHKRP(napi_create_int32(env, code, &ret), CREATE_INT32);
198 return ret;
199 }
200
EnumClassConstructor(napi_env env,napi_callback_info info)201 napi_value JsShortKeyContext::EnumClassConstructor(napi_env env, napi_callback_info info)
202 {
203 CALL_DEBUG_ENTER;
204 size_t argc = 0;
205 napi_value args[1] = { 0 };
206 napi_value ret = nullptr;
207 void *data = nullptr;
208 CHKRP(napi_get_cb_info(env, info, &argc, args, &ret, &data), GET_CB_INFO);
209 return ret;
210 }
211
Export(napi_env env,napi_value exports)212 napi_value JsShortKeyContext::Export(napi_env env, napi_value exports)
213 {
214 CALL_DEBUG_ENTER;
215 auto instance = CreateInstance(env);
216 if (instance == nullptr) {
217 THROWERR(env, "Failed to create instance");
218 return nullptr;
219 }
220 napi_property_descriptor desc[] = {
221 DECLARE_NAPI_STATIC_FUNCTION("setKeyDownDuration", SetKeyDownDuration),
222 };
223 CHKRP(napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc), DEFINE_PROPERTIES);
224
225 napi_property_descriptor fingerprintActionArr[] = {
226 DECLARE_NAPI_STATIC_PROPERTY("DOWN", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::DOWN))),
227 DECLARE_NAPI_STATIC_PROPERTY("UP", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::UP))),
228 DECLARE_NAPI_STATIC_PROPERTY("SLIDE", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::SLIDE))),
229 DECLARE_NAPI_STATIC_PROPERTY("RETOUCH", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::RETOUCH))),
230 DECLARE_NAPI_STATIC_PROPERTY("CLICK", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::CLICK))),
231 DECLARE_NAPI_STATIC_PROPERTY("CANCEL", GetNapiInt32(env, static_cast<int32_t>(FingerprintAction::CANCEL))),
232 };
233 napi_value fingerprintAction = nullptr;
234 CHKRP(napi_define_class(env, "FingerprintAction", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
235 sizeof(fingerprintActionArr) / sizeof(*fingerprintActionArr), fingerprintActionArr, &fingerprintAction),
236 DEFINE_CLASS);
237 CHKRP(napi_set_named_property(env, exports, "FingerprintAction", fingerprintAction), SET_NAMED_PROPERTY);
238
239 napi_property_descriptor xKeyActionArr[] = {
240 DECLARE_NAPI_STATIC_PROPERTY("X_KEY_DOWN", GetNapiInt32(env, static_cast<int32_t>(XKeyAction::X_KEY_DOWN))),
241 DECLARE_NAPI_STATIC_PROPERTY("X_KEY_UP", GetNapiInt32(env, static_cast<int32_t>(XKeyAction::X_KEY_UP))),
242 DECLARE_NAPI_STATIC_PROPERTY("SINGLE_CLICK", GetNapiInt32(env, static_cast<int32_t>(XKeyAction::SINGLE_CLICK))),
243 DECLARE_NAPI_STATIC_PROPERTY("DOUBLE_CLICK", GetNapiInt32(env, static_cast<int32_t>(XKeyAction::DOUBLE_CLICK))),
244 DECLARE_NAPI_STATIC_PROPERTY("LONG_PRESS", GetNapiInt32(env, static_cast<int32_t>(XKeyAction::LONG_PRESS))),
245 };
246 napi_value xKeyAction = nullptr;
247 CHKRP(napi_define_class(env, "XKeyAction", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
248 sizeof(xKeyActionArr) / sizeof(*xKeyActionArr), xKeyActionArr, &xKeyAction),
249 DEFINE_CLASS);
250 CHKRP(napi_set_named_property(env, exports, "XKeyAction", xKeyAction), SET_NAMED_PROPERTY);
251 return exports;
252 }
253 } // namespace MMI
254 } // namespace OHOS
255