• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "core/common/event_manager.h"
17 
18 #include "base/geometry/ng/point_t.h"
19 #include "base/log/ace_trace.h"
20 #include "base/memory/ace_type.h"
21 #include "base/thread/frame_trace_adapter.h"
22 #include "base/utils/utils.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
26 #include "core/event/ace_events.h"
27 #include "core/event/key_event.h"
28 #include "core/event/touch_event.h"
29 #include "core/gestures/gesture_referee.h"
30 #include "core/pipeline/base/element.h"
31 #include "core/pipeline/base/render_node.h"
32 
33 namespace OHOS::Ace {
34 constexpr uint8_t KEYS_MAX_VALUE = 3;
35 const std::string SHORT_CUT_VALUE_X = "X";
36 const std::string SHORT_CUT_VALUE_Y = "Y";
37 const std::string SHORT_CUT_VALUE_Z = "Z";
38 const std::string SHORT_CUT_VALUE_A = "A";
39 const std::string SHORT_CUT_VALUE_C = "C";
40 const std::string SHORT_CUT_VALUE_V = "V";
41 enum class CtrlKeysBit {
42     CTRL = 1,
43     SHIFT = 2,
44     ALT = 4,
45 };
46 
TouchTest(const TouchEvent & touchPoint,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)47 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode,
48     const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
49 {
50     ContainerScope scope(instanceId_);
51 
52     ACE_FUNCTION_TRACE();
53     CHECK_NULL_VOID(renderNode);
54     // first clean.
55     referee_->CleanGestureScope(touchPoint.id);
56     // collect
57     TouchTestResult hitTestResult;
58     const Point point { touchPoint.x, touchPoint.y, touchPoint.sourceType };
59     // For root node, the parent local point is the same as global point.
60     renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
61     if (needAppend) {
62 #ifdef OHOS_STANDARD_SYSTEM
63         for (auto entry = hitTestResult.begin(); entry != hitTestResult.end(); ++entry) {
64             if ((*entry)) {
65                 (*entry)->SetSubPipelineGlobalOffset(offset, viewScale);
66             }
67         }
68 #endif
69         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
70         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
71     }
72     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
73 }
74 
TouchTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)75 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
76     const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
77 {
78     ContainerScope scope(instanceId_);
79 
80     ACE_FUNCTION_TRACE();
81     CHECK_NULL_VOID(frameNode);
82     // collect
83     TouchTestResult hitTestResult;
84     const NG::PointF point { touchPoint.x, touchPoint.y };
85     if (refereeNG_->CheckSourceTypeChange(touchPoint.sourceType)) {
86         refereeNG_->CleanAll(true);
87     }
88     if (refereeNG_->QueryAllDone(touchPoint.id)) {
89         refereeNG_->CleanGestureScope(touchPoint.id);
90     }
91     if (frameNode->HaveSecurityComponent()) {
92         std::vector<NG::RectF> rect;
93         frameNode->CheckSecurityComponentStatus(rect);
94     }
95     if (!needAppend) {
96         NG::NGGestureRecognizer::ResetGlobalTransCfg();
97     }
98     // For root node, the parent local point is the same as global point.
99     frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id);
100     if (needAppend) {
101 #ifdef OHOS_STANDARD_SYSTEM
102         for (const auto& entry : hitTestResult) {
103             if (entry) {
104                 entry->SetSubPipelineGlobalOffset(offset, viewScale);
105             }
106         }
107 #endif
108         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
109         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
110     }
111     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
112 }
113 
TouchTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)114 void EventManager::TouchTest(
115     const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
116 {
117     ContainerScope scope(instanceId_);
118 
119     if (refereeNG_->CheckSourceTypeChange(event.sourceType, true)) {
120         refereeNG_->CleanAll(true);
121     }
122     ACE_FUNCTION_TRACE();
123     CHECK_NULL_VOID(frameNode);
124     // collect
125     const NG::PointF point { event.x, event.y };
126     if (frameNode->HaveSecurityComponent()) {
127         std::vector<NG::RectF> rect;
128         frameNode->CheckSecurityComponentStatus(rect);
129     }
130     // For root node, the parent local point is the same as global point.
131     TouchTestResult hitTestResult;
132     frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, event.id);
133     axisTouchTestResults_[event.id] = std::move(hitTestResult);
134 }
135 
HandleGlobalEvent(const TouchEvent & touchPoint,const RefPtr<TextOverlayManager> & textOverlayManager)136 void EventManager::HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager)
137 {
138     if (touchPoint.type != TouchType::DOWN) {
139         return;
140     }
141     auto coordinateOffset = textOverlayManager->GetCoordinateOffset();
142     const Point point { touchPoint.x - coordinateOffset.GetX(), touchPoint.y - coordinateOffset.GetY(),
143         touchPoint.sourceType };
144     CHECK_NULL_VOID_NOLOG(textOverlayManager);
145     auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
146     CHECK_NULL_VOID_NOLOG(textOverlayBase);
147     auto targetNode = textOverlayManager->GetTargetNode();
148     CHECK_NULL_VOID_NOLOG(targetNode);
149     for (auto& rect : textOverlayManager->GetTextOverlayRect()) {
150         if (rect.IsInRegion(point)) {
151             inSelectedRect_ = true;
152         }
153     }
154     for (auto& rect : textOverlayBase->GetSelectedRect()) {
155         if (rect.IsInRegion(point)) {
156             inSelectedRect_ = true;
157         }
158     }
159     if (!inSelectedRect_) {
160         textOverlayManager->PopTextOverlay();
161         textOverlayBase->ChangeSelection(0, 0);
162         textOverlayBase->MarkIsOverlayShowed(false);
163         targetNode->MarkNeedRender();
164     }
165     inSelectedRect_ = false;
166 }
167 
HandleGlobalEventNG(const TouchEvent & touchPoint,const RefPtr<NG::SelectOverlayManager> & selectOverlayManager,const NG::OffsetF & rootOffset)168 void EventManager::HandleGlobalEventNG(const TouchEvent& touchPoint,
169     const RefPtr<NG::SelectOverlayManager>& selectOverlayManager, const NG::OffsetF& rootOffset)
170 {
171     CHECK_NULL_VOID_NOLOG(selectOverlayManager);
172     if (touchPoint.type == TouchType::DOWN &&
173         touchTestResults_.find(touchPoint.id) != touchTestResults_.end()) {
174         std::vector<std::string> touchTestIds;
175         const auto& resultList = touchTestResults_[touchPoint.id];
176         for (const auto& result : resultList) {
177             auto eventTarget = result->GetEventTarget();
178             if (eventTarget.has_value()) {
179                 touchTestIds.emplace_back(eventTarget.value().id);
180             }
181         }
182         selectOverlayManager->SetOnTouchTestResults(touchTestIds);
183     }
184     selectOverlayManager->HandleGlobalEvent(touchPoint, rootOffset);
185 }
186 
HandleOutOfRectCallback(const Point & point,std::vector<RectCallback> & rectCallbackList)187 void EventManager::HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList)
188 {
189     for (auto iter = rectCallbackList.begin(); iter != rectCallbackList.end();) {
190         auto rectCallback = *iter;
191         auto rectGetCallback = rectCallback.rectGetCallback;
192         if (!rectGetCallback) {
193             ++iter;
194             continue;
195         }
196         std::vector<Rect> rectList;
197         rectGetCallback(rectList);
198         if (std::any_of(
199                 rectList.begin(), rectList.end(), [point](const Rect& rect) { return rect.IsInRegion(point); })) {
200             ++iter;
201             continue;
202         }
203         for (const auto& rect : rectList) {
204             LOGI("Point(%{public}f, %{public}f) out of Rect-[%{public}f, %{public}f, %{public}f, %{public}f]",
205                 point.GetX(), point.GetY(), rect.Left(), rect.Right(), rect.Top(), rect.Bottom());
206         }
207         if (point.GetSourceType() == SourceType::TOUCH) {
208             if (!rectCallback.touchCallback) {
209                 ++iter;
210                 continue;
211             }
212             rectCallback.touchCallback();
213         } else if (point.GetSourceType() == SourceType::MOUSE) {
214             if (!rectCallback.mouseCallback) {
215                 ++iter;
216                 continue;
217             }
218             rectCallback.mouseCallback();
219         }
220         iter = rectCallbackList.erase(iter);
221     }
222 }
223 
TouchTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict)224 void EventManager::TouchTest(
225     const AxisEvent& event, const RefPtr<RenderNode>& renderNode, const TouchRestrict& touchRestrict)
226 {
227     ContainerScope scope(instanceId_);
228 
229     ACE_FUNCTION_TRACE();
230     CHECK_NULL_VOID(renderNode);
231     // collect
232     const Point point { event.x, event.y, event.sourceType };
233     // For root node, the parent local point is the same as global point.
234     TouchTestResult hitTestResult;
235     renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
236     axisTouchTestResults_[event.id] = std::move(hitTestResult);
237 }
238 
FlushTouchEventsBegin(const std::list<TouchEvent> & touchEvents)239 void EventManager::FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents)
240 {
241     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
242         const auto result = touchTestResults_.find((*iter).id);
243         if (result != touchTestResults_.end()) {
244             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
245                 (*entry)->OnFlushTouchEventsBegin();
246             }
247         }
248     }
249 }
250 
FlushTouchEventsEnd(const std::list<TouchEvent> & touchEvents)251 void EventManager::FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents)
252 {
253     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
254         const auto result = touchTestResults_.find((*iter).id);
255         if (result != touchTestResults_.end()) {
256             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
257                 (*entry)->OnFlushTouchEventsEnd();
258             }
259         }
260     }
261 }
262 
DispatchTouchEvent(const TouchEvent & event)263 bool EventManager::DispatchTouchEvent(const TouchEvent& event)
264 {
265     ContainerScope scope(instanceId_);
266     TouchEvent point = event;
267 #ifdef ENABLE_DRAG_FRAMEWORK
268     if (isDragging_ && point.type == TouchType::PULL_MOVE) {
269         isDragging_ = false;
270         point.type = TouchType::CANCEL;
271     }
272     if (point.type == TouchType::PULL_UP || point.type == TouchType::UP) {
273         isDragging_ = false;
274         point.type = TouchType::UP;
275     }
276 #endif // ENABLE_DRAG_FRAMEWORK
277     ACE_FUNCTION_TRACE();
278     const auto iter = touchTestResults_.find(point.id);
279     if (iter == touchTestResults_.end()) {
280         LOGI("the %{public}d touch test result does not exist!", point.id);
281         return false;
282     }
283 
284     if (point.type == TouchType::DOWN) {
285         // first collect gesture into gesture referee.
286         if (Container::IsCurrentUseNewPipeline()) {
287             refereeNG_->AddGestureToScope(point.id, iter->second);
288         }
289     }
290 
291     bool dispatchSuccess = true;
292     for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
293         if (!(*entry)->DispatchMultiContainerEvent(point)) {
294             dispatchSuccess = false;
295             break;
296         }
297     }
298     // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
299     // the event, each recognizer needs to filter the extra events by itself.
300     if (dispatchSuccess) {
301         if (Container::IsCurrentUseNewPipeline()) {
302             // Need update here: onTouch/Recognizer need update
303             bool isStopTouchEvent = false;
304             for (const auto& entry : iter->second) {
305                 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
306                 if (recognizer) {
307                     entry->HandleMultiContainerEvent(point);
308                 }
309                 if (!recognizer && !isStopTouchEvent) {
310                     isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
311                 }
312             }
313         } else {
314             for (const auto& entry : iter->second) {
315                 if (!entry->HandleMultiContainerEvent(point)) {
316                     break;
317                 }
318             }
319         }
320     }
321 
322     if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
323         FrameTraceAdapter* ft = FrameTraceAdapter::GetInstance();
324         if (ft != nullptr) {
325             ft->SetFrameTraceLimit();
326         }
327         refereeNG_->CleanGestureScope(point.id);
328         referee_->CleanGestureScope(point.id);
329         touchTestResults_.erase(point.id);
330     }
331 
332     return true;
333 }
334 
DispatchTouchEvent(const AxisEvent & event)335 bool EventManager::DispatchTouchEvent(const AxisEvent& event)
336 {
337     ContainerScope scope(instanceId_);
338 
339     const auto curResultIter = axisTouchTestResults_.find(event.id);
340     if (curResultIter == axisTouchTestResults_.end()) {
341         LOGI("the %{public}d axis test result does not exist!", event.id);
342         return false;
343     }
344     if (event.action == AxisAction::BEGIN) {
345         // first collect gesture into gesture referee.
346         if (Container::IsCurrentUseNewPipeline()) {
347             if (refereeNG_) {
348                 refereeNG_->AddGestureToScope(event.id, curResultIter->second);
349             }
350         }
351     }
352 
353     ACE_FUNCTION_TRACE();
354     for (const auto& entry : curResultIter->second) {
355         if (!entry->HandleEvent(event)) {
356             break;
357         }
358     }
359     if (event.action == AxisAction::END || event.action == AxisAction::NONE || event.action == AxisAction::CANCEL) {
360         if (Container::IsCurrentUseNewPipeline()) {
361             if (refereeNG_) {
362                 refereeNG_->CleanGestureScope(event.id);
363             }
364         }
365         axisTouchTestResults_.erase(event.id);
366     }
367     return true;
368 }
369 
DispatchTabIndexEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode,const RefPtr<FocusGroup> & mainNode)370 bool EventManager::DispatchTabIndexEvent(
371     const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& mainNode)
372 {
373     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
374         event.action, event.repeatTime);
375     CHECK_NULL_RETURN(focusNode, false);
376     CHECK_NULL_RETURN(mainNode, false);
377     if (focusNode->HandleFocusByTabIndex(event, mainNode)) {
378         LOGI("Tab index focus system handled this event");
379         return true;
380     }
381     return false;
382 }
383 
DispatchKeyEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode)384 bool EventManager::DispatchKeyEvent(const KeyEvent& event, const RefPtr<FocusNode>& focusNode)
385 {
386     CHECK_NULL_RETURN(focusNode, false);
387     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
388         event.action, event.repeatTime);
389     if (focusNode->HandleKeyEvent(event)) {
390         LOGI("Default focus system handled this event");
391         return true;
392     }
393     LOGD("Use platform to handle this event");
394     return false;
395 }
396 
DispatchTabIndexEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode,const RefPtr<NG::FrameNode> & mainNode)397 bool EventManager::DispatchTabIndexEventNG(
398     const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode, const RefPtr<NG::FrameNode>& mainNode)
399 {
400     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
401         event.action, event.repeatTime);
402     CHECK_NULL_RETURN(focusNode, false);
403     CHECK_NULL_RETURN(mainNode, false);
404     auto focusNodeHub = focusNode->GetFocusHub();
405     CHECK_NULL_RETURN(focusNodeHub, false);
406     auto mainNodeHub = mainNode->GetFocusHub();
407     CHECK_NULL_RETURN(mainNodeHub, false);
408     if (focusNodeHub->HandleFocusByTabIndex(event, mainNodeHub)) {
409         LOGI("Tab index focus system handled this event");
410         return true;
411     }
412     return false;
413 }
414 
DispatchKeyEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode)415 bool EventManager::DispatchKeyEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode)
416 {
417     CHECK_NULL_RETURN(focusNode, false);
418     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
419         event.action, event.repeatTime);
420     auto focusNodeHub = focusNode->GetFocusHub();
421     CHECK_NULL_RETURN(focusNodeHub, false);
422     if (focusNodeHub->HandleKeyEvent(event)) {
423         LOGI("Default focus system handled this event");
424         return true;
425     }
426     LOGD("Use platform to handle this event");
427     return false;
428 }
429 
MouseTest(const MouseEvent & event,const RefPtr<RenderNode> & renderNode)430 void EventManager::MouseTest(const MouseEvent& event, const RefPtr<RenderNode>& renderNode)
431 {
432     CHECK_NULL_VOID(renderNode);
433     const Point point { event.x, event.y };
434     MouseHoverTestList hitTestResult;
435     WeakPtr<RenderNode> hoverNode = nullptr;
436     renderNode->MouseDetect(point, point, hitTestResult, hoverNode);
437     if (hitTestResult.empty()) {
438         LOGD("mouse hover test result is empty");
439     }
440     if (event.action == MouseAction::WINDOW_LEAVE) {
441         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
442         mouseHoverTestResults_.clear();
443     } else if (event.action == MouseAction::WINDOW_ENTER) {
444         mouseHoverTestResultsPre_.clear();
445         mouseHoverTestResults_ = std::move(hitTestResult);
446     } else {
447         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
448         mouseHoverTestResults_ = std::move(hitTestResult);
449     }
450     mouseHoverNodePre_ = mouseHoverNode_;
451     mouseHoverNode_ = hoverNode;
452     LOGI("MouseDetect hit test last/new result size = %{public}zu/%{public}zu", mouseHoverTestResultsPre_.size(),
453         mouseHoverTestResults_.size());
454 }
455 
DispatchMouseEvent(const MouseEvent & event)456 bool EventManager::DispatchMouseEvent(const MouseEvent& event)
457 {
458     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
459         event.action == MouseAction::MOVE) {
460         LOGD("RenderBox::HandleMouseEvent, button is %{public}d, action is %{public}d", event.button, event.action);
461         for (const auto& wp : mouseHoverTestResults_) {
462             auto hoverNode = wp.Upgrade();
463             if (hoverNode) {
464                 if (hoverNode->HandleMouseEvent(event)) {
465                     LOGI("Do HandleMouseEvent. Dispatch node: %{public}s", AceType::TypeName(hoverNode));
466                     break;
467                 }
468             }
469         }
470         return true;
471     }
472     return false;
473 }
474 
DispatchMouseHoverAnimation(const MouseEvent & event)475 void EventManager::DispatchMouseHoverAnimation(const MouseEvent& event)
476 {
477     auto hoverNodeCur = mouseHoverNode_.Upgrade();
478     auto hoverNodePre = mouseHoverNodePre_.Upgrade();
479     if (event.action == MouseAction::PRESS) {
480         if (hoverNodeCur) {
481             hoverNodeCur->AnimateMouseHoverExit();
482         }
483     } else if (event.action == MouseAction::RELEASE) {
484         if (hoverNodeCur) {
485             hoverNodeCur->AnimateMouseHoverEnter();
486         }
487     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
488         if (hoverNodeCur != hoverNodePre) {
489             if (hoverNodeCur) {
490                 hoverNodeCur->AnimateMouseHoverEnter();
491             }
492             if (hoverNodePre) {
493                 hoverNodePre->AnimateMouseHoverExit();
494             }
495         }
496     } else if (event.action == MouseAction::WINDOW_ENTER) {
497         if (hoverNodeCur) {
498             hoverNodeCur->AnimateMouseHoverEnter();
499         }
500     } else if (event.action == MouseAction::WINDOW_LEAVE) {
501         if (hoverNodeCur) {
502             hoverNodeCur->AnimateMouseHoverExit();
503         }
504     }
505 }
506 
DispatchMouseHoverEvent(const MouseEvent & event)507 bool EventManager::DispatchMouseHoverEvent(const MouseEvent& event)
508 {
509     for (const auto& wp : mouseHoverTestResultsPre_) {
510         // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
511         auto it = std::find(mouseHoverTestResults_.begin(), mouseHoverTestResults_.end(), wp);
512         if (it == mouseHoverTestResults_.end()) {
513             auto hoverNode = wp.Upgrade();
514             if (hoverNode) {
515                 hoverNode->HandleMouseHoverEvent(MouseState::NONE);
516             }
517         }
518     }
519     for (const auto& wp : mouseHoverTestResults_) {
520         // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
521         auto it = std::find(mouseHoverTestResultsPre_.begin(), mouseHoverTestResultsPre_.end(), wp);
522         if (it == mouseHoverTestResultsPre_.end()) {
523             auto hoverNode = wp.Upgrade();
524             if (hoverNode) {
525                 hoverNode->HandleMouseHoverEvent(MouseState::HOVER);
526             }
527         }
528     }
529     return true;
530 }
531 
LogPrintMouseTest()532 void EventManager::LogPrintMouseTest()
533 {
534 #ifdef ACE_DEBUG_LOG
535     if (!SystemProperties::GetDebugEnabled()) {
536         return;
537     }
538     if (currMouseTestResults_.empty()) {
539         LOGD("Mouse test onMouse result is empty.");
540     } else {
541         for (const auto& result : currMouseTestResults_) {
542             LOGD("Mouse test onMouse result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
543                 result->GetNodeId());
544         }
545     }
546     if (lastHoverTestResults_.empty()) {
547         LOGD("Mouse test onHover last result is empty.");
548     } else {
549         for (const auto& result : lastHoverTestResults_) {
550             LOGD("Mouse test onHover last result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
551                 result->GetNodeId());
552         }
553     }
554     if (currHoverTestResults_.empty()) {
555         LOGD("Mouse test onHover current result is empty.");
556     } else {
557         for (const auto& result : currHoverTestResults_) {
558             LOGD("Mouse test onHover current result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
559                 result->GetNodeId());
560         }
561     }
562     auto lastNode = lastHoverNode_.Upgrade();
563     auto currNode = currHoverNode_.Upgrade();
564     LOGD("Mouse test last/current hoverEffect node: %{public}s/%{public}d / %{public}s/%{public}d",
565         lastNode ? lastNode->GetTag().c_str() : "NULL", lastNode ? lastNode->GetId() : -1,
566         currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
567 #endif
568 }
569 
MouseTest(const MouseEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)570 void EventManager::MouseTest(
571     const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
572 {
573     LOGD("Mouse test start. Mouse event is (%{public}f,%{public}f), button: %{public}d, action: %{public}d", event.x,
574         event.y, event.button, event.action);
575     CHECK_NULL_VOID(frameNode);
576     const NG::PointF point { event.x, event.y };
577     TouchTestResult testResult;
578     if (frameNode->HaveSecurityComponent()) {
579         std::vector<NG::RectF> rect;
580         frameNode->CheckSecurityComponentStatus(rect);
581     }
582     frameNode->TouchTest(point, point, point, touchRestrict, testResult, event.GetId());
583     if (testResult.empty()) {
584         LOGD("mouse hover test result is empty");
585     }
586     currMouseTestResults_.clear();
587     HoverTestResult hoverTestResult;
588     WeakPtr<NG::FrameNode> hoverNode = nullptr;
589     for (const auto& result : testResult) {
590         auto mouseResult = AceType::DynamicCast<MouseEventTarget>(result);
591         if (mouseResult) {
592             currMouseTestResults_.emplace_back(mouseResult);
593         }
594         auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
595         if (hoverResult) {
596             hoverTestResult.emplace_back(hoverResult);
597         }
598         if (!hoverNode.Upgrade()) {
599             auto hoverEffectResult = AceType::DynamicCast<HoverEffectTarget>(result);
600             if (hoverEffectResult) {
601                 hoverNode = hoverEffectResult->GetHoverNode();
602             }
603         }
604     }
605     if (event.action == MouseAction::WINDOW_LEAVE) {
606         lastHoverTestResults_ = std::move(currHoverTestResults_);
607         currHoverTestResults_.clear();
608     } else if (event.action == MouseAction::WINDOW_ENTER) {
609         lastHoverTestResults_.clear();
610         currHoverTestResults_ = std::move(hoverTestResult);
611     } else {
612         lastHoverTestResults_ = std::move(currHoverTestResults_);
613         currHoverTestResults_ = std::move(hoverTestResult);
614     }
615     lastHoverNode_ = currHoverNode_;
616     currHoverNode_ = hoverNode;
617     LogPrintMouseTest();
618     LOGD("Mouse test end.");
619 }
620 
DispatchMouseEventNG(const MouseEvent & event)621 bool EventManager::DispatchMouseEventNG(const MouseEvent& event)
622 {
623     LOGD("DispatchMouseEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
624     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
625         event.action == MouseAction::MOVE || event.action == MouseAction::WINDOW_ENTER ||
626         event.action == MouseAction::WINDOW_LEAVE) {
627         MouseTestResult handledResults;
628         handledResults.clear();
629         auto container = Container::Current();
630         CHECK_NULL_RETURN(container, false);
631         if ((event.button == MouseButton::LEFT_BUTTON && !container->IsScenceBoardWindow()) ||
632             (event.button == MouseButton::LEFT_BUTTON && container->IsScenceBoardWindow() &&
633             event.pullAction != MouseAction::PULL_UP && event.pullAction != MouseAction::PULL_MOVE)) {
634             for (const auto& mouseTarget : pressMouseTestResults_) {
635                 if (mouseTarget) {
636                     handledResults.emplace_back(mouseTarget);
637                     if (mouseTarget->HandleMouseEvent(event)) {
638                         break;
639                     }
640                 }
641             }
642             if (event.action == MouseAction::PRESS) {
643                 pressMouseTestResults_ = currMouseTestResults_;
644             } else if (event.action == MouseAction::RELEASE) {
645                 DoMouseActionRelease();
646             }
647         }
648         if (event.pullAction == MouseAction::PULL_UP) {
649             DoMouseActionRelease();
650         }
651         for (const auto& mouseTarget : currMouseTestResults_) {
652             if (mouseTarget &&
653                 std::find(handledResults.begin(), handledResults.end(), mouseTarget) == handledResults.end()) {
654                 if (mouseTarget->HandleMouseEvent(event)) {
655                     return true;
656                 }
657             }
658         }
659     }
660     return false;
661 }
662 
DoMouseActionRelease()663 void EventManager::DoMouseActionRelease()
664 {
665     pressMouseTestResults_.clear();
666 }
667 
DispatchMouseHoverAnimationNG(const MouseEvent & event)668 void EventManager::DispatchMouseHoverAnimationNG(const MouseEvent& event)
669 {
670     LOGD("DispatchMouseHoverAnimationNG: button is %{public}d, action is %{public}d.", event.button, event.action);
671     auto hoverNodeCur = currHoverNode_.Upgrade();
672     auto hoverNodePre = lastHoverNode_.Upgrade();
673     if (event.action == MouseAction::PRESS) {
674         if (hoverNodeCur) {
675             hoverNodeCur->AnimateHoverEffect(false);
676         }
677     } else if (event.action == MouseAction::RELEASE) {
678         if (hoverNodeCur) {
679             hoverNodeCur->AnimateHoverEffect(true);
680         }
681     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
682         if (hoverNodeCur != hoverNodePre) {
683             if (hoverNodeCur) {
684                 hoverNodeCur->AnimateHoverEffect(true);
685             }
686             if (hoverNodePre) {
687                 hoverNodePre->AnimateHoverEffect(false);
688             }
689         }
690     } else if (event.action == MouseAction::WINDOW_ENTER) {
691         if (hoverNodeCur) {
692             hoverNodeCur->AnimateHoverEffect(true);
693         }
694     } else if (event.action == MouseAction::WINDOW_LEAVE) {
695         if (hoverNodeCur) {
696             hoverNodeCur->AnimateHoverEffect(false);
697         }
698     }
699 }
700 
DispatchMouseHoverEventNG(const MouseEvent & event)701 bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
702 {
703     LOGD("DispatchMouseHoverEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
704     auto lastHoverEndNode = lastHoverTestResults_.begin();
705     auto currHoverEndNode = currHoverTestResults_.begin();
706     RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
707     uint32_t iterCountLast = 0;
708     uint32_t iterCountCurr = 0;
709     for (const auto& hoverResult : lastHoverTestResults_) {
710         // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
711         // there may have some nodes in currHoverTestResults_ but intercepted
712         iterCountLast++;
713         if (lastHoverEndNode != currHoverTestResults_.end()) {
714             lastHoverEndNode++;
715         }
716         if (std::find(currHoverTestResults_.begin(), currHoverTestResults_.end(), hoverResult) ==
717             currHoverTestResults_.end()) {
718             hoverResult->HandleHoverEvent(false, event);
719         }
720         if ((iterCountLast >= lastHoverDispatchLength_) && (lastHoverDispatchLength_ != 0)) {
721             lastHoverEndNodeTarget = hoverResult;
722             break;
723         }
724     }
725     lastHoverDispatchLength_ = 0;
726     for (const auto& hoverResult : currHoverTestResults_) {
727         // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
728         // the valid part stops at first interception
729         iterCountCurr++;
730         if (currHoverEndNode != currHoverTestResults_.end()) {
731             currHoverEndNode++;
732         }
733         if (std::find(lastHoverTestResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
734             if (!hoverResult->HandleHoverEvent(true, event)) {
735                 lastHoverDispatchLength_ = iterCountCurr;
736                 break;
737             }
738         }
739         if (hoverResult == lastHoverEndNodeTarget) {
740             lastHoverDispatchLength_ = iterCountCurr;
741             break;
742         }
743     }
744     for (auto hoverResultIt = lastHoverTestResults_.begin(); hoverResultIt != lastHoverEndNode; ++hoverResultIt) {
745         // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
746         if (std::find(currHoverEndNode, currHoverTestResults_.end(), *hoverResultIt) != currHoverTestResults_.end()) {
747             (*hoverResultIt)->HandleHoverEvent(false, event);
748         }
749     }
750     return true;
751 }
752 
AxisTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode)753 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
754 {
755     CHECK_NULL_VOID(renderNode);
756     const Point point { event.x, event.y };
757     WeakPtr<RenderNode> axisNode = nullptr;
758     renderNode->AxisDetect(point, point, axisNode, event.GetDirection());
759     axisNode_ = axisNode;
760     LOGI("Current axis node is %{public}s", AceType::TypeName(axisNode_.Upgrade()));
761 }
762 
DispatchAxisEvent(const AxisEvent & event)763 bool EventManager::DispatchAxisEvent(const AxisEvent& event)
764 {
765     auto responseNode = axisNode_.Upgrade();
766     if (responseNode) {
767         responseNode->HandleAxisEvent(event);
768     }
769     return true;
770 }
771 
AxisTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode)772 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode)
773 {
774     CHECK_NULL_VOID(frameNode);
775     const NG::PointF point { event.x, event.y };
776     frameNode->AxisTest(point, point, axisTestResults_);
777 }
778 
DispatchAxisEventNG(const AxisEvent & event)779 bool EventManager::DispatchAxisEventNG(const AxisEvent& event)
780 {
781     if (event.horizontalAxis == 0 && event.verticalAxis == 0 && event.pinchAxisScale == 0) {
782         return false;
783     }
784     LOGD("DispatchAxisEventNG, action is %{public}d, axis is %{public}f / %{public}f / %{public}f", event.action,
785         event.horizontalAxis, event.verticalAxis, event.pinchAxisScale);
786     for (const auto& axisTarget : axisTestResults_) {
787         if (axisTarget && axisTarget->HandleAxisEvent(event)) {
788             return true;
789         }
790     }
791     return true;
792 }
793 
DispatchRotationEvent(const RotationEvent & event,const RefPtr<RenderNode> & renderNode,const RefPtr<RenderNode> & requestFocusNode)794 bool EventManager::DispatchRotationEvent(
795     const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode)
796 {
797     CHECK_NULL_RETURN(renderNode, false);
798     if (requestFocusNode && renderNode->RotationMatchTest(requestFocusNode)) {
799         LOGD("RotationMatchTest: dispatch rotation to request node.");
800         return requestFocusNode->RotationTestForward(event);
801     } else {
802         LOGD("RotationMatchTest: dispatch rotation to stack render node.");
803         return renderNode->RotationTest(event);
804     }
805 }
806 
AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode> & node)807 void EventManager::AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode>& node)
808 {
809     auto frameNode = node.Upgrade();
810     CHECK_NULL_VOID(frameNode);
811     auto iter = keyboardShortcutNode_.begin();
812     while (iter != keyboardShortcutNode_.end()) {
813         auto keyboardShortcutNode = (*iter).Upgrade();
814         if (!keyboardShortcutNode) {
815             keyboardShortcutNode_.erase(iter++);
816             continue;
817         }
818         if (keyboardShortcutNode->GetId() == frameNode->GetId()) {
819             return;
820         }
821         ++iter;
822     }
823     keyboardShortcutNode_.emplace_back(node);
824 }
825 
GetKeyboardShortcutKeys(const std::vector<ModifierKey> & keys)826 uint8_t EventManager::GetKeyboardShortcutKeys(const std::vector<ModifierKey>& keys)
827 {
828     uint8_t keyValue = 0;
829     uint8_t ctrlTimes = 0;
830     uint8_t shiftTimes = 0;
831     uint8_t altTimes = 0;
832     if (keys.size() > KEYS_MAX_VALUE) {
833         return 0;
834     }
835     for (const auto& key : keys) {
836         switch (static_cast<uint8_t>(key)) {
837             case static_cast<uint8_t>(ModifierKey::CTRL): {
838                 keyValue |= static_cast<uint8_t>(CtrlKeysBit::CTRL);
839                 ++ctrlTimes;
840                 break;
841             }
842             case static_cast<uint8_t>(ModifierKey::SHIFT): {
843                 keyValue |= static_cast<uint8_t>(CtrlKeysBit::SHIFT);
844                 ++shiftTimes;
845                 break;
846             }
847             case static_cast<uint8_t>(ModifierKey::ALT): {
848                 keyValue |= static_cast<uint8_t>(CtrlKeysBit::ALT);
849                 ++altTimes;
850                 break;
851             }
852             default:
853                 keyValue |= 0;
854         }
855     }
856     if (ctrlTimes > 1 || shiftTimes > 1 || altTimes > 1) {
857         return 0;
858     }
859     return keyValue;
860 }
861 
IsSystemKeyboardShortcut(const std::string & value,uint8_t keys)862 bool EventManager::IsSystemKeyboardShortcut(const std::string& value, uint8_t keys)
863 {
864     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_C) {
865         return true;
866     }
867     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_A) {
868         return true;
869     }
870     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_V) {
871         return true;
872     }
873     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_X) {
874         return true;
875     }
876     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Y) {
877         return true;
878     }
879     if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Z) {
880         return true;
881     }
882     if (!(keys ^ (static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT))) &&
883         value == SHORT_CUT_VALUE_Z) {
884         return true;
885     }
886     return false;
887 }
888 
IsSameKeyboardShortcutNode(const std::string & value,uint8_t keys)889 bool EventManager::IsSameKeyboardShortcutNode(const std::string& value, uint8_t keys)
890 {
891     if (IsSystemKeyboardShortcut(value, keys)) {
892         return true;
893     }
894     for (auto& weakNode : keyboardShortcutNode_) {
895         auto frameNode = weakNode.Upgrade();
896         if (!frameNode) {
897             continue;
898         }
899         auto eventHub = frameNode->GetEventHub<NG::EventHub>();
900         if (!eventHub) {
901             continue;
902         }
903         auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
904         for (auto& keyboardShortcut : keyboardShortcuts) {
905             LOGI("IsSameKeyboardShortcutNode keys = %{public}d value = %{public}s", keyboardShortcut.keys,
906                 keyboardShortcut.value.c_str());
907             if (keyboardShortcut.value.find(value) != std::string::npos && keyboardShortcut.keys == keys) {
908                 return true;
909             }
910         }
911     }
912     return false;
913 }
914 
AddKeyboardShortcutSingleKey(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)915 void AddKeyboardShortcutSingleKey(
916     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
917 {
918     uint8_t index = 0;
919     std::vector<KeyCode> keyCode1;
920     std::vector<KeyCode> keyCode2;
921     if (keys & static_cast<uint8_t>(CtrlKeysBit::CTRL)) {
922         keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
923         keyCode2.emplace_back(KeyCode::KEY_CTRL_RIGHT);
924         permutation.emplace_back(++index);
925     }
926     if (keys & static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
927         keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
928         keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
929         permutation.emplace_back(++index);
930     }
931     if (keys & static_cast<uint8_t>(CtrlKeysBit::ALT)) {
932         keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
933         keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
934         permutation.emplace_back(++index);
935     }
936     keyCodes.emplace_back(keyCode1);
937     keyCodes.emplace_back(keyCode2);
938 }
939 
AddKeyboardShortcutDoubleKeysWithCtrlShift(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)940 void AddKeyboardShortcutDoubleKeysWithCtrlShift(
941     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
942 {
943     uint8_t index = 0;
944     std::vector<KeyCode> keyCode1;
945     std::vector<KeyCode> keyCode2;
946     std::vector<KeyCode> keyCode3;
947     std::vector<KeyCode> keyCode4;
948 
949     keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
950     keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
951     keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
952     keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
953     permutation.emplace_back(++index);
954 
955     keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
956     keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
957     keyCode3.emplace_back(KeyCode::KEY_SHIFT_LEFT);
958     keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
959     permutation.emplace_back(++index);
960 
961     keyCodes.emplace_back(keyCode1);
962     keyCodes.emplace_back(keyCode2);
963     keyCodes.emplace_back(keyCode3);
964     keyCodes.emplace_back(keyCode4);
965 }
966 
AddKeyboardShortcutDoubleKeysWithCtrlAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)967 void AddKeyboardShortcutDoubleKeysWithCtrlAlt(
968     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
969 {
970     uint8_t index = 0;
971     std::vector<KeyCode> keyCode1;
972     std::vector<KeyCode> keyCode2;
973     std::vector<KeyCode> keyCode3;
974     std::vector<KeyCode> keyCode4;
975 
976     keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
977     keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
978     keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
979     keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
980     permutation.emplace_back(++index);
981 
982     keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
983     keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
984     keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
985     keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
986     permutation.emplace_back(++index);
987 
988     keyCodes.emplace_back(keyCode1);
989     keyCodes.emplace_back(keyCode2);
990     keyCodes.emplace_back(keyCode3);
991     keyCodes.emplace_back(keyCode4);
992 }
993 
AddKeyboardShortcutDoubleKeysWithShiftAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)994 void AddKeyboardShortcutDoubleKeysWithShiftAlt(
995     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
996 {
997     uint8_t index = 0;
998     std::vector<KeyCode> keyCode1;
999     std::vector<KeyCode> keyCode2;
1000     std::vector<KeyCode> keyCode3;
1001     std::vector<KeyCode> keyCode4;
1002 
1003     keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1004     keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1005     keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1006     keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1007     permutation.emplace_back(++index);
1008 
1009     keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1010     keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1011     keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1012     keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1013     permutation.emplace_back(++index);
1014 
1015     keyCodes.emplace_back(keyCode1);
1016     keyCodes.emplace_back(keyCode2);
1017     keyCodes.emplace_back(keyCode3);
1018     keyCodes.emplace_back(keyCode4);
1019 }
1020 
AddKeyboardShortcutDoubleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1021 void AddKeyboardShortcutDoubleKeys(
1022     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1023 {
1024     if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
1025         AddKeyboardShortcutDoubleKeysWithCtrlShift(keys, keyCodes, permutation);
1026     }
1027     if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1028         AddKeyboardShortcutDoubleKeysWithCtrlAlt(keys, keyCodes, permutation);
1029     }
1030     if (keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1031         AddKeyboardShortcutDoubleKeysWithShiftAlt(keys, keyCodes, permutation);
1032     }
1033 }
1034 
AddKeyboardShortcutTripleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1035 void AddKeyboardShortcutTripleKeys(
1036     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1037 {
1038     uint8_t index = 0;
1039     std::vector<KeyCode> keyCode1;
1040     std::vector<KeyCode> keyCode2;
1041     std::vector<KeyCode> keyCode3;
1042     std::vector<KeyCode> keyCode4;
1043     std::vector<KeyCode> keyCode5;
1044     std::vector<KeyCode> keyCode6;
1045     std::vector<KeyCode> keyCode7;
1046     std::vector<KeyCode> keyCode8;
1047 
1048     keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1049     keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
1050     keyCode3.emplace_back(KeyCode::KEY_CTRL_LEFT);
1051     keyCode4.emplace_back(KeyCode::KEY_CTRL_LEFT);
1052     keyCode5.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1053     keyCode6.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1054     keyCode7.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1055     keyCode8.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1056     permutation.emplace_back(++index);
1057 
1058     keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1059     keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1060     keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1061     keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1062     keyCode5.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1063     keyCode6.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1064     keyCode7.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1065     keyCode8.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1066     permutation.emplace_back(++index);
1067 
1068     keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1069     keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1070     keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1071     keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1072     keyCode5.emplace_back(KeyCode::KEY_ALT_LEFT);
1073     keyCode6.emplace_back(KeyCode::KEY_ALT_RIGHT);
1074     keyCode7.emplace_back(KeyCode::KEY_ALT_LEFT);
1075     keyCode8.emplace_back(KeyCode::KEY_ALT_RIGHT);
1076     permutation.emplace_back(++index);
1077 
1078     keyCodes.emplace_back(keyCode1);
1079     keyCodes.emplace_back(keyCode2);
1080     keyCodes.emplace_back(keyCode3);
1081     keyCodes.emplace_back(keyCode4);
1082     keyCodes.emplace_back(keyCode5);
1083     keyCodes.emplace_back(keyCode6);
1084     keyCodes.emplace_back(keyCode7);
1085     keyCodes.emplace_back(keyCode8);
1086 }
1087 
AddKeyboardShortcutKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1088 void AddKeyboardShortcutKeys(
1089     uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1090 {
1091     // single FunctionKey
1092     if (keys == 0) {
1093         keyCodes.emplace_back(std::vector<KeyCode>());
1094     }
1095     // single key
1096     if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) || keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1097         keys == static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1098         LOGI("AddKeyboardShortcutKeys single key");
1099         AddKeyboardShortcutSingleKey(keys, keyCodes, permutation);
1100     }
1101     // double keys
1102     if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1103         keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT) ||
1104         keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1105         LOGI("AddKeyboardShortcutKeys double keys");
1106         AddKeyboardShortcutDoubleKeys(keys, keyCodes, permutation);
1107     }
1108     // triple keys
1109     if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) +
1110                     static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1111         LOGI("AddKeyboardShortcutKeys triple keys");
1112         AddKeyboardShortcutTripleKeys(keys, keyCodes, permutation);
1113     }
1114 }
1115 
TriggerKeyboardShortcut(const KeyEvent & event,const std::vector<NG::KeyboardShortcut> & keyboardShortcuts,const WeakPtr<NG::FrameNode> & node,const RefPtr<NG::EventHub> & eventHub)1116 void TriggerKeyboardShortcut(const KeyEvent& event, const std::vector<NG::KeyboardShortcut>& keyboardShortcuts,
1117     const WeakPtr<NG::FrameNode>& node, const RefPtr<NG::EventHub>& eventHub)
1118 {
1119     CHECK_NULL_VOID(eventHub);
1120     for (auto& keyboardShortcut : keyboardShortcuts) {
1121         if (keyboardShortcut.value.empty()) {
1122             continue;
1123         }
1124 
1125         std::vector<std::vector<KeyCode>> keyCodes;
1126         std::vector<uint8_t> permutation;
1127         AddKeyboardShortcutKeys(keyboardShortcut.keys, keyCodes, permutation);
1128         // FunctionKey
1129         if ((event.IsFunctionKey() || event.IsEscapeKey()) &&
1130             event.ConvertInputCodeToString() != keyboardShortcut.value) {
1131             continue;
1132         } else if (event.ConvertInputCodeToString().find(keyboardShortcut.value) == std::string::npos) {
1133             continue;
1134         }
1135         // Handle left and right the keys problem.
1136         std::vector<uint8_t> perm;
1137         for (auto& keyCode : keyCodes) {
1138             perm.assign(permutation.begin(), permutation.end());
1139             // Handle the keys order problem.
1140             do {
1141                 keyCode.emplace_back(event.code);
1142                 if (!event.IsKey(keyCode)) {
1143                     keyCode.pop_back();
1144                     std::next_permutation(keyCode.begin(), keyCode.end());
1145                     continue;
1146                 }
1147 
1148                 if (keyboardShortcut.onKeyboardShortcutAction) {
1149                     keyboardShortcut.onKeyboardShortcutAction();
1150                     LOGI("TriggerKeyboardShortcut action done.");
1151                 } else {
1152                     auto gestureEventHub = eventHub->GetGestureEventHub();
1153                     if (gestureEventHub && gestureEventHub->IsClickable()) {
1154                         gestureEventHub->KeyBoardShortCutClick(event, node);
1155                         LOGI("TriggerKeyboardShortcut click done.");
1156                     }
1157                 }
1158                 keyCode.pop_back();
1159                 std::next_permutation(keyCode.begin(), keyCode.end());
1160             } while (std::next_permutation(perm.begin(), perm.end()));
1161             perm.clear();
1162         }
1163         keyCodes.clear();
1164         permutation.clear();
1165     }
1166 }
1167 
DispatchKeyboardShortcut(const KeyEvent & event)1168 void EventManager::DispatchKeyboardShortcut(const KeyEvent& event)
1169 {
1170     LOGD("EventManager: The key code is %{public}d, the key action is %{public}d.", event.code, event.action);
1171     if (event.action != KeyAction::DOWN) {
1172         return;
1173     }
1174     for (auto& node : keyboardShortcutNode_) {
1175         auto frameNode = node.Upgrade();
1176         if (!frameNode || !(frameNode->IsActive())) {
1177             continue;
1178         }
1179         auto eventHub = frameNode->GetEventHub<NG::EventHub>();
1180         if (!eventHub || !(eventHub->IsEnabled())) {
1181             continue;
1182         }
1183 
1184         auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
1185         TriggerKeyboardShortcut(event, keyboardShortcuts, node, eventHub);
1186     }
1187 }
1188 
DelKeyboardShortcutNode(int32_t nodeId)1189 void EventManager::DelKeyboardShortcutNode(int32_t nodeId)
1190 {
1191     auto iter = keyboardShortcutNode_.begin();
1192     while (iter != keyboardShortcutNode_.end()) {
1193         auto frameNode = (*iter).Upgrade();
1194         if (!frameNode) {
1195             keyboardShortcutNode_.erase(iter++);
1196             continue;
1197         }
1198         if (frameNode->GetId() == nodeId) {
1199             keyboardShortcutNode_.erase(iter);
1200             break;
1201         }
1202         ++iter;
1203     }
1204 }
1205 
ClearResults()1206 void EventManager::ClearResults()
1207 {
1208     touchTestResults_.clear();
1209     mouseTestResults_.clear();
1210     axisTouchTestResults_.clear();
1211     keyboardShortcutNode_.clear();
1212 }
1213 
EventManager()1214 EventManager::EventManager()
1215 {
1216     LOGD("EventManger Constructor.");
1217     refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1218     referee_ = AceType::MakeRefPtr<GestureReferee>();
1219 
1220     auto callback = [weak = WeakClaim(this)](size_t touchId) -> bool {
1221         auto eventManager = weak.Upgrade();
1222         CHECK_NULL_RETURN(eventManager, false);
1223         auto refereeNG = eventManager->refereeNG_;
1224         CHECK_NULL_RETURN(refereeNG, false);
1225         return refereeNG->HasGestureAccepted(touchId);
1226     };
1227     referee_->SetQueryStateFunc(std::move(callback));
1228 
1229     auto cleanReferee = [weak = WeakClaim(this)](size_t touchId) -> void {
1230         auto eventManager = weak.Upgrade();
1231         CHECK_NULL_VOID(eventManager);
1232         auto referee = eventManager->referee_;
1233         CHECK_NULL_VOID(referee);
1234         auto gestureScope = referee->GetGestureScope();
1235         const auto iter = gestureScope.find(touchId);
1236         if (iter == gestureScope.end()) {
1237             return;
1238         }
1239 
1240         auto highRecognizers = iter->second.GetHighRecognizers();
1241         auto lowRecognizers = iter->second.GetLowRecognizers();
1242         auto parallelRecognizers = iter->second.GetParallelRecognizers();
1243 
1244         for (const auto& weak : highRecognizers) {
1245             auto gesture = weak.Upgrade();
1246             if (gesture) {
1247                 gesture->OnRejected(touchId);
1248             }
1249         }
1250 
1251         for (const auto& weak : lowRecognizers) {
1252             auto gesture = weak.Upgrade();
1253             if (gesture) {
1254                 gesture->OnRejected(touchId);
1255             }
1256         }
1257 
1258         for (const auto& weak : parallelRecognizers) {
1259             auto gesture = weak.Upgrade();
1260             if (gesture) {
1261                 gesture->OnRejected(touchId);
1262             }
1263         }
1264     };
1265     refereeNG_->SetQueryStateFunc(std::move(cleanReferee));
1266 }
1267 
1268 } // namespace OHOS::Ace
1269