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