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