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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_EVENT_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_EVENT_MANAGER_H 18 19 #include <unordered_map> 20 21 #include "base/memory/ace_type.h" 22 #include "base/memory/referenced.h" 23 #include "core/common/event_dump.h" 24 #include "core/components/common/layout/constants.h" 25 #include "core/components_ng/event/response_ctrl.h" 26 #include "core/components_ng/gestures/gesture_referee.h" 27 #include "core/components_ng/gestures/recognizers/gesture_recognizer.h" 28 #include "core/event/axis_event.h" 29 #include "core/event/key_event.h" 30 #include "core/event/mouse_event.h" 31 #include "core/event/rotation_event.h" 32 #include "core/event/touch_event.h" 33 #include "core/focus/focus_node.h" 34 #include "core/gestures/gesture_referee.h" 35 36 namespace OHOS::Ace { 37 namespace NG { 38 class FrameNode; 39 class SelectOverlayManager; 40 class ResponseCtrl; 41 } // namespace NG 42 class RenderNode; 43 class Element; 44 class TextOverlayManager; 45 using MouseHoverTestList = std::list<WeakPtr<RenderNode>>; 46 using OutOfRectGetRectCallback = std::function<void(std::vector<Rect>&)>; 47 using OutOfRectTouchCallback = std::function<void(void)>; 48 using OutOfRectMouseCallback = std::function<void(void)>; 49 50 struct RectCallback final { RectCallbackfinal51 RectCallback(OutOfRectGetRectCallback rectGetCallback, OutOfRectTouchCallback touchCallback, 52 OutOfRectMouseCallback mouseCallback) 53 : rectGetCallback(std::move(rectGetCallback)), touchCallback(std::move(touchCallback)), 54 mouseCallback(std::move(mouseCallback)) 55 {} 56 ~RectCallback() = default; 57 OutOfRectGetRectCallback rectGetCallback; 58 OutOfRectTouchCallback touchCallback; 59 OutOfRectMouseCallback mouseCallback; 60 }; 61 62 struct MarkProcessedEventInfo { 63 int32_t eventId = -1; 64 int64_t lastLogTimeStamp = 0; 65 }; 66 67 class EventManager : public virtual AceType { 68 DECLARE_ACE_TYPE(EventManager, AceType); 69 70 public: 71 EventManager(); 72 ~EventManager() override = default; 73 // After the touch down event is triggered, the touch test is performed to collect the corresponding 74 // touch event target list. 75 void TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode, 76 TouchRestrict& touchRestrict, const Offset& offset = Offset(), 77 float viewScale = 1.0f, bool needAppend = false); 78 79 void TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode, 80 TouchRestrict& touchRestrict, const Offset& offset = Offset(), 81 float viewScale = 1.0f, bool needAppend = false); 82 83 bool PostEventTouchTest(const TouchEvent& touchPoint, const RefPtr<NG::UINode>& uiNode, 84 TouchRestrict& touchRestrict); 85 86 void TouchTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode, TouchRestrict& touchRestrict); 87 88 void TouchTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict); 89 90 bool HasDifferentDirectionGesture(); 91 92 bool DispatchTouchEvent(const TouchEvent& point); 93 bool DispatchTouchEvent(const AxisEvent& event); 94 bool PostEventDispatchTouchEvent(const TouchEvent& point); 95 void FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents); 96 void FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents); 97 void PostEventFlushTouchEventEnd(const TouchEvent& touchEvent); 98 99 // Distribute the key event to the corresponding root node. If the root node is not processed, return false and the 100 // platform will handle it. 101 bool DispatchKeyEvent(const KeyEvent& event, const RefPtr<FocusNode>& focusNode); 102 bool DispatchTabIndexEvent( 103 const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& mainNode); 104 105 // Distribute the key event to the corresponding root node. If the root node is not processed, return false and the 106 // platform will handle it. 107 bool DispatchKeyEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode); 108 bool DispatchTabIndexEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& mainView); 109 110 // Distribute the rotation event to the corresponding render tree or requested render node. If the render is not 111 // processed, return false and the platform will handle it. 112 static bool DispatchRotationEvent( 113 const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode); 114 115 // If current focus node is Web, will skip some events processing. 116 static bool IsSkipEventNode(const RefPtr<NG::FrameNode>& focusNode); 117 118 // mouse event target list. 119 void MouseTest(const MouseEvent& touchPoint, const RefPtr<RenderNode>& renderNode); 120 bool DispatchMouseEvent(const MouseEvent& event); 121 void DispatchMouseHoverAnimation(const MouseEvent& event); 122 bool DispatchMouseHoverEvent(const MouseEvent& event); 123 124 void LogPrintMouseTest(); 125 void MouseTest(const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict); 126 void AccessibilityHoverTest( 127 const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict); 128 void UpdateAccessibilityHoverNode(const TouchEvent& event, const TouchTestResult& testResult); 129 void PenHoverTest(const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict); 130 void UpdatePenHoverNode(const TouchEvent& event, const TouchTestResult& testResult); 131 void UpdateHoverNode(const MouseEvent& event, const TouchTestResult& testResult); 132 bool DispatchMouseEventNG(const MouseEvent& event); 133 void DispatchMouseHoverAnimationNG(const MouseEvent& event); 134 bool DispatchMouseHoverEventNG(const MouseEvent& event); 135 void DispatchHoverEffectEvent(const MouseEvent& event); 136 void DispatchAccessibilityHoverEventNG(const TouchEvent& event); 137 void DispatchPenHoverEventNG(const TouchEvent& event); 138 139 void AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode); 140 bool DispatchAxisEvent(const AxisEvent& event); 141 142 void AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode); 143 bool DispatchAxisEventNG(const AxisEvent& event); 144 145 void ClearResults(); SetInstanceId(int32_t instanceId)146 void SetInstanceId(int32_t instanceId) 147 { 148 instanceId_ = instanceId; 149 } GetInstanceId()150 int32_t GetInstanceId() 151 { 152 return instanceId_; 153 } 154 void HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager); 155 void HandleGlobalEventNG(const TouchEvent& touchPoint, const RefPtr<NG::SelectOverlayManager>& selectOverlayManager, 156 const NG::OffsetF& rootOffset); 157 158 void CollectTabIndexNodes(const RefPtr<FocusNode>& rootNode); 159 160 void AdjustTabIndexNodes(); 161 162 bool HandleFocusByTabIndex( 163 const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& curPage); 164 165 void HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList); 166 GetGestureReferee()167 RefPtr<GestureReferee> GetGestureReferee() 168 { 169 return referee_; 170 } 171 GetGestureRefereeNG(const RefPtr<NG::NGGestureRecognizer> & recognizer)172 RefPtr<NG::GestureReferee> GetGestureRefereeNG(const RefPtr<NG::NGGestureRecognizer>& recognizer) 173 { 174 if (recognizer->IsPostEventResult()) { 175 return postEventRefereeNG_; 176 } 177 return refereeNG_; 178 } 179 180 bool DispatchKeyboardShortcut(const KeyEvent& event); 181 182 void AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode>& node); 183 184 void DelKeyboardShortcutNode(int32_t nodeId); 185 186 void AddKeyboardShortcutKeys(uint8_t keys, std::vector<KeyCode>& leftKeyCode, std::vector<KeyCode>& rightKeyCode, 187 std::vector<uint8_t>& permutation); 188 IsKeyInPressed(KeyCode tarCode)189 bool IsKeyInPressed(KeyCode tarCode) const 190 { 191 return std::any_of(pressedKeyCodes_.begin(), pressedKeyCodes_.end(), 192 [tarCode](const KeyCode& code) { return code == tarCode; }); 193 } SetPressedKeyCodes(const std::vector<KeyCode> & pressedKeyCodes)194 void SetPressedKeyCodes(const std::vector<KeyCode>& pressedKeyCodes) 195 { 196 pressedKeyCodes_ = pressedKeyCodes; 197 } 198 199 bool IsSameKeyboardShortcutNode(const std::string& value, uint8_t keys); 200 201 bool IsSystemKeyboardShortcut(const std::string& value, uint8_t keys); 202 203 uint8_t GetKeyboardShortcutKeys(const std::vector<ModifierKey>& keys); 204 205 void DoMouseActionRelease(); 206 SetIsDragging(bool isDragging)207 void SetIsDragging(bool isDragging) 208 { 209 isDragging_ = isDragging; 210 } 211 IsDragging()212 bool IsDragging() const 213 { 214 return isDragging_; 215 } 216 SetLastMoveBeforeUp(bool isLastMoveBeforeUp)217 void SetLastMoveBeforeUp(bool isLastMoveBeforeUp) 218 { 219 isLastMoveBeforeUp_ = isLastMoveBeforeUp; 220 } 221 IsLastMoveBeforeUp()222 bool IsLastMoveBeforeUp() const 223 { 224 return isLastMoveBeforeUp_; 225 } 226 GetEventTreeRecord(NG::EventTreeType treeType)227 NG::EventTreeRecord& GetEventTreeRecord(NG::EventTreeType treeType) 228 { 229 switch (treeType) { 230 case NG::EventTreeType::TOUCH : 231 return eventTree_; 232 case NG::EventTreeType::POST_EVENT : 233 return postEventTree_; 234 } 235 } 236 237 void DumpEvent(NG::EventTreeType type); 238 239 void AddGestureSnapshot( 240 int32_t finger, int32_t depth, const RefPtr<TouchEventTarget>& target, NG::EventTreeType type); 241 GetResponseCtrl()242 RefPtr<NG::ResponseCtrl> GetResponseCtrl() 243 { 244 return responseCtrl_; 245 } 246 247 void CheckDownEvent(const TouchEvent& touchEvent); 248 void CheckUpEvent(const TouchEvent& touchEvent); 249 std::unordered_map<size_t, TouchTestResult> touchTestResults_; 250 std::unordered_map<size_t, TouchTestResult> postEventTouchTestResults_; 251 SetInnerFlag(bool value)252 void SetInnerFlag(bool value) 253 { 254 innerEventWin_ = value; 255 } 256 GetInnerFlag()257 bool GetInnerFlag() const 258 { 259 return innerEventWin_; 260 } 261 SetIsKeyConsumed(bool value)262 void SetIsKeyConsumed(bool value) 263 { 264 // Once consumed, isKeyConsumed_ keeps true 265 if (!isKeyConsumed_ && value) { 266 isKeyConsumed_ = true; 267 } 268 } 269 GetLastTouchEventEndTimestamp()270 int64_t GetLastTouchEventEndTimestamp() 271 { 272 return lastTouchEventEndTimestamp_; 273 } 274 275 void RecordHitEmptyMessage( 276 const TouchEvent& touchPoint, const std::string& resultInfo, const RefPtr<NG::FrameNode>& frameNode); 277 278 void CheckAndLogLastReceivedTouchEventInfo(int32_t eventId, TouchType type); 279 280 void CheckAndLogLastConsumedTouchEventInfo(int32_t eventId, TouchType type); 281 282 void CheckAndLogLastReceivedMouseEventInfo(int32_t eventId, MouseAction action); 283 284 void CheckAndLogLastConsumedMouseEventInfo(int32_t eventId, MouseAction action); 285 286 void CheckAndLogLastReceivedAxisEventInfo(int32_t eventId, AxisAction action); 287 288 void CheckAndLogLastConsumedAxisEventInfo(int32_t eventId, AxisAction action); 289 290 void CheckAndLogLastReceivedEventInfo(int32_t eventId, bool logImmediately = false); 291 292 void CheckAndLogLastConsumedEventInfo(int32_t eventId, bool logImmediately = false); 293 294 void ClearTouchTestTargetForPenStylus(TouchEvent& touchEvent); 295 GetDownFingerIds()296 inline const std::unordered_map<int32_t, int32_t>& GetDownFingerIds() const 297 { 298 return downFingerIds_; 299 } 300 301 TouchEvent ConvertAxisEventToTouchEvent(const AxisEvent& axisEvent); 302 303 #if defined(SUPPORT_TOUCH_TARGET_TEST) 304 bool TouchTargetHitTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode, 305 TouchRestrict& touchRestrict, const Offset& offset = Offset(), float viewScale = 1.0f, 306 bool needAppend = false, const std::string& target = ""); 307 #endif 308 private: 309 void SetHittedFrameNode(const std::list<RefPtr<NG::NGGestureRecognizer>>& touchTestResults); 310 void CleanGestureEventHub(); 311 void GetTouchTestIds(const TouchEvent& touchPoint, std::vector<std::string>& touchTestIds, 312 bool& isMousePressAtSelectedNode, int32_t selectedNodeId); 313 void CheckMouseTestResults(bool& isMousePressAtSelectedNode, int32_t selectedNodeId); 314 void LogTouchTestResultRecognizers(const TouchTestResult& result, int32_t touchEventId); 315 void LogTouchTestRecognizerStates(int32_t touchEventId); 316 void DispatchTouchEventToTouchTestResult(TouchEvent touchEvent, TouchTestResult touchTestResult, 317 bool sendOnTouch); 318 void CleanRecognizersForDragBegin(TouchEvent& touchEvent); 319 void SetResponseLinkRecognizers(const TouchTestResult& result, const ResponseLinkResult& responseLinkRecognizers); 320 void FalsifyCancelEventAndDispatch(const TouchEvent& touchPoint); 321 void FalsifyCancelEventAndDispatch(const AxisEvent& axisEvent); 322 void FalsifyHoverCancelEventAndDispatch(const TouchEvent& touchPoint); 323 void DoSingleMouseActionRelease(MouseButton button); 324 bool DispatchMouseEventInGreatOrEqualAPI13(const MouseEvent& event); 325 bool DispatchMouseEventInLessAPI13(const MouseEvent& event); 326 void DispatchMouseEventToPressResults(const MouseEvent& event, const MouseTestResult& targetResults, 327 MouseTestResult& handledResults, bool& isStopPropagation); 328 bool DispatchMouseEventToCurResults( 329 const MouseEvent& event, const MouseTestResult& handledResults, bool isStopPropagation); 330 bool DispatchMouseEventToCurResultsInLessAPI13( 331 const MouseEvent& event, const MouseTestResult& handledResults, bool isStopPropagation); 332 bool innerEventWin_ = false; 333 std::unordered_map<size_t, TouchTestResult> mouseTestResults_; 334 MouseTestResult currMouseTestResults_; 335 // used less than API13 336 MouseTestResult pressMouseTestResults_; 337 // used great or equal API13 338 std::unordered_map<MouseButton, MouseTestResult> pressMouseTestResultsMap_; 339 HoverTestResult currHoverTestResults_; 340 HoverTestResult lastHoverTestResults_; 341 HoverTestResult curAccessibilityHoverResults_; 342 HoverTestResult lastAccessibilityHoverResults_; 343 HoverTestResult curPenHoverResults_; 344 HoverTestResult lastPenHoverResults_; 345 AxisTestResult axisTestResults_; 346 WeakPtr<NG::FrameNode> lastHoverNode_; 347 WeakPtr<NG::FrameNode> currHoverNode_; 348 std::unordered_map<size_t, TouchTestResult> axisTouchTestResults_; 349 MouseHoverTestList mouseHoverTestResults_; 350 MouseHoverTestList mouseHoverTestResultsPre_; 351 WeakPtr<RenderNode> mouseHoverNodePre_; 352 WeakPtr<RenderNode> mouseHoverNode_; 353 WeakPtr<RenderNode> axisNode_; 354 int32_t instanceId_ = 0; 355 uint32_t lastHoverDispatchLength_ = 0; 356 uint32_t lastAccessibilityHoverDispatchLength_ = 0; 357 uint32_t lastPenHoverDispatchLength_ = 0; 358 bool inSelectedRect_ = false; 359 bool isDragging_ = false; 360 bool isLastMoveBeforeUp_ = false; 361 bool isKeyConsumed_ = false; 362 RefPtr<GestureReferee> referee_; 363 RefPtr<NG::GestureReferee> refereeNG_; 364 RefPtr<NG::GestureReferee> postEventRefereeNG_; 365 std::list<WeakPtr<NG::FrameNode>> keyboardShortcutNode_; 366 std::vector<KeyCode> pressedKeyCodes_; 367 NG::EventTreeRecord eventTree_; 368 NG::EventTreeRecord postEventTree_; 369 RefPtr<NG::ResponseCtrl> responseCtrl_; 370 TimeStamp lastEventTime_; 371 int64_t lastTouchEventEndTimestamp_ = 0; 372 std::unordered_map<int32_t, int32_t> downFingerIds_; 373 std::set<WeakPtr<NG::FrameNode>> hittedFrameNode_; 374 MarkProcessedEventInfo lastReceivedEvent_; 375 MarkProcessedEventInfo lastConsumedEvent_; 376 int32_t lastDownFingerNumber_ = 0; 377 SourceTool lastSourceTool_ = SourceTool::UNKNOWN; 378 // used to pseudo cancel event. 379 TouchEvent lastTouchEvent_; 380 }; 381 382 } // namespace OHOS::Ace 383 384 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_EVENT_MANAGER_H 385