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