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