• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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