1 /*
2 * Copyright (c) 2021-2025 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_input_monitor.h"
17
18 #include "define_multimodal.h"
19 #include "input_manager.h"
20 #include "js_input_monitor_manager.h"
21 #include "js_gesture_event.h"
22 #include "napi_constants.h"
23 #include "util_napi_error.h"
24 #include "util_napi_value.h"
25
26 #undef MMI_LOG_TAG
27 #define MMI_LOG_TAG "JsInputMonitor"
28
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 constexpr int32_t AXIS_TYPE_SCROLL_VERTICAL { 0 };
33 constexpr int32_t AXIS_TYPE_SCROLL_HORIZONTAL { 1 };
34 constexpr int32_t AXIS_TYPE_PINCH { 2 };
35 constexpr int32_t NAPI_ERR { 3 };
36 constexpr int32_t CANCEL { 0 };
37 constexpr int32_t MOVE { 1 };
38 constexpr int32_t BUTTON_DOWN { 2 };
39 constexpr int32_t BUTTON_UP { 3 };
40 constexpr int32_t AXIS_BEGIN { 4 };
41 constexpr int32_t AXIS_UPDATE { 5 };
42 constexpr int32_t AXIS_END { 6 };
43 constexpr int32_t MIDDLE { 1 };
44 constexpr int32_t RIGHT { 2 };
45 constexpr int32_t MOUSE_FLOW { 10 };
46 constexpr int32_t ONE_FINGERS { 1 };
47 constexpr int32_t THREE_FINGERS { 3 };
48 constexpr int32_t INJECTION_EVENT_FLAG { 10000 };
49 constexpr int32_t FOUR_FINGERS { 4 };
50 constexpr int32_t GESTURE_BEGIN { 1 };
51 constexpr int32_t GESTURE_UPDATE { 2 };
52 constexpr int32_t GESTURE_END { 3 };
53 const std::string INVALID_TYPE_NAME { "" };
54 #ifdef OHOS_BUILD_ENABLE_FINGERPRINT
55 constexpr int32_t FINGERPRINT_DOWN { 0 };
56 constexpr int32_t FINGERPRINT_UP { 1 };
57 constexpr int32_t FINGERPRINT_SLIDE { 2 };
58 constexpr int32_t FINGERPRINT_RETOUCH { 3 };
59 constexpr int32_t FINGERPRINT_CLICK { 4 };
60 constexpr int32_t FINGERPRINT_CANCEL { 5 };
61 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
62
63 enum TypeName : int32_t {
64 TOUCH = 0,
65 MOUSE = 1,
66 PINCH = 2,
67 THREE_FINGERS_SWIPE = 3,
68 FOUR_FINGERS_SWIPE = 4,
69 ROTATE = 5,
70 THREE_FINGERS_TAP = 6,
71 JOYSTICK = 7,
72 FINGERPRINT = 8,
73 SWIPE_INWARD = 9,
74 TOUCH_GESTURE = 10,
75 PRE_KEY = 11
76 };
77
78 enum InputKeyEventAction {
79 /** Cancellation of a key action. */
80 KEY_ACTION_CANCEL = 0,
81 /** Pressing of a key. */
82 KEY_ACTION_DOWN = 1,
83 /** Release of a key. */
84 KEY_ACTION_UP = 2,
85 };
86
87 std::map<std::string, int32_t> TO_MONITOR_TYPE = {
88 { "touch", TOUCH },
89 { "mouse", MOUSE },
90 { "pinch", PINCH },
91 { "threeFingersSwipe", THREE_FINGERS_SWIPE },
92 { "fourFingersSwipe", FOUR_FINGERS_SWIPE },
93 { "rotate", ROTATE },
94 { "threeFingersTap", THREE_FINGERS_TAP },
95 { "joystick", JOYSTICK },
96 { "fingerprint", FINGERPRINT },
97 { "swipeInward", SWIPE_INWARD },
98 { TOUCH_SWIPE_GESTURE, TOUCH_GESTURE },
99 { TOUCH_PINCH_GESTURE, TOUCH_GESTURE },
100 { TOUCH_ALL_GESTURE, TOUCH_GESTURE },
101 };
102
103 std::map<std::string, int32_t> TO_PRE_MONITOR_TYPE = {
104 { "keyPressed", PRE_KEY },
105 };
106
107 struct MonitorInfo {
108 int32_t monitorId;
109 int32_t fingers;
110 };
111
112 std::map<JsJoystickEvent::Axis, PointerEvent::AxisType> g_joystickAxisType = {
113 { JsJoystickEvent::Axis::ABS_X, PointerEvent::AXIS_TYPE_ABS_X },
114 { JsJoystickEvent::Axis::ABS_Y, PointerEvent::AXIS_TYPE_ABS_Y },
115 { JsJoystickEvent::Axis::ABS_Z, PointerEvent::AXIS_TYPE_ABS_Z },
116 { JsJoystickEvent::Axis::ABS_RZ, PointerEvent::AXIS_TYPE_ABS_RZ },
117 { JsJoystickEvent::Axis::ABS_GAS, PointerEvent::AXIS_TYPE_ABS_GAS },
118 { JsJoystickEvent::Axis::ABS_BRAKE, PointerEvent::AXIS_TYPE_ABS_BRAKE },
119 { JsJoystickEvent::Axis::ABS_HAT0X, PointerEvent::AXIS_TYPE_ABS_HAT0X },
120 { JsJoystickEvent::Axis::ABS_HAT0Y, PointerEvent::AXIS_TYPE_ABS_HAT0Y },
121 { JsJoystickEvent::Axis::ABS_THROTTLE, PointerEvent::AXIS_TYPE_ABS_THROTTLE }
122 };
123
124 std::map<JsJoystickEvent::Button, int32_t> g_joystickButtonType = {
125 { JsJoystickEvent::Button::BUTTON_TL2, PointerEvent::JOYSTICK_BUTTON_TL2 },
126 { JsJoystickEvent::Button::BUTTON_TR2, PointerEvent::JOYSTICK_BUTTON_TR2 },
127 { JsJoystickEvent::Button::BUTTON_TL, PointerEvent::JOYSTICK_BUTTON_TL },
128 { JsJoystickEvent::Button::BUTTON_TR, PointerEvent::JOYSTICK_BUTTON_TR },
129 { JsJoystickEvent::Button::BUTTON_WEST, PointerEvent::JOYSTICK_BUTTON_WEST },
130 { JsJoystickEvent::Button::BUTTON_SOUTH, PointerEvent::JOYSTICK_BUTTON_SOUTH },
131 { JsJoystickEvent::Button::BUTTON_NORTH, PointerEvent::JOYSTICK_BUTTON_NORTH },
132 { JsJoystickEvent::Button::BUTTON_EAST, PointerEvent::JOYSTICK_BUTTON_EAST },
133 { JsJoystickEvent::Button::BUTTON_START, PointerEvent::JOYSTICK_BUTTON_START },
134 { JsJoystickEvent::Button::BUTTON_SELECT, PointerEvent::JOYSTICK_BUTTON_SELECT },
135 { JsJoystickEvent::Button::BUTTON_HOMEPAGE, PointerEvent::JOYSTICK_BUTTON_HOMEPAGE },
136 { JsJoystickEvent::Button::BUTTON_THUMBL, PointerEvent::JOYSTICK_BUTTON_THUMBL },
137 { JsJoystickEvent::Button::BUTTON_THUMBR, PointerEvent::JOYSTICK_BUTTON_THUMBR },
138 { JsJoystickEvent::Button::BUTTON_TRIGGER, PointerEvent::JOYSTICK_BUTTON_TRIGGER },
139 { JsJoystickEvent::Button::BUTTON_THUMB, PointerEvent::JOYSTICK_BUTTON_THUMB },
140 { JsJoystickEvent::Button::BUTTON_THUMB2, PointerEvent::JOYSTICK_BUTTON_THUMB2 },
141 { JsJoystickEvent::Button::BUTTON_TOP, PointerEvent::JOYSTICK_BUTTON_TOP },
142 { JsJoystickEvent::Button::BUTTON_TOP2, PointerEvent::JOYSTICK_BUTTON_TOP2 },
143 { JsJoystickEvent::Button::BUTTON_PINKIE, PointerEvent::JOYSTICK_BUTTON_PINKIE },
144 { JsJoystickEvent::Button::BUTTON_BASE, PointerEvent::JOYSTICK_BUTTON_BASE },
145 { JsJoystickEvent::Button::BUTTON_BASE2, PointerEvent::JOYSTICK_BUTTON_BASE2 },
146 { JsJoystickEvent::Button::BUTTON_BASE3, PointerEvent::JOYSTICK_BUTTON_BASE3 },
147 { JsJoystickEvent::Button::BUTTON_BASE4, PointerEvent::JOYSTICK_BUTTON_BASE4 },
148 { JsJoystickEvent::Button::BUTTON_BASE5, PointerEvent::JOYSTICK_BUTTON_BASE5 },
149 { JsJoystickEvent::Button::BUTTON_BASE6, PointerEvent::JOYSTICK_BUTTON_BASE6 },
150 { JsJoystickEvent::Button::BUTTON_DEAD, PointerEvent::JOYSTICK_BUTTON_DEAD },
151 { JsJoystickEvent::Button::BUTTON_C, PointerEvent::JOYSTICK_BUTTON_C },
152 { JsJoystickEvent::Button::BUTTON_Z, PointerEvent::JOYSTICK_BUTTON_Z },
153 { JsJoystickEvent::Button::BUTTON_MODE, PointerEvent::JOYSTICK_BUTTON_MODE }
154 };
155
156 std::map<std::string, TouchGestureType> TO_GESTURE_TYPE = {
157 { TOUCH_PINCH_GESTURE, TOUCH_GESTURE_TYPE_PINCH },
158 { TOUCH_SWIPE_GESTURE, TOUCH_GESTURE_TYPE_SWIPE },
159 { TOUCH_ALL_GESTURE, TOUCH_GESTURE_TYPE_ALL },
160 };
161
CleanData(MonitorInfo ** monitorInfo,uv_work_t ** work)162 void CleanData(MonitorInfo** monitorInfo, uv_work_t** work)
163 {
164 if (*monitorInfo != nullptr) {
165 delete *monitorInfo;
166 *monitorInfo = nullptr;
167 }
168 if (*work != nullptr) {
169 delete *work;
170 *work = nullptr;
171 }
172 }
173
174 std::map<std::string, int32_t> TO_HANDLE_EVENT_TYPE = {
175 { "none", HANDLE_EVENT_TYPE_NONE },
176 { "key", HANDLE_EVENT_TYPE_KEY },
177 { "pointer", HANDLE_EVENT_TYPE_POINTER },
178 { "touch", HANDLE_EVENT_TYPE_TOUCH },
179 { "mouse", HANDLE_EVENT_TYPE_MOUSE },
180 { "pinch", HANDLE_EVENT_TYPE_PINCH },
181 { "threeFingersSwipe", HANDLE_EVENT_TYPE_THREEFINGERSSWIP },
182 { "fourFingersSwipe", HANDLE_EVENT_TYPE_FOURFINGERSSWIP },
183 { "swipeInward", HANDLE_EVENT_TYPE_SWIPEINWARD },
184 { "rotate", HANDLE_EVENT_TYPE_ROTATE },
185 { "threeFingersTap", HANDLE_EVENT_TYPE_THREEFINGERSTAP },
186 { "fingerprint", HANDLE_EVENT_TYPE_FINGERPRINT },
187 };
188
189 std::map<std::string, int32_t> TO_HANDLE_PRE_EVENT_TYPE = {
190 { "keyPressed", HANDLE_EVENT_TYPE_PRE_KEY },
191 };
192 } // namespace
193
Start(const std::string & typeName)194 int32_t InputMonitor::Start(const std::string &typeName)
195 {
196 CALL_DEBUG_ENTER;
197 std::lock_guard<std::mutex> guard(mutex_);
198 if (monitorId_ < 0) {
199 auto iter = TO_HANDLE_PRE_EVENT_TYPE.find(typeName.c_str());
200 if (iter != TO_HANDLE_PRE_EVENT_TYPE.end()) {
201 monitorId_ = InputManager::GetInstance()->AddPreMonitor(shared_from_this(), iter->second, keys_);
202 return monitorId_;
203 }
204
205 auto it = TO_GESTURE_TYPE.find(typeName);
206 if (it != TO_GESTURE_TYPE.end()) {
207 monitorId_ = InputManager::GetInstance()->AddGestureMonitor(shared_from_this(), it->second, fingers_);
208 } else {
209 int32_t eventType = 0;
210 auto it = TO_HANDLE_EVENT_TYPE.find(typeName.c_str());
211 if (it != TO_HANDLE_EVENT_TYPE.end()) {
212 eventType = it->second;
213 }
214 monitorId_ = InputManager::GetInstance()->AddMonitor(shared_from_this(), eventType);
215 }
216 }
217 return monitorId_;
218 }
219
Stop()220 void InputMonitor::Stop()
221 {
222 CALL_DEBUG_ENTER;
223 std::lock_guard<std::mutex> guard(mutex_);
224 if (monitorId_ < 0) {
225 MMI_HILOGE("Invalid values");
226 return;
227 }
228
229 auto iter = TO_HANDLE_PRE_EVENT_TYPE.find(typeName_.c_str());
230 if (iter != TO_HANDLE_PRE_EVENT_TYPE.end()) {
231 InputManager::GetInstance()->RemovePreMonitor(monitorId_);
232 monitorId_ = -1;
233 return;
234 }
235
236 auto it = TO_GESTURE_TYPE.find(typeName_);
237 if (it != TO_GESTURE_TYPE.end()) {
238 InputManager::GetInstance()->RemoveGestureMonitor(monitorId_);
239 } else {
240 InputManager::GetInstance()->RemoveMonitor(monitorId_);
241 }
242 monitorId_ = -1;
243 }
244
GetTypeName() const245 std::string InputMonitor::GetTypeName() const
246 {
247 return typeName_;
248 }
249
SetTypeName(const std::string & typeName)250 void InputMonitor::SetTypeName(const std::string &typeName)
251 {
252 typeName_ = typeName;
253 }
254
SetCallback(std::function<void (std::shared_ptr<PointerEvent>)> callback)255 void InputMonitor::SetCallback(std::function<void(std::shared_ptr<PointerEvent>)> callback)
256 {
257 std::lock_guard<std::mutex> guard(mutex_);
258 callback_ = callback;
259 }
260
SetKeyCallback(std::function<void (std::shared_ptr<KeyEvent>)> keyCallback)261 void InputMonitor::SetKeyCallback(std::function<void(std::shared_ptr<KeyEvent>)> keyCallback)
262 {
263 std::lock_guard<std::mutex> guard(mutex_);
264 keyCallback_ = keyCallback;
265 }
266
SetKeys(std::vector<int32_t> keys)267 void InputMonitor::SetKeys(std::vector<int32_t> keys)
268 {
269 keys_ = keys;
270 }
271
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const272 void InputMonitor::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
273 {
274 CALL_DEBUG_ENTER;
275 CHKPV(pointerEvent);
276 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE
277 && pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_MOVE) {
278 if (++flowCtrl_ < MOUSE_FLOW) {
279 return;
280 } else {
281 flowCtrl_ = 0;
282 }
283 }
284 std::function<void(std::shared_ptr<PointerEvent>)> callback;
285 {
286 std::lock_guard<std::mutex> guard(mutex_);
287 auto typeName = JS_INPUT_MONITOR_MGR.GetMonitorTypeName(id_, fingers_);
288 if (typeName == INVALID_TYPE_NAME) {
289 MMI_HILOGE("Failed to process pointer event, id:%{public}d", id_);
290 return;
291 }
292 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
293 if (typeName != "touch" && typeName != TOUCH_SWIPE_GESTURE &&
294 typeName != TOUCH_PINCH_GESTURE && typeName != TOUCH_ALL_GESTURE) {
295 return;
296 }
297 SetConsumeState(pointerEvent);
298 }
299 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_MOUSE) {
300 if (typeName != "mouse" && typeName != "pinch" && typeName != "rotate") {
301 return;
302 }
303 SetConsumeState(pointerEvent);
304 }
305 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_TOUCHPAD) {
306 if (!IsGestureEvent(pointerEvent)) {
307 return;
308 }
309 }
310 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_JOYSTICK) {
311 if (JS_INPUT_MONITOR_MGR.GetMonitor(id_, fingers_)->GetTypeName() != "joystick") {
312 MMI_HILOGE("Failed to process joystick event");
313 return;
314 }
315 }
316 callback = callback_;
317 }
318 CHKPV(callback);
319 callback(pointerEvent);
320 }
321
SetConsumeState(std::shared_ptr<PointerEvent> pointerEvent) const322 void InputMonitor::SetConsumeState(std::shared_ptr<PointerEvent> pointerEvent) const
323 {
324 CHKPV(pointerEvent);
325 if (pointerEvent->GetPointerIds().size() == 1) {
326 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN) {
327 consumed_ = false;
328 }
329 }
330 }
331
IsGestureEvent(std::shared_ptr<PointerEvent> pointerEvent) const332 bool InputMonitor::IsGestureEvent(std::shared_ptr<PointerEvent> pointerEvent) const
333 {
334 CHKPF(pointerEvent);
335 auto jsMonitor = JS_INPUT_MONITOR_MGR.GetMonitor(id_, fingers_);
336 CHKPF(jsMonitor);
337 auto ret = jsMonitor->GetTypeName();
338 if (ret != "pinch" && ret != "threeFingersSwipe" &&
339 ret != "fourFingersSwipe" && ret != "threeFingersTap" &&
340 ret != "swipeInward") {
341 return false;
342 }
343 if (pointerEvent->GetPointerIds().size() == 1) {
344 if (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_BEGIN ||
345 PointerEvent::POINTER_ACTION_SWIPE_BEGIN) {
346 consumed_ = false;
347 }
348 }
349 return true;
350 }
351
SetId(int32_t id)352 void InputMonitor::SetId(int32_t id)
353 {
354 id_ = id;
355 }
356
SetFingers(int32_t fingers)357 void InputMonitor::SetFingers(int32_t fingers)
358 {
359 fingers_ = fingers;
360 }
361
SetHotRectArea(std::vector<Rect> hotRectArea)362 void InputMonitor::SetHotRectArea(std::vector<Rect> hotRectArea)
363 {
364 hotRectArea_ = hotRectArea;
365 }
366
GetHotRectArea()367 std::vector<Rect> InputMonitor::GetHotRectArea()
368 {
369 return hotRectArea_;
370 }
371
SetRectTotal(uint32_t rectTotal)372 void InputMonitor::SetRectTotal(uint32_t rectTotal)
373 {
374 rectTotal_ = rectTotal;
375 }
376
GetRectTotal()377 uint32_t InputMonitor::GetRectTotal()
378 {
379 return rectTotal_;
380 }
381
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const382 void InputMonitor::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
383 {
384 CALL_DEBUG_ENTER;
385 CHKPV(keyEvent);
386 std::function<void(std::shared_ptr<KeyEvent>)> callback;
387 {
388 std::lock_guard<std::mutex> guard(mutex_);
389 auto typeName = JS_INPUT_MONITOR_MGR.GetPreMonitorTypeName(id_);
390 if (typeName == INVALID_TYPE_NAME || typeName != "keyPressed") {
391 MMI_HILOGE("Failed to process key event, id:%{public}d", id_);
392 return;
393 }
394 callback = keyCallback_;
395 }
396 CHKPV(callback);
397 callback(keyEvent);
398 }
399
OnInputEvent(std::shared_ptr<AxisEvent> axisEvent) const400 void InputMonitor::OnInputEvent(std::shared_ptr<AxisEvent> axisEvent) const {}
401
MarkConsumed(int32_t eventId)402 void InputMonitor::MarkConsumed(int32_t eventId)
403 {
404 std::lock_guard<std::mutex> guard(mutex_);
405 if (consumed_) {
406 MMI_HILOGD("The consumed_ is true");
407 return;
408 }
409 if (monitorId_ < 0) {
410 MMI_HILOGE("Invalid values");
411 return;
412 }
413 InputManager::GetInstance()->MarkConsumed(monitorId_, eventId);
414 consumed_ = true;
415 }
416
JsInputMonitor(napi_env jsEnv,const std::string & typeName,std::vector<Rect> rectParam,int32_t rectTotal,napi_value callback,int32_t id,int32_t fingers)417 JsInputMonitor::JsInputMonitor(napi_env jsEnv, const std::string &typeName, std::vector<Rect> rectParam,
418 int32_t rectTotal, napi_value callback, int32_t id, int32_t fingers)
419 : monitor_(std::make_shared<InputMonitor>()), jsEnv_(jsEnv), typeName_(typeName), monitorId_(id),
420 fingers_(fingers)
421 {
422 SetCallback(callback);
423 CHKPV(monitor_);
424 monitor_->SetCallback([jsId = id, jsFingers = fingers](std::shared_ptr<PointerEvent> pointerEvent) {
425 JS_INPUT_MONITOR_MGR.OnPointerEventByMonitorId(jsId, jsFingers, pointerEvent);
426 });
427 monitor_->SetTypeName(typeName_);
428 monitor_->SetId(monitorId_);
429 monitor_->SetFingers(fingers_);
430 if (rectTotal != 0) {
431 monitor_->SetHotRectArea(rectParam);
432 monitor_->SetRectTotal(rectTotal);
433 }
434 }
435
JsInputMonitor(napi_env jsEnv,const std::string & typeName,napi_value callback,int32_t id,int32_t fingers)436 JsInputMonitor::JsInputMonitor(napi_env jsEnv, const std::string &typeName,
437 napi_value callback, int32_t id, int32_t fingers)
438 : monitor_(std::make_shared<InputMonitor>()), jsEnv_(jsEnv), typeName_(typeName), monitorId_(id),
439 fingers_(fingers)
440 {
441 SetCallback(callback);
442 CHKPV(monitor_);
443 monitor_->SetCallback([jsId = id, jsFingers = fingers](std::shared_ptr<PointerEvent> pointerEvent) {
444 JS_INPUT_MONITOR_MGR.OnPointerEventByMonitorId(jsId, jsFingers, pointerEvent);
445 });
446 monitor_->SetTypeName(typeName_);
447 monitor_->SetId(monitorId_);
448 monitor_->SetFingers(fingers_);
449 }
450
JsInputMonitor(napi_env jsEnv,const std::string & typeName,napi_value callback,int32_t id,std::vector<int32_t> keys)451 JsInputMonitor::JsInputMonitor(napi_env jsEnv, const std::string &typeName,
452 napi_value callback, int32_t id, std::vector<int32_t> keys)
453 : monitor_(std::make_shared<InputMonitor>()), jsEnv_(jsEnv), typeName_(typeName), monitorId_(id),
454 keys_(keys)
455 {
456 SetCallback(callback);
457 CHKPV(monitor_);
458 monitor_->SetKeyCallback([jsId = id](std::shared_ptr<KeyEvent> keyEvent) {
459 JS_INPUT_MONITOR_MGR.OnKeyEventByMonitorId(jsId, keyEvent);
460 });
461 monitor_->SetTypeName(typeName_);
462 monitor_->SetId(monitorId_);
463 monitor_->SetKeys(keys_);
464 }
465
SetCallback(napi_value callback)466 void JsInputMonitor::SetCallback(napi_value callback)
467 {
468 if (receiver_ == nullptr && jsEnv_ != nullptr) {
469 uint32_t refCount = 1;
470 auto status = napi_create_reference(jsEnv_, callback, refCount, &receiver_);
471 if (status != napi_ok) {
472 THROWERR(jsEnv_, "napi_create_reference is failed");
473 return;
474 }
475 }
476 }
477
MarkConsumed(int32_t eventId)478 void JsInputMonitor::MarkConsumed(int32_t eventId)
479 {
480 CHKPV(monitor_);
481 monitor_->MarkConsumed(eventId);
482 }
483
IsMatch(napi_env jsEnv,napi_value callback)484 int32_t JsInputMonitor::IsMatch(napi_env jsEnv, napi_value callback)
485 {
486 CHKPR(callback, ERROR_NULL_POINTER);
487 if (jsEnv_ == jsEnv) {
488 napi_value handlerTemp = nullptr;
489 auto status = napi_get_reference_value(jsEnv_, receiver_, &handlerTemp);
490 if (status != napi_ok) {
491 THROWERR(jsEnv_, "napi_get_reference_value is failed");
492 return NAPI_ERR;
493 }
494 bool isEquals = false;
495 status = napi_strict_equals(jsEnv_, handlerTemp, callback, &isEquals);
496 if (status != napi_ok) {
497 THROWERR(jsEnv_, "napi_strict_equals is failed");
498 return NAPI_ERR;
499 }
500 if (isEquals) {
501 MMI_HILOGI("Js callback match success");
502 return RET_OK;
503 }
504 MMI_HILOGI("Js callback match failed");
505 return RET_ERR;
506 }
507 MMI_HILOGI("Js callback match failed");
508 return RET_ERR;
509 }
510
IsMatch(napi_env jsEnv)511 int32_t JsInputMonitor::IsMatch(napi_env jsEnv)
512 {
513 if (jsEnv_ == jsEnv) {
514 MMI_HILOGI("Env match success");
515 return RET_OK;
516 }
517 MMI_HILOGI("Env match failed");
518 return RET_ERR;
519 }
520
GetInputEventFunc(const std::shared_ptr<InputEvent> inputEvent)521 MapFun JsInputMonitor::GetInputEventFunc(const std::shared_ptr<InputEvent> inputEvent)
522 __attribute__((no_sanitize("cfi")))
523 {
524 MapFun mapFunc;
525 mapFunc["id"] = [inputEvent] { return inputEvent->GetId(); };
526 mapFunc["deviceId"] = [inputEvent] { return inputEvent->GetDeviceId(); };
527 mapFunc["actionTime"] = [inputEvent] { return inputEvent->GetActionTime(); };
528 mapFunc["screenId"] = [inputEvent] { return inputEvent->GetTargetDisplayId(); };
529 mapFunc["windowId"] = [inputEvent] { return inputEvent->GetTargetWindowId(); };
530
531 return mapFunc;
532 }
533
SetInputEventProperty(const std::shared_ptr<InputEvent> inputEvent,napi_value result)534 int32_t JsInputMonitor::SetInputEventProperty(const std::shared_ptr<InputEvent> inputEvent, napi_value result)
535 {
536 CHKPR(inputEvent, ERROR_NULL_POINTER);
537 auto mapFun = GetInputEventFunc(inputEvent);
538 for (const auto &it : mapFun) {
539 auto setProperty = "Set" + it.first;
540 CHKRR(SetNameProperty(jsEnv_, result, it.first, it.second()), setProperty, RET_ERR);
541 }
542 return RET_OK;
543 }
544
GetAction(int32_t action) const545 int32_t JsInputMonitor::GetAction(int32_t action) const
546 {
547 switch (action) {
548 case PointerEvent::POINTER_ACTION_CANCEL: {
549 return static_cast<int32_t>(JsTouchEvent::Action::CANCEL);
550 }
551 case PointerEvent::POINTER_ACTION_DOWN: {
552 return static_cast<int32_t>(JsTouchEvent::Action::DOWN);
553 }
554 case PointerEvent::POINTER_ACTION_MOVE: {
555 return static_cast<int32_t>(JsTouchEvent::Action::MOVE);
556 }
557 case PointerEvent::POINTER_ACTION_UP: {
558 return static_cast<int32_t>(JsTouchEvent::Action::UP);
559 }
560 case PointerEvent::POINTER_ACTION_PULL_DOWN: {
561 return static_cast<int32_t>(JsTouchEvent::Action::PULL_DOWN);
562 }
563 case PointerEvent::POINTER_ACTION_PULL_MOVE: {
564 return static_cast<int32_t>(JsTouchEvent::Action::PULL_MOVE);
565 }
566 case PointerEvent::POINTER_ACTION_PULL_UP: {
567 return static_cast<int32_t>(JsTouchEvent::Action::PULL_UP);
568 }
569 default: {
570 return RET_ERR;
571 }
572 }
573 }
574
GetGestureAction(int32_t action) const575 int32_t JsInputMonitor::GetGestureAction(int32_t action) const
576 {
577 switch (action) {
578 case PointerEvent::TOUCH_ACTION_SWIPE_DOWN: {
579 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::SWIPE_DOWN);
580 }
581 case PointerEvent::TOUCH_ACTION_SWIPE_UP: {
582 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::SWIPE_UP);
583 }
584 case PointerEvent::TOUCH_ACTION_SWIPE_RIGHT: {
585 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::SWIPE_RIGHT);
586 }
587 case PointerEvent::TOUCH_ACTION_SWIPE_LEFT: {
588 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::SWIPE_LEFT);
589 }
590 case PointerEvent::TOUCH_ACTION_PINCH_OPENED: {
591 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::PINCH_OPENED);
592 }
593 case PointerEvent::TOUCH_ACTION_PINCH_CLOSEED: {
594 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::PINCH_CLOSED);
595 }
596 case PointerEvent::TOUCH_ACTION_GESTURE_END: {
597 return static_cast<int32_t>(JsGestureEvent::TouchGesturAction::GESTURE_END);
598 }
599 default: {
600 MMI_HILOGW("unknow action, action:%{public}d", action);
601 return RET_ERR;
602 }
603 }
604 }
605
GetSourceType(int32_t sourceType) const606 int32_t JsInputMonitor::GetSourceType(int32_t sourceType) const
607 {
608 switch (sourceType) {
609 case PointerEvent::SOURCE_TYPE_TOUCHSCREEN: {
610 return static_cast<int32_t>(JsTouchEvent::SourceType::TOUCH_SCREEN);
611 }
612 case PointerEvent::SOURCE_TYPE_TOUCHPAD: {
613 return static_cast<int32_t>(JsTouchEvent::SourceType::TOUCH_PAD);
614 }
615 default: {
616 return RET_ERR;
617 }
618 }
619 }
620
GetJsPointerItem(const PointerEvent::PointerItem & item,napi_value value) const621 int32_t JsInputMonitor::GetJsPointerItem(const PointerEvent::PointerItem &item, napi_value value) const
622 {
623 CHKRR(SetNameProperty(jsEnv_, value, "id", item.GetPointerId()), "Set id", RET_ERR);
624 CHKRR(SetNameProperty(jsEnv_, value, "pressedTime", item.GetDownTime()), "Set pressedTime", RET_ERR);
625 CHKRR(SetNameProperty(jsEnv_, value, "screenX", item.GetDisplayX()), "Set screenX", RET_ERR);
626 CHKRR(SetNameProperty(jsEnv_, value, "screenY", item.GetDisplayY()), "Set screenY", RET_ERR);
627 CHKRR(SetNameProperty(jsEnv_, value, "windowX", item.GetWindowX()), "Set windowX", RET_ERR);
628 CHKRR(SetNameProperty(jsEnv_, value, "windowY", item.GetWindowY()), "Set windowY", RET_ERR);
629 CHKRR(SetNameProperty(jsEnv_, value, "pressure", item.GetPressure()), "Set pressure", RET_ERR);
630 CHKRR(SetNameProperty(jsEnv_, value, "width", item.GetWidth()), "Set width", RET_ERR);
631 CHKRR(SetNameProperty(jsEnv_, value, "height", item.GetHeight()), "Set height", RET_ERR);
632 CHKRR(SetNameProperty(jsEnv_, value, "tiltX", item.GetTiltX()), "Set tiltX", RET_ERR);
633 CHKRR(SetNameProperty(jsEnv_, value, "tiltY", item.GetTiltY()), "Set tiltY", RET_ERR);
634 CHKRR(SetNameProperty(jsEnv_, value, "toolX", item.GetToolDisplayX()), "Set toolX", RET_ERR);
635 CHKRR(SetNameProperty(jsEnv_, value, "toolY", item.GetToolDisplayY()), "Set toolY", RET_ERR);
636 CHKRR(SetNameProperty(jsEnv_, value, "toolWidth", item.GetToolWidth()), "Set toolWidth", RET_ERR);
637 CHKRR(SetNameProperty(jsEnv_, value, "toolHeight", item.GetToolHeight()), "Set toolHeight", RET_ERR);
638 CHKRR(SetNameProperty(jsEnv_, value, "rawX", item.GetRawDx()), "Set rawX", RET_ERR);
639 CHKRR(SetNameProperty(jsEnv_, value, "rawY", item.GetRawDy()), "Set rawY", RET_ERR);
640 CHKRR(SetNameProperty(jsEnv_, value, "toolType", item.GetToolType()), "Set toolType", RET_ERR);
641 CHKRR(SetNameProperty(jsEnv_, value, "fixedDisplayX", item.GetFixedDisplayX()), "Set fixedDisplayX", RET_ERR);
642 CHKRR(SetNameProperty(jsEnv_, value, "fixedDisplayY", item.GetFixedDisplayY()), "Set fixedDisplayY", RET_ERR);
643 return RET_OK;
644 }
645
TransformPointerEvent(const std::shared_ptr<PointerEvent> pointerEvent,napi_value result)646 int32_t JsInputMonitor::TransformPointerEvent(const std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
647 {
648 CHKPR(pointerEvent, ERROR_NULL_POINTER);
649 if (SetInputEventProperty(pointerEvent, result) != RET_OK) {
650 MMI_HILOGE("Set inputEvent property failed");
651 return RET_ERR;
652 }
653 if (SetNameProperty(jsEnv_, result, "action", GetAction(pointerEvent->GetPointerAction())) != napi_ok) {
654 MMI_HILOGE("Set action property failed");
655 return RET_ERR;
656 }
657 if (SetNameProperty(jsEnv_, result, "sourceType", GetSourceType(pointerEvent->GetSourceType())) != napi_ok) {
658 MMI_HILOGE("Set sourceType property failed");
659 return RET_ERR;
660 }
661 napi_value pointers = nullptr;
662 CHKRR(napi_create_array(jsEnv_, &pointers), "napi_create_array is", RET_ERR);
663 std::vector<PointerEvent::PointerItem> pointerItems;
664 for (const auto &item : pointerEvent->GetPointerIds()) {
665 PointerEvent::PointerItem pointerItem;
666 if (!pointerEvent->GetPointerItem(item, pointerItem)) {
667 MMI_HILOGE("Get pointer item failed");
668 return RET_ERR;
669 }
670 pointerItems.push_back(pointerItem);
671 }
672 uint32_t index = 0;
673 for (const auto &it : pointerItems) {
674 napi_value element = nullptr;
675 CHKRR(napi_create_object(jsEnv_, &element), "napi_create_object is", RET_ERR);
676 if (GetJsPointerItem(it, element) != RET_OK) {
677 MMI_HILOGE("Transform pointerItem failed");
678 return RET_ERR;
679 }
680 if (it.GetPointerId() == pointerEvent->GetPointerId()) {
681 CHKRR(SetNameProperty(jsEnv_, result, "touch", element), "Set touch", RET_ERR);
682 }
683 CHKRR(napi_set_element(jsEnv_, pointers, index, element), "napi_set_element is", RET_ERR);
684 ++index;
685 }
686 CHKRR(SetNameProperty(jsEnv_, result, "touches", pointers), "Set touches", RET_ERR);
687 CHKRR(SetNameProperty(jsEnv_, result, "fixedMode", static_cast<int32_t>(pointerEvent->GetFixedMode())),
688 "Set fixedMode", RET_ERR);
689 return RET_OK;
690 }
691
TransformPinchEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)692 int32_t JsInputMonitor::TransformPinchEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
693 {
694 CHKPR(pointerEvent, ERROR_NULL_POINTER);
695 int32_t actionValue = GetPinchAction(pointerEvent->GetPointerAction());
696 if (actionValue == RET_ERR) {
697 MMI_HILOGE("Get action value failed");
698 return RET_ERR;
699 }
700 if (SetNameProperty(jsEnv_, result, "type", actionValue) != napi_ok) {
701 MMI_HILOGE("Set type property failed");
702 return RET_ERR;
703 }
704 if (SetNameProperty(jsEnv_, result, "scale",
705 pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_PINCH)) != napi_ok) {
706 MMI_HILOGE("Set scale property failed");
707 return RET_ERR;
708 }
709 return RET_OK;
710 }
711
TransformRotateEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)712 int32_t JsInputMonitor::TransformRotateEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
713 {
714 CHKPR(pointerEvent, ERROR_NULL_POINTER);
715 int32_t actionValue = GetRotateAction(pointerEvent->GetPointerAction());
716 if (actionValue == RET_ERR) {
717 MMI_HILOGE("Get action value failed");
718 return RET_ERR;
719 }
720 if (SetNameProperty(jsEnv_, result, "type", actionValue) != napi_ok) {
721 MMI_HILOGE("Set type property failed");
722 return RET_ERR;
723 }
724 if (SetNameProperty(jsEnv_, result, "angle",
725 pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_ROTATE)) != napi_ok) {
726 MMI_HILOGE("Set scale property failed");
727 return RET_ERR;
728 }
729 return RET_OK;
730 }
731
GetPinchAction(int32_t action) const732 int32_t JsInputMonitor::GetPinchAction(int32_t action) const
733 {
734 switch (action) {
735 case PointerEvent::POINTER_ACTION_AXIS_BEGIN: {
736 return GESTURE_BEGIN;
737 }
738 case PointerEvent::POINTER_ACTION_AXIS_UPDATE: {
739 return GESTURE_UPDATE;
740 }
741 case PointerEvent::POINTER_ACTION_AXIS_END: {
742 return GESTURE_END;
743 }
744 default: {
745 MMI_HILOGD("Abnormal pointer action in pinch event");
746 return RET_ERR;
747 }
748 }
749 }
750
GetRotateAction(int32_t action) const751 int32_t JsInputMonitor::GetRotateAction(int32_t action) const
752 {
753 switch (action) {
754 case PointerEvent::POINTER_ACTION_ROTATE_BEGIN: {
755 return GESTURE_BEGIN;
756 }
757 case PointerEvent::POINTER_ACTION_ROTATE_UPDATE: {
758 return GESTURE_UPDATE;
759 }
760 case PointerEvent::POINTER_ACTION_ROTATE_END: {
761 return GESTURE_END;
762 }
763 default: {
764 MMI_HILOGD("Abnormal pointer action in pinch event");
765 return RET_ERR;
766 }
767 }
768 }
769
TransformSwipeEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)770 int32_t JsInputMonitor::TransformSwipeEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
771 {
772 CHKPR(pointerEvent, ERROR_NULL_POINTER);
773 int32_t actionValue = GetSwipeAction(pointerEvent->GetPointerAction());
774 if (actionValue == RET_ERR) {
775 if (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE) {
776 MMI_HILOGE("Get action value failed");
777 }
778 return RET_ERR;
779 }
780 if (SetNameProperty(jsEnv_, result, "type", actionValue) != napi_ok) {
781 MMI_HILOGE("Set type property failed");
782 return RET_ERR;
783 }
784 PointerEvent::PointerItem pointeritem;
785 int32_t pointerId = 0;
786 if (INJECTION_EVENT_FLAG <= pointerEvent->GetPointerId()) {
787 pointerId = pointerEvent->GetPointerId();
788 }
789 if (!pointerEvent->GetPointerItem(pointerId, pointeritem)) {
790 MMI_HILOGE("Can't find this pointerItem");
791 return RET_ERR;
792 }
793 if (SetNameProperty(jsEnv_, result, "x", pointeritem.GetDisplayX()) != napi_ok) {
794 MMI_HILOGE("Set displayX property failed");
795 return RET_ERR;
796 }
797 if (SetNameProperty(jsEnv_, result, "y", pointeritem.GetDisplayY()) != napi_ok) {
798 MMI_HILOGE("Set displayY property failed");
799 return RET_ERR;
800 }
801 return RET_OK;
802 }
803
GetSwipeAction(int32_t action) const804 int32_t JsInputMonitor::GetSwipeAction(int32_t action) const
805 {
806 switch (action) {
807 case PointerEvent::POINTER_ACTION_SWIPE_BEGIN: {
808 return GESTURE_BEGIN;
809 }
810 case PointerEvent::POINTER_ACTION_SWIPE_UPDATE: {
811 return GESTURE_UPDATE;
812 }
813 case PointerEvent::POINTER_ACTION_SWIPE_END: {
814 return GESTURE_END;
815 }
816 default: {
817 MMI_HILOGD("Abnormal pointer action in swipe event");
818 return RET_ERR;
819 }
820 }
821 }
822
TransformMultiTapEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)823 int32_t JsInputMonitor::TransformMultiTapEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
824 {
825 CHKPR(pointerEvent, ERROR_NULL_POINTER);
826 int32_t actionValue = GetMultiTapAction(pointerEvent->GetPointerAction());
827 if (actionValue == RET_ERR) {
828 MMI_HILOGE("Get action value failed");
829 return RET_ERR;
830 }
831 if (SetNameProperty(jsEnv_, result, "type", actionValue) != napi_ok) {
832 MMI_HILOGE("Set type property failed");
833 return RET_ERR;
834 }
835 return RET_OK;
836 }
837
GetMultiTapAction(int32_t action) const838 int32_t JsInputMonitor::GetMultiTapAction(int32_t action) const
839 {
840 switch (action) {
841 case PointerEvent::POINTER_ACTION_TRIPTAP: {
842 return GESTURE_END;
843 }
844 default: {
845 MMI_HILOGD("Abnormal pointer action in multi tap event");
846 return RET_ERR;
847 }
848 }
849 }
850
TransformSwipeInwardEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)851 int32_t JsInputMonitor::TransformSwipeInwardEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
852 {
853 CHKPR(pointerEvent, ERROR_NULL_POINTER);
854 int32_t actionValue = pointerEvent->GetPointerAction();
855 if (actionValue == RET_ERR) {
856 MMI_HILOGE("Get action value failed");
857 return RET_ERR;
858 }
859 int32_t actionTypeTemp = actionValue;
860 switch (actionTypeTemp) {
861 case PointerEvent::POINTER_ACTION_DOWN: {
862 actionValue = GESTURE_BEGIN;
863 break;
864 }
865 case PointerEvent::POINTER_ACTION_MOVE: {
866 actionValue = GESTURE_UPDATE;
867 break;
868 }
869 case PointerEvent::POINTER_ACTION_UP:
870 case PointerEvent::POINTER_ACTION_CANCEL: {
871 actionValue = GESTURE_END;
872 break;
873 }
874 default: {
875 MMI_HILOGE("Abnormal pointer action in swipe event");
876 return RET_ERR;
877 }
878 }
879 if (SetNameProperty(jsEnv_, result, "type", actionValue) != napi_ok) {
880 MMI_HILOGE("Set type property failed");
881 return RET_ERR;
882 }
883 PointerEvent::PointerItem pointeritem;
884 int32_t pointerId = 0;
885 if (!pointerEvent->GetPointerItem(pointerId, pointeritem)) {
886 MMI_HILOGE("Can't find this pointerItem");
887 return RET_ERR;
888 }
889 if (SetNameProperty(jsEnv_, result, "x", pointeritem.GetDisplayX()) != napi_ok) {
890 MMI_HILOGE("Set displayX property failed");
891 return RET_ERR;
892 }
893 if (SetNameProperty(jsEnv_, result, "y", pointeritem.GetDisplayY()) != napi_ok) {
894 MMI_HILOGE("Set displayY property failed");
895 return RET_ERR;
896 }
897 return RET_OK;
898 }
899
900 #ifdef OHOS_BUILD_ENABLE_FINGERPRINT
GetFingerprintAction(int32_t action) const901 int32_t JsInputMonitor::GetFingerprintAction(int32_t action) const
902 {
903 MMI_HILOGD("GetFingerprintAction enter, action is %{public}d", action);
904 switch (action) {
905 case PointerEvent::POINTER_ACTION_FINGERPRINT_DOWN: {
906 return FINGERPRINT_DOWN;
907 }
908 case PointerEvent::POINTER_ACTION_FINGERPRINT_UP: {
909 return FINGERPRINT_UP;
910 }
911 case PointerEvent::POINTER_ACTION_FINGERPRINT_SLIDE: {
912 return FINGERPRINT_SLIDE;
913 }
914 case PointerEvent::POINTER_ACTION_FINGERPRINT_RETOUCH: {
915 return FINGERPRINT_RETOUCH;
916 }
917 case PointerEvent::POINTER_ACTION_FINGERPRINT_CLICK: {
918 return FINGERPRINT_CLICK;
919 }
920 case PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL: {
921 return FINGERPRINT_CANCEL;
922 }
923 default: {
924 MMI_HILOGE("Wrong action is %{public}d", action);
925 return RET_ERR;
926 }
927 }
928 }
929 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
930
GetFuns(const std::shared_ptr<PointerEvent> pointerEvent,const PointerEvent::PointerItem & item)931 MapFun JsInputMonitor::GetFuns(const std::shared_ptr<PointerEvent> pointerEvent, const PointerEvent::PointerItem& item)
932 {
933 MapFun mapFun;
934 mapFun["actionTime"] = [pointerEvent] { return pointerEvent->GetActionTime(); };
935 mapFun["screenId"] = [pointerEvent] { return pointerEvent->GetTargetDisplayId(); };
936 mapFun["windowId"] = [pointerEvent] { return pointerEvent->GetTargetWindowId(); };
937 mapFun["deviceId"] = [item] { return item.GetDeviceId(); };
938 mapFun["windowX"] = [item] { return item.GetWindowX(); };
939 mapFun["windowY"] = [item] { return item.GetWindowY(); };
940 mapFun["screenX"] = [item] { return item.GetDisplayX(); };
941 mapFun["screenY"] = [item] { return item.GetDisplayY(); };
942 mapFun["rawDeltaX"] = [item] { return item.GetRawDx(); };
943 mapFun["rawDeltaY"] = [item] { return item.GetRawDy(); };
944 return mapFun;
945 }
946
SetMouseProperty(const std::shared_ptr<PointerEvent> pointerEvent,const PointerEvent::PointerItem & item,napi_value result)947 bool JsInputMonitor::SetMouseProperty(const std::shared_ptr<PointerEvent> pointerEvent,
948 const PointerEvent::PointerItem& item, napi_value result)
949 {
950 CHKPF(pointerEvent);
951 int32_t buttonId = pointerEvent->GetButtonId();
952 if (buttonId == PointerEvent::MOUSE_BUTTON_MIDDLE) {
953 buttonId = MIDDLE;
954 } else if (buttonId == PointerEvent::MOUSE_BUTTON_RIGHT) {
955 buttonId = RIGHT;
956 }
957 if (SetNameProperty(jsEnv_, result, "button", buttonId) != napi_ok) {
958 THROWERR(jsEnv_, "Set property failed");
959 return false;
960 }
961
962 auto mapFun = GetFuns(pointerEvent, item);
963 for (const auto &it : mapFun) {
964 if (SetNameProperty(jsEnv_, result, it.first, it.second()) != napi_ok) {
965 THROWERR(jsEnv_, "Set property failed");
966 return false;
967 }
968 }
969 return true;
970 }
971
GetAxesValue(const std::shared_ptr<PointerEvent> pointerEvent,napi_value element)972 bool JsInputMonitor::GetAxesValue(const std::shared_ptr<PointerEvent> pointerEvent, napi_value element)
973 {
974 CALL_DEBUG_ENTER;
975 CHKPF(pointerEvent);
976 double axisValue = -1.0;
977 int32_t axis = -1;
978 if (pointerEvent->HasAxis(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL)) {
979 axisValue = pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL);
980 axis = AXIS_TYPE_SCROLL_VERTICAL;
981 }
982 if (pointerEvent->HasAxis(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL)) {
983 axisValue = pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL);
984 axis = AXIS_TYPE_SCROLL_HORIZONTAL;
985 }
986 if (pointerEvent->HasAxis(PointerEvent::AXIS_TYPE_PINCH)) {
987 axisValue = pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_PINCH);
988 axis = AXIS_TYPE_PINCH;
989 }
990 if (SetNameProperty(jsEnv_, element, "axis", axis) != napi_ok) {
991 THROWERR(jsEnv_, "Set property of axis failed");
992 return false;
993 }
994 if (SetNameProperty(jsEnv_, element, "value", axisValue) != napi_ok) {
995 THROWERR(jsEnv_, "Set property of value failed");
996 return false;
997 }
998 return true;
999 }
1000
GetJoystickAction(int32_t action)1001 std::optional<int32_t> JsInputMonitor::GetJoystickAction(int32_t action)
1002 {
1003 switch (action) {
1004 case PointerEvent::POINTER_ACTION_CANCEL: {
1005 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::CANCEL));
1006 }
1007 case PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
1008 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::BUTTON_DOWN));
1009 }
1010 case PointerEvent::POINTER_ACTION_BUTTON_UP: {
1011 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::BUTTON_UP));
1012 }
1013 case PointerEvent::POINTER_ACTION_AXIS_BEGIN: {
1014 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::ABS_BEGIN));
1015 }
1016 case PointerEvent::POINTER_ACTION_AXIS_UPDATE: {
1017 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::ABS_UPDATE));
1018 }
1019 case PointerEvent::POINTER_ACTION_AXIS_END: {
1020 return std::make_optional(static_cast<int32_t>(JsJoystickEvent::Action::ABS_END));
1021 }
1022 default: {
1023 MMI_HILOGW("action:%{public}d is unknown", action);
1024 return std::nullopt;
1025 }
1026 }
1027 }
1028
GetJoystickButton(int32_t buttonId)1029 int32_t JsInputMonitor::GetJoystickButton(int32_t buttonId)
1030 {
1031 int32_t currentButtonId = -1;
1032 for (const auto &item : g_joystickButtonType) {
1033 if (buttonId == item.second) {
1034 currentButtonId = static_cast<int32_t>(item.first);
1035 break;
1036 }
1037 }
1038 return currentButtonId;
1039 }
1040
GetJoystickPressedButtons(const std::set<int32_t> & pressedButtons,napi_value result)1041 bool JsInputMonitor::GetJoystickPressedButtons(const std::set<int32_t>& pressedButtons, napi_value result)
1042 {
1043 CALL_DEBUG_ENTER;
1044 napi_value value = nullptr;
1045 napi_status status = napi_create_array(jsEnv_, &value);
1046 if (status != napi_ok || value == nullptr) {
1047 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "napi_create_array is failed");
1048 return false;
1049 }
1050 uint32_t index = 0;
1051 for (const auto &item : pressedButtons) {
1052 int32_t buttonId = GetJoystickButton(item);
1053 napi_value element = nullptr;
1054 if (napi_create_int32(jsEnv_, buttonId, &element) != napi_ok) {
1055 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Napi create int32 failed");
1056 return false;
1057 }
1058 status = napi_set_element(jsEnv_, value, index, element);
1059 if (status != napi_ok) {
1060 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Napi set element failed");
1061 return false;
1062 }
1063 ++index;
1064 }
1065 if (SetNameProperty(jsEnv_, result, "pressedButtons", value) != napi_ok) {
1066 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Set property of pressedButtons failed");
1067 return false;
1068 }
1069 return true;
1070 }
1071
GetMousePointerItem(const std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1072 int32_t JsInputMonitor::GetMousePointerItem(const std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
1073 {
1074 CALL_DEBUG_ENTER;
1075 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1076 napi_value axes = nullptr;
1077 napi_status status = napi_create_array(jsEnv_, &axes);
1078 if (status != napi_ok || axes == nullptr) {
1079 THROWERR(jsEnv_, "napi_create_array is failed");
1080 return RET_ERR;
1081 }
1082 uint32_t index = 0;
1083 int32_t currentPointerId = pointerEvent->GetPointerId();
1084 std::vector<int32_t> pointerIds { pointerEvent->GetPointerIds() };
1085 for (const auto& pointerId : pointerIds) {
1086 if (pointerId == currentPointerId) {
1087 PointerEvent::PointerItem item;
1088 if (!pointerEvent->GetPointerItem(pointerId, item)) {
1089 MMI_HILOGE("Invalid pointer:%{public}d", pointerId);
1090 return RET_ERR;
1091 }
1092 if (SetNameProperty(jsEnv_, result, "id", currentPointerId) != napi_ok) {
1093 THROWERR(jsEnv_, "Set property of id failed");
1094 return false;
1095 }
1096 if (!SetMouseProperty(pointerEvent, item, result)) {
1097 MMI_HILOGE("Set property of mouse failed");
1098 return RET_ERR;
1099 }
1100 }
1101 napi_value element = nullptr;
1102 if (napi_create_object(jsEnv_, &element) != napi_ok) {
1103 THROWERR(jsEnv_, "napi_create_object is failed");
1104 return RET_ERR;
1105 }
1106 if (!GetAxesValue(pointerEvent, element)) {
1107 THROWERR(jsEnv_, "Get axesValue failed");
1108 return RET_ERR;
1109 }
1110 status = napi_set_element(jsEnv_, axes, index, element);
1111 if (status != napi_ok) {
1112 THROWERR(jsEnv_, "Napi set element in axes failed");
1113 return RET_ERR;
1114 }
1115 ++index;
1116 }
1117 if (SetNameProperty(jsEnv_, result, "axes", axes) != napi_ok) {
1118 THROWERR(jsEnv_, "Set property of axes failed");
1119 return RET_ERR;
1120 }
1121 return RET_OK;
1122 }
1123
GetJoystickPointerItem(const std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1124 int32_t JsInputMonitor::GetJoystickPointerItem(const std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
1125 {
1126 CALL_DEBUG_ENTER;
1127 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1128 napi_value axes = nullptr;
1129 napi_status status = napi_create_array(jsEnv_, &axes);
1130 if (status != napi_ok || axes == nullptr) {
1131 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "napi_create_array is failed");
1132 return RET_ERR;
1133 }
1134
1135 int32_t currentPointerId = pointerEvent->GetPointerId();
1136 if (SetNameProperty(jsEnv_, result, "id", currentPointerId) != napi_ok) {
1137 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Set property of id failed");
1138 return RET_ERR;
1139 }
1140
1141 uint32_t index = 0;
1142 for (const auto &item : g_joystickAxisType) {
1143 if (!pointerEvent->HasAxis(item.second)) {
1144 continue;
1145 }
1146 double axisValue = pointerEvent->GetAxisValue(item.second);
1147 int32_t axis = static_cast<int32_t>(item.first);
1148 napi_value element = nullptr;
1149 if (napi_create_object(jsEnv_, &element) != napi_ok) {
1150 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "napi_create_object is failed");
1151 return RET_ERR;
1152 }
1153
1154 if (SetNameProperty(jsEnv_, element, "axis", axis) != napi_ok) {
1155 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Set property of axis failed");
1156 return RET_ERR;
1157 }
1158 if (SetNameProperty(jsEnv_, element, "value", axisValue) != napi_ok) {
1159 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Set property of value failed");
1160 return RET_ERR;
1161 }
1162
1163 status = napi_set_element(jsEnv_, axes, index, element);
1164 if (status != napi_ok) {
1165 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Napi set element in axes failed");
1166 return RET_ERR;
1167 }
1168 ++index;
1169 }
1170
1171 if (SetNameProperty(jsEnv_, result, "axes", axes) != napi_ok) {
1172 THROWERR_CUSTOM(jsEnv_, COMMON_PARAMETER_ERROR, "Set property of axes failed");
1173 return RET_ERR;
1174 }
1175
1176 return RET_OK;
1177 }
1178
1179
GetPressedButtons(const std::set<int32_t> & pressedButtons,napi_value result)1180 bool JsInputMonitor::GetPressedButtons(const std::set<int32_t>& pressedButtons, napi_value result)
1181 {
1182 CALL_DEBUG_ENTER;
1183 napi_value value = nullptr;
1184 napi_status status = napi_create_array(jsEnv_, &value);
1185 if (status != napi_ok || value == nullptr) {
1186 THROWERR(jsEnv_, "napi_create_array is failed");
1187 return false;
1188 }
1189 uint32_t index = 0;
1190 for (const auto &item : pressedButtons) {
1191 int32_t buttonId = item;
1192 if (buttonId == PointerEvent::MOUSE_BUTTON_MIDDLE) {
1193 buttonId = MIDDLE;
1194 } else if (buttonId == PointerEvent::MOUSE_BUTTON_RIGHT) {
1195 buttonId = RIGHT;
1196 }
1197 napi_value element = nullptr;
1198 if (napi_create_int32(jsEnv_, buttonId, &element) != napi_ok) {
1199 THROWERR(jsEnv_, "Napi create int32 failed");
1200 return false;
1201 }
1202 status = napi_set_element(jsEnv_, value, index, element);
1203 if (status != napi_ok) {
1204 THROWERR(jsEnv_, "Napi set element failed");
1205 return false;
1206 }
1207 ++index;
1208 }
1209 if (SetNameProperty(jsEnv_, result, "pressedButtons", value) != napi_ok) {
1210 THROWERR(jsEnv_, "Set property of pressedButtons failed");
1211 return false;
1212 }
1213 return true;
1214 }
1215
GetPressedKeys(const std::vector<int32_t> & pressedKeys,napi_value result)1216 bool JsInputMonitor::GetPressedKeys(const std::vector<int32_t>& pressedKeys, napi_value result)
1217 {
1218 CALL_DEBUG_ENTER;
1219 napi_value value = nullptr;
1220 napi_status status = napi_create_array(jsEnv_, &value);
1221 if (status != napi_ok || value == nullptr) {
1222 THROWERR(jsEnv_, "napi_create_array is failed");
1223 return false;
1224 }
1225 uint32_t index = 0;
1226 for (const auto &it : pressedKeys) {
1227 napi_value element = nullptr;
1228 if (napi_create_int32(jsEnv_, it, &element) != napi_ok) {
1229 THROWERR(jsEnv_, "Napi create int32 failed");
1230 return false;
1231 }
1232 status = napi_set_element(jsEnv_, value, index, element);
1233 if (status != napi_ok) {
1234 THROWERR(jsEnv_, "Napi set element failed");
1235 return false;
1236 }
1237 ++index;
1238 }
1239 if (SetNameProperty(jsEnv_, result, "pressedKeys", value) != napi_ok) {
1240 THROWERR(jsEnv_, "Set property of pressedKeys failed");
1241 return false;
1242 }
1243 return true;
1244 }
1245
HasKeyCode(const std::vector<int32_t> & pressedKeys,int32_t keyCode)1246 bool JsInputMonitor::HasKeyCode(const std::vector<int32_t>& pressedKeys, int32_t keyCode)
1247 {
1248 return std::find(pressedKeys.begin(), pressedKeys.end(), keyCode) != pressedKeys.end();
1249 }
1250
GetPressedKey(const std::vector<int32_t> & pressedKeys,napi_value result)1251 bool JsInputMonitor::GetPressedKey(const std::vector<int32_t>& pressedKeys, napi_value result)
1252 {
1253 CALL_DEBUG_ENTER;
1254 bool isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_CTRL_LEFT)
1255 || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_CTRL_RIGHT);
1256 if (SetNameProperty(jsEnv_, result, "ctrlKey", isExists) != napi_ok) {
1257 THROWERR(jsEnv_, "Set ctrlKey with failed");
1258 return false;
1259 }
1260 isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_ALT_LEFT)
1261 || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_ALT_RIGHT);
1262 if (SetNameProperty(jsEnv_, result, "altKey", isExists) != napi_ok) {
1263 THROWERR(jsEnv_, "Set altKey failed");
1264 return false;
1265 }
1266 isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_SHIFT_LEFT)
1267 || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_SHIFT_RIGHT);
1268 if (SetNameProperty(jsEnv_, result, "shiftKey", isExists) != napi_ok) {
1269 THROWERR(jsEnv_, "Set shiftKey failed");
1270 return false;
1271 }
1272 isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_META_LEFT)
1273 || HasKeyCode(pressedKeys, KeyEvent::KEYCODE_META_RIGHT);
1274 if (SetNameProperty(jsEnv_, result, "logoKey", isExists) != napi_ok) {
1275 THROWERR(jsEnv_, "Set logoKey failed");
1276 return false;
1277 }
1278 isExists = HasKeyCode(pressedKeys, KeyEvent::KEYCODE_FN);
1279 if (SetNameProperty(jsEnv_, result, "fnKey", isExists) != napi_ok) {
1280 THROWERR(jsEnv_, "Set fnKey failed");
1281 return false;
1282 }
1283 return true;
1284 }
1285
TransformTsActionValue(int32_t pointerAction)1286 int32_t JsInputMonitor::TransformTsActionValue(int32_t pointerAction)
1287 {
1288 switch (pointerAction) {
1289 case PointerEvent::POINTER_ACTION_CANCEL: {
1290 return CANCEL;
1291 }
1292 case PointerEvent::POINTER_ACTION_MOVE:
1293 case PointerEvent::POINTER_ACTION_PULL_MOVE: {
1294 return MOVE;
1295 }
1296 case PointerEvent::POINTER_ACTION_BUTTON_DOWN:
1297 case PointerEvent::POINTER_ACTION_PULL_DOWN: {
1298 return BUTTON_DOWN;
1299 }
1300 case PointerEvent::POINTER_ACTION_BUTTON_UP:
1301 case PointerEvent::POINTER_ACTION_PULL_UP: {
1302 return BUTTON_UP;
1303 }
1304 case PointerEvent::POINTER_ACTION_AXIS_BEGIN: {
1305 return AXIS_BEGIN;
1306 }
1307 case PointerEvent::POINTER_ACTION_AXIS_UPDATE: {
1308 return AXIS_UPDATE;
1309 }
1310 case PointerEvent::POINTER_ACTION_AXIS_END: {
1311 return AXIS_END;
1312 }
1313 default: {
1314 MMI_HILOGD("Abnormal pointer action");
1315 return RET_ERR;
1316 }
1317 }
1318 }
1319
TransformMousePointerEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1320 int32_t JsInputMonitor::TransformMousePointerEvent(std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
1321 {
1322 CALL_DEBUG_ENTER;
1323 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1324 int32_t actionValue = TransformTsActionValue(pointerEvent->GetPointerAction());
1325 if (actionValue == RET_ERR) {
1326 MMI_HILOGD("Transform action value failed");
1327 return RET_ERR;
1328 }
1329 if (SetNameProperty(jsEnv_, result, "action", actionValue) != napi_ok) {
1330 MMI_HILOGE("Set property of action failed");
1331 return RET_ERR;
1332 }
1333 std::vector<int32_t> pressedKeys = pointerEvent->GetPressedKeys();
1334 if (!GetPressedKeys(pressedKeys, result)) {
1335 MMI_HILOGE("Get pressedButtons failed");
1336 return RET_ERR;
1337 }
1338 if (!GetPressedKey(pressedKeys, result)) {
1339 MMI_HILOGE("Get singlePressedKey failed");
1340 return RET_ERR;
1341 }
1342 if (GetMousePointerItem(pointerEvent, result) != RET_OK) {
1343 MMI_HILOGE("Get item of mousePointer failed");
1344 return RET_ERR;
1345 }
1346 std::set<int32_t> pressedButtons = pointerEvent->GetPressedButtons();
1347 if (!GetPressedButtons(pressedButtons, result)) {
1348 MMI_HILOGE("Get pressedKeys failed");
1349 return RET_ERR;
1350 }
1351 return RET_OK;
1352 }
1353
TransformJoystickPointerEvent(std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1354 int32_t JsInputMonitor::TransformJoystickPointerEvent(std::shared_ptr<PointerEvent> pointerEvent,
1355 napi_value result)
1356 {
1357 CALL_DEBUG_ENTER;
1358 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1359 int32_t pointerAction = pointerEvent->GetPointerAction();
1360 if (pointerAction <= 0) {
1361 MMI_HILOGE("GetPointerAction failed");
1362 return RET_ERR;
1363 }
1364 std::optional<int32_t> tempActionValue = GetJoystickAction(pointerAction);
1365 if (!tempActionValue) {
1366 MMI_HILOGE("Get joystick action value failed");
1367 return RET_ERR;
1368 }
1369 int32_t actionValue = tempActionValue.value();
1370 if (actionValue <= 0) {
1371 MMI_HILOGE("actionValue:%{public}d error", actionValue);
1372 return RET_ERR;
1373 }
1374 if (SetNameProperty(jsEnv_, result, "action", actionValue) != napi_ok) {
1375 MMI_HILOGE("Set property of action failed");
1376 return RET_ERR;
1377 }
1378
1379 int32_t actionTime = pointerEvent->GetActionTime();
1380 if (SetNameProperty(jsEnv_, result, "actionTime", actionTime) != napi_ok) {
1381 THROWERR(jsEnv_, "Set actionTime failed");
1382 return RET_ERR;
1383 }
1384
1385 int32_t deviceId = pointerEvent->GetDeviceId();
1386 if (SetNameProperty(jsEnv_, result, "deviceId", deviceId) != napi_ok) {
1387 THROWERR(jsEnv_, "Set deviceId failed");
1388 return RET_ERR;
1389 }
1390
1391 int32_t buttonId = GetJoystickButton(pointerEvent->GetButtonId());
1392 if (SetNameProperty(jsEnv_, result, "button", buttonId) != napi_ok) {
1393 THROWERR(jsEnv_, "Set property of button failed");
1394 return RET_ERR;
1395 }
1396
1397 if (GetJoystickPointerItem(pointerEvent, result) != RET_OK) {
1398 MMI_HILOGE("Get item of mousePointer failed");
1399 return RET_ERR;
1400 }
1401
1402 std::set<int32_t> pressedButtons = pointerEvent->GetPressedButtons();
1403 if (!GetJoystickPressedButtons(pressedButtons, result)) {
1404 MMI_HILOGE("Get pressedKeys failed");
1405 return RET_ERR;
1406 }
1407
1408 return RET_OK;
1409 }
1410
1411 #ifdef OHOS_BUILD_ENABLE_FINGERPRINT
TransformFingerprintEvent(const std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1412 int32_t JsInputMonitor::TransformFingerprintEvent(const std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
1413 {
1414 CALL_DEBUG_ENTER;
1415 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1416 int32_t actionValue = GetFingerprintAction(pointerEvent->GetPointerAction());
1417 if (actionValue == RET_ERR) {
1418 MMI_HILOGW("Get action value failed");
1419 return RET_ERR;
1420 }
1421 if (SetNameProperty(jsEnv_, result, "action", actionValue) != napi_ok) {
1422 MMI_HILOGW("Set name property failed");
1423 return RET_ERR;
1424 }
1425 if (SetNameProperty(jsEnv_, result, "distanceX", pointerEvent->GetFingerprintDistanceX()) != napi_ok) {
1426 MMI_HILOGW("Set distanceX property failed");
1427 return RET_ERR;
1428 }
1429 if (SetNameProperty(jsEnv_, result, "distanceY", pointerEvent->GetFingerprintDistanceY()) != napi_ok) {
1430 MMI_HILOGW("Set distanceY property failed");
1431 return RET_ERR;
1432 }
1433 MMI_HILOGD("jsfingerprint key:%{public}d, x:%{public}f, y:%{public}f", actionValue,
1434 pointerEvent->GetFingerprintDistanceX(), pointerEvent->GetFingerprintDistanceY());
1435 return RET_OK;
1436 }
1437 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
1438
TransformGestureEvent(const std::shared_ptr<PointerEvent> pointerEvent,napi_value result)1439 int32_t JsInputMonitor::TransformGestureEvent(const std::shared_ptr<PointerEvent> pointerEvent, napi_value result)
1440 {
1441 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1442 if (SetNameProperty(jsEnv_, result, "action", GetGestureAction(pointerEvent->GetPointerAction())) != napi_ok) {
1443 MMI_HILOGE("Set action property failed");
1444 return RET_ERR;
1445 }
1446 napi_value pointers = nullptr;
1447 CHKRR(napi_create_array(jsEnv_, &pointers), "napi_create_array is", RET_ERR);
1448 std::vector<PointerEvent::PointerItem> pointerItems;
1449 for (const auto &item : pointerEvent->GetPointerIds()) {
1450 PointerEvent::PointerItem pointerItem;
1451 if (!pointerEvent->GetPointerItem(item, pointerItem)) {
1452 MMI_HILOGE("Get pointer item failed");
1453 return RET_ERR;
1454 }
1455 pointerItems.push_back(pointerItem);
1456 }
1457 uint32_t index = 0;
1458 for (const auto &it : pointerItems) {
1459 napi_value element = nullptr;
1460 CHKRR(napi_create_object(jsEnv_, &element), "napi_create_object is", RET_ERR);
1461 if (GetJsPointerItem(it, element) != RET_OK) {
1462 MMI_HILOGE("Transform pointerItem failed");
1463 return RET_ERR;
1464 }
1465 CHKRR(napi_set_element(jsEnv_, pointers, index, element), "napi_set_element is", RET_ERR);
1466 ++index;
1467 }
1468 CHKRR(SetNameProperty(jsEnv_, result, "touches", pointers), "Set touches", RET_ERR);
1469 return RET_OK;
1470 }
1471
Start(const std::string & typeName)1472 int32_t JsInputMonitor::Start(const std::string &typeName)
1473 {
1474 CALL_DEBUG_ENTER;
1475 CHKPF(monitor_);
1476 if (isMonitoring_) {
1477 MMI_HILOGW("Js is monitoring");
1478 return RET_OK;
1479 }
1480 int32_t ret = monitor_->Start(typeName);
1481 if (ret >= 0) {
1482 isMonitoring_ = true;
1483 }
1484 return ret;
1485 }
1486
~JsInputMonitor()1487 JsInputMonitor::~JsInputMonitor()
1488 {
1489 CALL_DEBUG_ENTER;
1490 if (isMonitoring_) {
1491 isMonitoring_ = false;
1492 if (monitor_ != nullptr) {
1493 monitor_->Stop();
1494 }
1495 }
1496 uint32_t refCount = 0;
1497 auto status = napi_reference_unref(jsEnv_, receiver_, &refCount);
1498 if (status != napi_ok) {
1499 THROWERR(jsEnv_, "napi_reference_unref is failed");
1500 return;
1501 }
1502 }
1503
Stop()1504 void JsInputMonitor::Stop()
1505 {
1506 CALL_DEBUG_ENTER;
1507 CHKPV(monitor_);
1508 if (isMonitoring_) {
1509 isMonitoring_ = false;
1510 if (monitor_ != nullptr) {
1511 monitor_->Stop();
1512 }
1513 }
1514 }
1515
GetId() const1516 int32_t JsInputMonitor::GetId() const
1517 {
1518 return monitorId_;
1519 }
1520
GetFingers() const1521 int32_t JsInputMonitor::GetFingers() const
1522 {
1523 return fingers_;
1524 }
1525
GetTypeName() const1526 std::string JsInputMonitor::GetTypeName() const
1527 {
1528 return typeName_;
1529 }
1530
OnPointerEvent(std::shared_ptr<PointerEvent> pointerEvent)1531 void JsInputMonitor::OnPointerEvent(std::shared_ptr<PointerEvent> pointerEvent)
1532 {
1533 CALL_DEBUG_ENTER;
1534 if (!isMonitoring_) {
1535 MMI_HILOGE("Js monitor stop");
1536 return;
1537 }
1538 CHKPV(monitor_);
1539 CHKPV(pointerEvent);
1540 {
1541 std::lock_guard<std::mutex> guard(mutex_);
1542 if (!evQueue_.empty()) {
1543 if (IsBeginAndEnd(pointerEvent)) {
1544 std::queue<std::shared_ptr<PointerEvent>> tmp;
1545 std::swap(evQueue_, tmp);
1546 }
1547 }
1548 evQueue_.push(pointerEvent);
1549 }
1550
1551 if (!evQueue_.empty()) {
1552 uv_work_t *work = new (std::nothrow) uv_work_t;
1553 CHKPV(work);
1554 MonitorInfo *monitorInfo = new (std::nothrow) MonitorInfo();
1555 if (monitorInfo == nullptr) {
1556 MMI_HILOGE("The monitorInfo is nullptr");
1557 delete work;
1558 work = nullptr;
1559 return;
1560 }
1561 monitorInfo->monitorId = monitorId_;
1562 monitorInfo->fingers = fingers_;
1563 work->data = monitorInfo;
1564 uv_loop_s *loop = nullptr;
1565 auto status = napi_get_uv_event_loop(jsEnv_, &loop);
1566 if (status != napi_ok) {
1567 THROWERR(jsEnv_, "napi_get_uv_event_loop is failed");
1568 CleanData(&monitorInfo, &work);
1569 return;
1570 }
1571 int32_t ret = uv_queue_work_with_qos(
1572 loop, work,
1573 [](uv_work_t *work) {
1574 MMI_HILOGD("uv_queue_work callback function is called");
1575 },
1576 &JsInputMonitor::JsCallback, uv_qos_user_initiated);
1577 if (ret != 0) {
1578 MMI_HILOGE("Add uv_queue failed, ret is %{public}d", ret);
1579 CleanData(&monitorInfo, &work);
1580 }
1581 }
1582 }
1583
IsBeginAndEnd(std::shared_ptr<PointerEvent> pointerEvent)1584 bool JsInputMonitor::IsBeginAndEnd(std::shared_ptr<PointerEvent> pointerEvent)
1585 {
1586 CHKPF(pointerEvent);
1587 bool res = pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_DOWN ||
1588 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP ||
1589 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_BEGIN ||
1590 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_END;
1591 return res;
1592 }
1593
JsCallback(uv_work_t * work,int32_t status)1594 void JsInputMonitor::JsCallback(uv_work_t *work, int32_t status)
1595 {
1596 CALL_DEBUG_ENTER;
1597 CHKPV(work);
1598 auto temp = static_cast<MonitorInfo*>(work->data);
1599 delete work;
1600 work = nullptr;
1601 auto jsMonitor { JS_INPUT_MONITOR_MGR.GetMonitor(temp->monitorId, temp->fingers) };
1602 CHKPV(jsMonitor);
1603 jsMonitor->OnPointerEventInJsThread(jsMonitor->GetTypeName(), temp->fingers);
1604 delete temp;
1605 temp = nullptr;
1606 }
1607
OnPointerEventInJsThread(const std::string & typeName,int32_t fingers)1608 void JsInputMonitor::OnPointerEventInJsThread(const std::string &typeName, int32_t fingers)
1609 {
1610 CALL_DEBUG_ENTER;
1611 {
1612 std::lock_guard<std::mutex> guard(mutex_);
1613 if (!isMonitoring_) {
1614 MMI_HILOGE("Js monitor stop");
1615 return;
1616 }
1617 CHKPV(jsEnv_);
1618 CHKPV(receiver_);
1619 while (!evQueue_.empty()) {
1620 if (!isMonitoring_) {
1621 MMI_HILOGE("Js monitor stop handle callback");
1622 break;
1623 }
1624 napi_handle_scope scope = nullptr;
1625 napi_open_handle_scope(jsEnv_, &scope);
1626 CHKPV(scope);
1627 auto pointerEvent = evQueue_.front();
1628 if (pointerEvent == nullptr) {
1629 MMI_HILOGE("Scope is nullptr");
1630 napi_close_handle_scope(jsEnv_, scope);
1631 continue;
1632 }
1633 evQueue_.pop();
1634 pointerQueue_.push(pointerEvent);
1635 napi_close_handle_scope(jsEnv_, scope);
1636 }
1637 }
1638 std::lock_guard<std::mutex> guard(resourcemutex_);
1639 while (!pointerQueue_.empty()) {
1640 auto pointerEventItem = pointerQueue_.front();
1641 pointerQueue_.pop();
1642 napi_handle_scope scope = nullptr;
1643 napi_open_handle_scope(jsEnv_, &scope);
1644 CHKPV(scope);
1645 LogTracer lt(pointerEventItem->GetId(), pointerEventItem->GetEventType(), pointerEventItem->GetPointerAction());
1646 napi_value napiPointer = nullptr;
1647 CHECK_SCOPE_BEFORE_BREAK(jsEnv_, napi_create_object(jsEnv_, &napiPointer),
1648 CREATE_OBJECT, scope, pointerEventItem);
1649 auto ret = RET_ERR;
1650 switch (TO_MONITOR_TYPE[typeName.c_str()]) {
1651 case TypeName::TOUCH: {
1652 ret = TransformPointerEvent(pointerEventItem, napiPointer);
1653 break;
1654 }
1655 case TypeName::MOUSE: {
1656 ret = TransformMousePointerEvent(pointerEventItem, napiPointer);
1657 break;
1658 }
1659 case TypeName::ROTATE: {
1660 if (!IsRotate(pointerEventItem)) {
1661 napi_close_handle_scope(jsEnv_, scope);
1662 continue;
1663 }
1664 ret = TransformRotateEvent(pointerEventItem, napiPointer);
1665 break;
1666 }
1667 case TypeName::PINCH: {
1668 if (!IsPinch(pointerEventItem, fingers)) {
1669 napi_close_handle_scope(jsEnv_, scope);
1670 continue;
1671 }
1672 ret = TransformPinchEvent(pointerEventItem, napiPointer);
1673 break;
1674 }
1675 case TypeName::THREE_FINGERS_SWIPE: {
1676 if (!IsThreeFingersSwipe(pointerEventItem)) {
1677 napi_close_handle_scope(jsEnv_, scope);
1678 continue;
1679 }
1680 ret = TransformSwipeEvent(pointerEventItem, napiPointer);
1681 break;
1682 }
1683 case TypeName::FOUR_FINGERS_SWIPE: {
1684 if (!IsFourFingersSwipe(pointerEventItem)) {
1685 napi_close_handle_scope(jsEnv_, scope);
1686 continue;
1687 }
1688 ret = TransformSwipeEvent(pointerEventItem, napiPointer);
1689 break;
1690 }
1691 case TypeName::THREE_FINGERS_TAP: {
1692 if (!IsThreeFingersTap(pointerEventItem)) {
1693 napi_close_handle_scope(jsEnv_, scope);
1694 continue;
1695 }
1696 ret = TransformMultiTapEvent(pointerEventItem, napiPointer);
1697 break;
1698 }
1699 case TypeName::JOYSTICK:{
1700 if (!IsJoystick(pointerEventItem)) {
1701 napi_close_handle_scope(jsEnv_, scope);
1702 continue;
1703 }
1704 ret = TransformJoystickPointerEvent(pointerEventItem, napiPointer);
1705 break;
1706 }
1707 case TypeName::SWIPE_INWARD: {
1708 if (!IsSwipeInward(pointerEventItem)) {
1709 napi_close_handle_scope(jsEnv_, scope);
1710 continue;
1711 }
1712 ret = TransformSwipeInwardEvent(pointerEventItem, napiPointer);
1713 break;
1714 }
1715 #ifdef OHOS_BUILD_ENABLE_FINGERPRINT
1716 case TypeName::FINGERPRINT: {
1717 if (!IsFingerprint(pointerEventItem)) {
1718 napi_close_handle_scope(jsEnv_, scope);
1719 continue;
1720 }
1721 ret = TransformFingerprintEvent(pointerEventItem, napiPointer);
1722 break;
1723 }
1724 #endif // OHOS_BUILD_ENABLE_FINGERPRINT
1725 case TypeName::TOUCH_GESTURE:
1726 ret = TransformGestureEvent(pointerEventItem, napiPointer);
1727 break;
1728 default: {
1729 MMI_HILOGE("This event is invalid");
1730 break;
1731 }
1732 }
1733 bool checkFlag = ret != RET_OK || napiPointer == nullptr;
1734 if (checkFlag) {
1735 napi_close_handle_scope(jsEnv_, scope);
1736 break;
1737 }
1738 napi_value callback = nullptr;
1739 CHECK_SCOPE_BEFORE_BREAK(jsEnv_, napi_get_reference_value(jsEnv_, receiver_, &callback),
1740 GET_REFERENCE_VALUE, scope, pointerEventItem);
1741 napi_value result = nullptr;
1742 if (monitor_->GetRectTotal() == 0
1743 || IsLocaledWithinRect(jsEnv_, napiPointer, monitor_->GetRectTotal(), monitor_->GetHotRectArea())) {
1744 CHECK_SCOPE_BEFORE_BREAK(jsEnv_, napi_call_function(jsEnv_, nullptr, callback, 1, &napiPointer, &result),
1745 CALL_FUNCTION, scope, pointerEventItem);
1746 }
1747
1748 bool typeNameFlag = typeName == "touch" || typeName == "pinch" || typeName == "threeFingersSwipe" ||
1749 typeName == "fourFingersSwipe" || typeName == "rotate" || typeName == "threeFingersTap" ||
1750 typeName == "joystick" || typeName == "fingerprint" || typeName == "swipeInward" ||
1751 typeName == TOUCH_SWIPE_GESTURE || typeName == TOUCH_PINCH_GESTURE || typeName == TOUCH_ALL_GESTURE;
1752 if (typeNameFlag) {
1753 if (pointerEventItem->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE &&
1754 pointerEventItem->GetPointerAction() != PointerEvent::POINTER_ACTION_PULL_MOVE) {
1755 MMI_HILOGI("PointerId:%{public}d, PointerAction:%{public}s", pointerEventItem->GetPointerId(),
1756 pointerEventItem->DumpPointerAction());
1757 }
1758 bool retValue = false;
1759 CHKRV_SCOPE(jsEnv_, napi_get_value_bool(jsEnv_, result, &retValue), GET_VALUE_BOOL, scope);
1760 CheckConsumed(retValue, pointerEventItem);
1761 }
1762 napi_close_handle_scope(jsEnv_, scope);
1763 }
1764 }
1765
IsLocaledWithinRect(napi_env env,napi_value napiPointer,uint32_t rectTotal,std::vector<Rect> hotRectArea)1766 bool JsInputMonitor::IsLocaledWithinRect(napi_env env, napi_value napiPointer,
1767 uint32_t rectTotal, std::vector<Rect> hotRectArea)
1768 {
1769 napi_value xProperty;
1770 CHKRF(napi_get_named_property(env, napiPointer, "screenX", &xProperty), GET_NAMED_PROPERTY);
1771 CHKPF(xProperty);
1772 int32_t xInt { 0 };
1773 CHKRF(napi_get_value_int32(env, xProperty, &xInt), GET_VALUE_INT32);
1774
1775 napi_value yProperty;
1776 CHKRF(napi_get_named_property(env, napiPointer, "screenY", &yProperty), GET_NAMED_PROPERTY);
1777 CHKPF(yProperty);
1778 int32_t yInt { 0 };
1779 CHKRF(napi_get_value_int32(env, yProperty, &yInt), GET_VALUE_INT32);
1780
1781 for (uint32_t i = 0; i < rectTotal; i++) {
1782 int32_t hotAreaX = hotRectArea.at(i).x;
1783 int32_t hotAreaY = hotRectArea.at(i).y;
1784 int32_t hotAreaWidth = hotRectArea.at(i).width;
1785 int32_t hotAreaHeight = hotRectArea.at(i).height;
1786 if ((xInt >= hotAreaX) && (xInt <= hotAreaX + hotAreaWidth)
1787 && (yInt >= hotAreaY) && (yInt <= hotAreaY + hotAreaHeight)) {
1788 return true;
1789 }
1790 }
1791 return false;
1792 }
1793
CheckConsumed(bool retValue,std::shared_ptr<PointerEvent> pointerEvent)1794 void JsInputMonitor::CheckConsumed(bool retValue, std::shared_ptr<PointerEvent> pointerEvent)
1795 {
1796 CALL_DEBUG_ENTER;
1797 CHKPV(pointerEvent);
1798 if (retValue) {
1799 auto eventId = pointerEvent->GetId();
1800 MarkConsumed(eventId);
1801 }
1802 }
1803
IsPinch(std::shared_ptr<PointerEvent> pointerEvent,const int32_t fingers)1804 bool JsInputMonitor::IsPinch(std::shared_ptr<PointerEvent> pointerEvent, const int32_t fingers)
1805 {
1806 CHKPF(pointerEvent);
1807 if ((fingers > 0 && ((pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_MOUSE &&
1808 pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD) ||
1809 pointerEvent->GetFingerCount() != fingers)) ||
1810 (fingers == 0 && (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
1811 pointerEvent->GetFingerCount() < THREE_FINGERS))) {
1812 return false;
1813 }
1814 if ((pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_BEGIN &&
1815 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_UPDATE &&
1816 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_AXIS_END)) {
1817 return false;
1818 }
1819 return true;
1820 }
1821
IsRotate(std::shared_ptr<PointerEvent> pointerEvent)1822 bool JsInputMonitor::IsRotate(std::shared_ptr<PointerEvent> pointerEvent)
1823 {
1824 CHKPF(pointerEvent);
1825 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_MOUSE ||
1826 (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_BEGIN &&
1827 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_UPDATE &&
1828 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_ROTATE_END)) {
1829 return false;
1830 }
1831 return true;
1832 }
1833
1834
IsThreeFingersSwipe(std::shared_ptr<PointerEvent> pointerEvent)1835 bool JsInputMonitor::IsThreeFingersSwipe(std::shared_ptr<PointerEvent> pointerEvent)
1836 {
1837 CHKPF(pointerEvent);
1838 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
1839 pointerEvent->GetFingerCount() != THREE_FINGERS ||
1840 (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_BEGIN &&
1841 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE &&
1842 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_END)) {
1843 return false;
1844 }
1845 return true;
1846 }
1847
IsFourFingersSwipe(std::shared_ptr<PointerEvent> pointerEvent)1848 bool JsInputMonitor::IsFourFingersSwipe(std::shared_ptr<PointerEvent> pointerEvent)
1849 {
1850 CHKPF(pointerEvent);
1851 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
1852 pointerEvent->GetFingerCount() != FOUR_FINGERS ||
1853 (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_BEGIN &&
1854 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE &&
1855 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_END)) {
1856 return false;
1857 }
1858 return true;
1859 }
1860
IsThreeFingersTap(std::shared_ptr<PointerEvent> pointerEvent)1861 bool JsInputMonitor::IsThreeFingersTap(std::shared_ptr<PointerEvent> pointerEvent)
1862 {
1863 CHKPF(pointerEvent);
1864 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD ||
1865 pointerEvent->GetFingerCount() != THREE_FINGERS ||
1866 (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_TRIPTAP)) {
1867 return false;
1868 }
1869 return true;
1870 }
1871
IsJoystick(std::shared_ptr<PointerEvent> pointerEvent)1872 bool JsInputMonitor::IsJoystick(std::shared_ptr<PointerEvent> pointerEvent)
1873 {
1874 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1875
1876 return (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_JOYSTICK &&
1877 (pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_BUTTON_UP ||
1878 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_BUTTON_DOWN ||
1879 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_AXIS_UPDATE));
1880 }
1881
IsSwipeInward(std::shared_ptr<PointerEvent> pointerEvent)1882 bool JsInputMonitor::IsSwipeInward(std::shared_ptr<PointerEvent> pointerEvent)
1883 {
1884 CHKPF(pointerEvent);
1885 if (pointerEvent->GetSourceType() != PointerEvent::SOURCE_TYPE_TOUCHPAD) {
1886 MMI_HILOGE("Failed to do swipe inward, wrong source:%{public}d ", pointerEvent->GetSourceType());
1887 return false;
1888 } else if (pointerEvent->GetFingerCount() != ONE_FINGERS) {
1889 MMI_HILOGE("Failed to do swipe inward, more than one finger");
1890 return false;
1891 } else if (pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_DOWN &&
1892 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_MOVE &&
1893 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_UP &&
1894 pointerEvent->GetPointerAction() != PointerEvent::POINTER_ACTION_CANCEL) {
1895 MMI_HILOGE("Failed to do swipe inward, wrong action");
1896 return false;
1897 }
1898 return true;
1899 }
1900
IsFingerprint(std::shared_ptr<PointerEvent> pointerEvent)1901 bool JsInputMonitor::IsFingerprint(std::shared_ptr<PointerEvent> pointerEvent)
1902 {
1903 CHKPR(pointerEvent, ERROR_NULL_POINTER);
1904 if (pointerEvent->GetSourceType() == PointerEvent::SOURCE_TYPE_FINGERPRINT &&
1905 ((PointerEvent::POINTER_ACTION_FINGERPRINT_DOWN <= pointerEvent->GetPointerAction() &&
1906 pointerEvent->GetPointerAction() <= PointerEvent::POINTER_ACTION_FINGERPRINT_CLICK) ||
1907 pointerEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_FINGERPRINT_CANCEL)) {
1908 return true;
1909 }
1910 MMI_HILOGD("Not fingerprint event");
1911 return false;
1912 }
1913
OnKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)1914 void JsInputMonitor::OnKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
1915 {
1916 CALL_DEBUG_ENTER;
1917 if (!isMonitoring_) {
1918 MMI_HILOGE("Js monitor stop");
1919 return;
1920 }
1921 CHKPV(monitor_);
1922 CHKPV(keyEvent);
1923 preEvQueue_.Push(keyEvent);
1924 if (!preEvQueue_.Empty()) {
1925 uv_work_t *work = new (std::nothrow) uv_work_t;
1926 CHKPV(work);
1927 MonitorInfo *monitorInfo = new (std::nothrow) MonitorInfo();
1928 if (monitorInfo == nullptr) {
1929 MMI_HILOGE("The monitorInfo is nullptr");
1930 delete work;
1931 work = nullptr;
1932 return;
1933 }
1934 monitorInfo->monitorId = monitorId_;
1935 work->data = monitorInfo;
1936 uv_loop_s *loop = nullptr;
1937 auto status = napi_get_uv_event_loop(jsEnv_, &loop);
1938 if (status != napi_ok) {
1939 THROWERR(jsEnv_, "napi_get_uv_event_loop is failed");
1940 CleanData(&monitorInfo, &work);
1941 return;
1942 }
1943 int32_t ret = uv_queue_work_with_qos(
1944 loop,
1945 work,
1946 [](uv_work_t *work) { MMI_HILOGD("uv_queue_work callback function is called"); },
1947 &JsInputMonitor::JsPreCallback,
1948 uv_qos_user_initiated);
1949 if (ret != 0) {
1950 MMI_HILOGE("Add uv_queue failed, ret is %{public}d", ret);
1951 CleanData(&monitorInfo, &work);
1952 }
1953 }
1954 }
1955
JsPreCallback(uv_work_t * work,int32_t status)1956 void JsInputMonitor::JsPreCallback(uv_work_t *work, int32_t status)
1957 {
1958 CALL_DEBUG_ENTER;
1959 CHKPV(work);
1960 auto temp = static_cast<MonitorInfo*>(work->data);
1961 delete work;
1962 work = nullptr;
1963 auto jsMonitor { JS_INPUT_MONITOR_MGR.GetPreMonitor(temp->monitorId) };
1964 CHKPV(jsMonitor);
1965 jsMonitor->OnKeyEventInJsThread(jsMonitor->GetTypeName());
1966 delete temp;
1967 temp = nullptr;
1968 }
1969
OnKeyEventInJsThread(const std::string & typeName)1970 void JsInputMonitor::OnKeyEventInJsThread(const std::string &typeName)
1971 {
1972 CALL_DEBUG_ENTER;
1973 std::lock_guard<std::mutex> guard(resourcemutex_);
1974 if (!isMonitoring_) {
1975 MMI_HILOGE("Js monitor stop");
1976 return;
1977 }
1978 CHKPV(jsEnv_);
1979 CHKPV(receiver_);
1980 while (!preEvQueue_.Empty()) {
1981 auto keyEventItem = preEvQueue_.Front();
1982 preEvQueue_.Pop();
1983 napi_handle_scope scope = nullptr;
1984 napi_open_handle_scope(jsEnv_, &scope);
1985 CHKPV(scope);
1986 napi_value napiKeyEvent = nullptr;
1987 auto status = napi_create_object(jsEnv_, &napiKeyEvent);
1988 if (status != napi_ok) {
1989 napi_close_handle_scope(jsEnv_, scope);
1990 break;
1991 }
1992 auto ret = RET_ERR;
1993 switch (TO_PRE_MONITOR_TYPE[typeName.c_str()]) {
1994 case TypeName::PRE_KEY: {
1995 ret = TransformKeyEvent(keyEventItem, napiKeyEvent);
1996 break;
1997 }
1998 default: {
1999 MMI_HILOGE("This event is invalid");
2000 break;
2001 }
2002 }
2003 bool checkFlag = ret != RET_OK || napiKeyEvent == nullptr;
2004 if (checkFlag) {
2005 napi_close_handle_scope(jsEnv_, scope);
2006 break;
2007 }
2008 napi_value callback = nullptr;
2009 status = napi_get_reference_value(jsEnv_, receiver_, &callback);
2010 if (status != napi_ok) {
2011 napi_close_handle_scope(jsEnv_, scope);
2012 break;
2013 }
2014 napi_value result = nullptr;
2015 if (napi_call_function(jsEnv_, nullptr, callback, 1, &napiKeyEvent, &result) != napi_ok) {
2016 napi_close_handle_scope(jsEnv_, scope);
2017 return;
2018 }
2019 napi_close_handle_scope(jsEnv_, scope);
2020 }
2021 }
2022
TransformKeyEvent(const std::shared_ptr<KeyEvent> keyEvent,napi_value result)2023 int32_t JsInputMonitor::TransformKeyEvent(const std::shared_ptr<KeyEvent> keyEvent, napi_value result)
2024 {
2025 CHKPR(keyEvent, ERROR_NULL_POINTER);
2026 // set inputEvent
2027 if (SetInputEventProperty(keyEvent, result) != RET_OK) {
2028 MMI_HILOGE("Set inputEvent property failed");
2029 return RET_ERR;
2030 }
2031
2032 // set action
2033 if (SetNameProperty(jsEnv_, result, "action", GetKeyEventAction(keyEvent->GetKeyAction())) != napi_ok) {
2034 MMI_HILOGE("Set action property failed");
2035 return RET_ERR;
2036 }
2037
2038 // set key
2039 napi_value keyObject = nullptr;
2040 CHKRR(napi_create_object(jsEnv_, &keyObject), "napi_create_object is ", RET_ERR);
2041 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
2042 if (!keyItem) {
2043 MMI_HILOGE("The keyItem is nullopt");
2044 return false;
2045 }
2046 GetJsKeyItem(keyItem, keyObject);
2047 if (SetNameProperty(jsEnv_, result, "key", keyObject) != napi_ok) {
2048 MMI_HILOGE("Set key property failed");
2049 return RET_ERR;
2050 }
2051
2052 // set unicodeChar
2053 if (SetNameProperty(jsEnv_, result, "unicodeChar", keyItem->GetUnicode()) != napi_ok) {
2054 MMI_HILOGE("Set unicodeChar property failed");
2055 return RET_ERR;
2056 }
2057
2058 std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
2059 // set keys
2060 if (!GetKeys(keyEvent, pressedKeys, result)) {
2061 MMI_HILOGE("Get pressedKeys failed");
2062 return RET_ERR;
2063 }
2064
2065 if (!GetPressedKey(pressedKeys, result)) {
2066 MMI_HILOGE("Get single pressedKey failed");
2067 return RET_ERR;
2068 }
2069
2070 if (!GetFunctionKeyState(keyEvent, result)) {
2071 MMI_HILOGE("Get FunctionKey failed");
2072 return RET_ERR;
2073 }
2074
2075 return RET_OK;
2076 }
2077
GetKeyEventAction(int32_t action) const2078 int32_t JsInputMonitor::GetKeyEventAction(int32_t action) const
2079 {
2080 if (KeyEvent::KEY_ACTION_CANCEL == action) {
2081 return InputKeyEventAction::KEY_ACTION_CANCEL;
2082 } else if (KeyEvent::KEY_ACTION_DOWN == action) {
2083 return InputKeyEventAction::KEY_ACTION_DOWN;
2084 } else if (KeyEvent::KEY_ACTION_UP == action) {
2085 return InputKeyEventAction::KEY_ACTION_UP;
2086 } else {
2087 return RET_ERR;
2088 }
2089 }
2090
GetJsKeyItem(const std::optional<MMI::KeyEvent::KeyItem> keyItem,napi_value value) const2091 int32_t JsInputMonitor::GetJsKeyItem(const std::optional<MMI::KeyEvent::KeyItem> keyItem, napi_value value) const
2092 {
2093 CALL_DEBUG_ENTER;
2094 CHKRR(SetNameProperty(jsEnv_, value, "code", keyItem->GetKeyCode()), "Set code", RET_ERR);
2095 CHKRR(SetNameProperty(jsEnv_, value, "pressedTime", keyItem->GetDownTime()), "Set pressedTime", RET_ERR);
2096 CHKRR(SetNameProperty(jsEnv_, value, "deviceId", keyItem->GetDeviceId()), "Set deviceId", RET_ERR);
2097 return RET_OK;
2098 }
2099
GetFunctionKeyState(const std::shared_ptr<KeyEvent> keyEvent,napi_value result) const2100 bool JsInputMonitor::GetFunctionKeyState(const std::shared_ptr<KeyEvent> keyEvent, napi_value result) const
2101 {
2102 CALL_DEBUG_ENTER;
2103 // set capsLock
2104 napi_value capsLockValue = nullptr;
2105 napi_status status =
2106 napi_get_boolean(jsEnv_, keyEvent->GetFunctionKey(KeyEvent::CAPS_LOCK_FUNCTION_KEY), &capsLockValue);
2107 if (status != napi_ok) {
2108 return false;
2109 }
2110 if (SetNameProperty(jsEnv_, result, "capsLock", capsLockValue) != napi_ok) {
2111 MMI_HILOGE("Set capsLock property failed");
2112 return false;
2113 }
2114
2115 // set numLock
2116 napi_value numLockValue = nullptr;
2117 if (napi_get_boolean(jsEnv_, keyEvent->GetFunctionKey(KeyEvent::NUM_LOCK_FUNCTION_KEY), &numLockValue) != napi_ok) {
2118 return false;
2119 }
2120 if (SetNameProperty(jsEnv_, result, "numLock", numLockValue) != napi_ok) {
2121 MMI_HILOGE("Set numLock property failed");
2122 return false;
2123 }
2124
2125 // set scrollLock
2126 napi_value scrollLockValue = nullptr;
2127 if (napi_get_boolean(jsEnv_, keyEvent->GetFunctionKey(KeyEvent::SCROLL_LOCK_FUNCTION_KEY), &scrollLockValue) !=
2128 napi_ok) {
2129 return false;
2130 }
2131 if (SetNameProperty(jsEnv_, result, "scrollLock", scrollLockValue) != napi_ok) {
2132 MMI_HILOGE("Set scrollLock property failed");
2133 return false;
2134 }
2135 return true;
2136 }
2137
GetKeys(const std::shared_ptr<KeyEvent> keyEvent,const std::vector<int32_t> & pressedKeys,napi_value result) const2138 bool JsInputMonitor::GetKeys(
2139 const std::shared_ptr<KeyEvent> keyEvent, const std::vector<int32_t> &pressedKeys, napi_value result) const
2140 {
2141 CALL_DEBUG_ENTER;
2142 napi_value keysArray = nullptr;
2143 napi_status status = napi_create_array(jsEnv_, &keysArray);
2144 if (status != napi_ok || keysArray == nullptr) {
2145 THROWERR(jsEnv_, "napi_create_array is failed");
2146 return false;
2147 }
2148 uint32_t index = 0;
2149 for (const auto &pressedKeyCode : pressedKeys) {
2150 napi_value element = nullptr;
2151 if (napi_create_object(jsEnv_, &element) != napi_ok) {
2152 THROWERR(jsEnv_, "Napi create element failed");
2153 return false;
2154 }
2155 std::optional<KeyEvent::KeyItem> pressedKeyItem = keyEvent->GetKeyItem(pressedKeyCode);
2156 if (!pressedKeyItem) {
2157 MMI_HILOGE("The pressedKeyItem is nullopt");
2158 return false;
2159 }
2160 GetJsKeyItem(pressedKeyItem, element);
2161
2162 if (napi_set_element(jsEnv_, keysArray, index, element)) {
2163 THROWERR(jsEnv_, "Napi set element failed");
2164 return false;
2165 }
2166 ++index;
2167 }
2168 if (SetNameProperty(jsEnv_, result, "keys", keysArray) != napi_ok) {
2169 MMI_HILOGE("Set keys property failed");
2170 return false;
2171 }
2172 return true;
2173 }
2174 } // namespace MMI
2175 } // namespace OHOS
2176