1 /*
2  * Copyright (c) 2021-2022 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_EVENT_TOUCH_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H
18 
19 #include <list>
20 #include <utility>
21 
22 #include "base/geometry/offset.h"
23 #include "base/memory/ace_type.h"
24 #include "base/utils/time_util.h"
25 #include "core/components_ng/event/event_constants.h"
26 #include "core/components_ng/event/target_component.h"
27 #include "core/event/ace_events.h"
28 #include "core/event/axis_event.h"
29 
30 namespace OHOS::MMI {
31 class PointerEvent;
32 } // namespace OHOS::MMI
33 
34 namespace OHOS::Ace::NG {
35 class FrameNode;
36 } // namespace OHOS::Ace::NG
37 
38 namespace OHOS::Ace {
39 
40 static const int32_t TOUCH_TOOL_BASE_ID = 100;
41 
42 enum class TouchType : size_t {
43     DOWN = 0,
44     UP,
45     MOVE,
46     CANCEL,
47     PULL_DOWN,
48     PULL_UP,
49     PULL_MOVE,
50     PULL_IN_WINDOW,
51     PULL_OUT_WINDOW,
52     HOVER_ENTER,
53     HOVER_MOVE,
54     HOVER_EXIT,
55     HOVER_CANCEL,
56     PROXIMITY_IN,
57     PROXIMITY_OUT,
58     UNKNOWN,
59 };
60 
61 struct TouchPoint final {
62     int32_t id = 0;
63     float x = 0.0f;
64     float y = 0.0f;
65     float screenX = 0.0f;
66     float screenY = 0.0f;
67     TimeStamp downTime;
68     double size = 0.0;
69     float force = 0.0f;
70     std::optional<float> tiltX;
71     std::optional<float> tiltY;
72     SourceTool sourceTool = SourceTool::UNKNOWN;
73     bool isPressed = false;
74     int32_t originalId = 0;
75 };
76 
77 /**
78  * @brief TouchEvent contains the active change point and a list of all touch points.
79  */
80 struct TouchEvent final : public UIInputEvent {
81     ~TouchEvent() = default;
82     // the active changed point info
83     // The ID is used to identify the point of contact between the finger and the screen. Different fingers have
84     // different ids.
85     int32_t postEventNodeId = 0;
86     int32_t id = 0;
87     float x = 0.0f;
88     float y = 0.0f;
89     float screenX = 0.0f;
90     float screenY = 0.0f;
91     TouchType type = TouchType::UNKNOWN;
92     TouchType pullType = TouchType::UNKNOWN;
93     double size = 0.0;
94     float force = 0.0f;
95     std::optional<float> tiltX;
96     std::optional<float> tiltY;
97     int64_t deviceId = 0;
98     int32_t targetDisplayId = 0;
99     SourceType sourceType = SourceType::NONE;
100     SourceTool sourceTool = SourceTool::UNKNOWN;
101     int32_t touchEventId = 0;
102     bool isInterpolated = false;
103     bool isMouseTouchTest = false;
104     bool isFalsified = false;
105     bool isPassThroughMode = false;
106 
107     // all points on the touch screen.
108     std::vector<TouchPoint> pointers;
109     std::shared_ptr<MMI::PointerEvent> pointerEvent { nullptr };
110     // historical points
111     std::vector<TouchEvent> history;
112     std::vector<KeyCode> pressedKeyCodes_;
113 
114     std::list<std::string> childTouchTestList;
115 
116     // Coordinates relative to the upper-left corner of the current component
117     float localX = 0.0f;
118     float localY = 0.0f;
119     int32_t originalId = 0;
120     bool isInjected = false;
121     bool isPrivacyMode = false;
122 
123     // Save historical touch point slope.
124     float inputXDeltaSlope = 0.0f;
125     float inputYDeltaSlope = 0.0f;
126 
TouchEventfinal127     TouchEvent() {}
128 
SetIdfinal129     TouchEvent& SetId(int32_t id)
130     {
131         this->id = id;
132         return *this;
133     }
134 
SetXfinal135     TouchEvent& SetX(float x)
136     {
137         this->x = x;
138         return *this;
139     }
140 
SetYfinal141     TouchEvent& SetY(float y)
142     {
143         this->y = y;
144         return *this;
145     }
146 
SetScreenXfinal147     TouchEvent& SetScreenX(float screenX)
148     {
149         this->screenX = screenX;
150         return *this;
151     }
152 
SetScreenYfinal153     TouchEvent& SetScreenY(float screenY)
154     {
155         this->screenY = screenY;
156         return *this;
157     }
158 
SetTimefinal159     TouchEvent& SetTime(TimeStamp time)
160     {
161         this->time = time;
162         return *this;
163     }
164 
GetTimeStampfinal165     TimeStamp GetTimeStamp() const
166     {
167         return this->time;
168     }
169 
SetTypefinal170     TouchEvent& SetType(TouchType type)
171     {
172         this->type = type;
173         return *this;
174     }
175 
SetPullTypefinal176     TouchEvent& SetPullType(TouchType pullType)
177     {
178         this->pullType = pullType;
179         return *this;
180     }
181 
SetSizefinal182     TouchEvent& SetSize(double size)
183     {
184         this->size = size;
185         return *this;
186     }
187 
SetForcefinal188     TouchEvent& SetForce(float force)
189     {
190         this->force = force;
191         return *this;
192     }
193 
SetTiltXfinal194     TouchEvent& SetTiltX(std::optional<float> tiltX)
195     {
196         this->tiltX = tiltX;
197         return *this;
198     }
199 
SetTiltYfinal200     TouchEvent& SetTiltY(std::optional<float> tiltY)
201     {
202         this->tiltY = tiltY;
203         return *this;
204     }
205 
SetDeviceIdfinal206     TouchEvent& SetDeviceId(int64_t deviceId)
207     {
208         this->deviceId = deviceId;
209         return *this;
210     }
211 
SetTargetDisplayIdfinal212     TouchEvent& SetTargetDisplayId(int32_t targetDisplayId)
213     {
214         this->targetDisplayId = targetDisplayId;
215         return *this;
216     }
217 
SetSourceTypefinal218     TouchEvent& SetSourceType(SourceType sourceType)
219     {
220         this->sourceType = sourceType;
221         return *this;
222     }
223 
SetSourceToolfinal224     TouchEvent& SetSourceTool(SourceTool sourceTool)
225     {
226         this->sourceTool = sourceTool;
227         return *this;
228     }
229 
SetTouchEventIdfinal230     TouchEvent& SetTouchEventId(int32_t touchEventId)
231     {
232         this->touchEventId = touchEventId;
233         return *this;
234     }
235 
SetIsInterpolatedfinal236     TouchEvent& SetIsInterpolated(bool isInterpolated)
237     {
238         this->isInterpolated = isInterpolated;
239         return *this;
240     }
241 
SetPointersfinal242     TouchEvent& SetPointers(std::vector<TouchPoint> pointers)
243     {
244         this->pointers = std::move(pointers);
245         return *this;
246     }
247 
SetPointerEventfinal248     TouchEvent& SetPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
249     {
250         this->pointerEvent = std::move(pointerEvent);
251         return *this;
252     }
253 
SetOriginalIdfinal254     TouchEvent& SetOriginalId(int32_t originalId)
255     {
256         this->originalId = originalId;
257         return *this;
258     }
259 
SetIsInjectedfinal260     TouchEvent& SetIsInjected(bool isInjected)
261     {
262         this->isInjected = isInjected;
263         return *this;
264     }
265 
SetInputXDeltaSlopefinal266     TouchEvent& SetInputXDeltaSlope(float inputXDeltaSlope)
267     {
268         this->inputXDeltaSlope = inputXDeltaSlope;
269         return *this;
270     }
271 
SetInputYDeltaSlopefinal272     TouchEvent& SetInputYDeltaSlope(float inputYDeltaSlope)
273     {
274         this->inputYDeltaSlope = inputYDeltaSlope;
275         return *this;
276     }
277 
SetPressedKeyCodesfinal278     TouchEvent& SetPressedKeyCodes(const std::vector<KeyCode>& pressedKeyCodes)
279     {
280         this->pressedKeyCodes_ = pressedKeyCodes;
281         return *this;
282     }
283 
SetIsPassThroughModefinal284     TouchEvent& SetIsPassThroughMode(bool isPassThroughMode)
285     {
286         this->isPassThroughMode = isPassThroughMode;
287         return *this;
288     }
289 
CloneWithfinal290     TouchEvent CloneWith(float scale) const
291     {
292         return CloneWith(scale, 0.0f, 0.0f, std::nullopt);
293     }
294 
CloneWithfinal295     TouchEvent CloneWith(float scale, float offsetX, float offsetY, std::optional<int32_t> pointId) const
296     {
297         TouchEvent event;
298         event.id = pointId.has_value() ? pointId.value() : id;
299         event.x = (x - offsetX) / scale;
300         event.y = (y - offsetY) / scale;
301         event.screenX = (screenX - offsetX) / scale;
302         event.screenY = (screenY - offsetY) / scale;
303         event.type = type;
304         event.pullType = pullType;
305         event.time = time;
306         event.size = size;
307         event.force = force;
308         event.tiltX = tiltX;
309         event.tiltY = tiltY;
310         event.deviceId = deviceId;
311         event.targetDisplayId = targetDisplayId;
312         event.sourceType = sourceType;
313         event.sourceTool = sourceTool;
314         event.touchEventId = touchEventId;
315         event.isInterpolated = isInterpolated;
316         event.pointers = std::move(pointers);
317         event.pointerEvent = std::move(pointerEvent);
318         event.pressedKeyCodes_ = std::move(pressedKeyCodes_);
319         event.originalId = originalId;
320         event.isInjected = isInjected;
321         event.isPrivacyMode = isPrivacyMode;
322         event.inputXDeltaSlope = inputXDeltaSlope;
323         event.inputYDeltaSlope = inputYDeltaSlope;
324         event.isPassThroughMode = isPassThroughMode;
325         return event;
326     }
327 
ToJsonValuefinal328     void ToJsonValue(std::unique_ptr<JsonValue>& json) const
329     {
330         json->Put("id", id);
331         json->Put("x", x);
332         json->Put("y", y);
333         json->Put("sx", screenX);
334         json->Put("sy", screenY);
335         json->Put("ty", static_cast<int32_t>(type));
336         int64_t timeValue = std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count();
337         json->Put("ti", timeValue);
338         json->Put("si", size);
339         json->Put("f", force);
340         int32_t hasTiltX = tiltX.has_value() ? 1 : 0;
341         json->Put("hx", hasTiltX);
342         if (hasTiltX) {
343             json->Put("tx", tiltX.value());
344         }
345         int32_t hasTiltY = tiltY.has_value() ? 1 : 0;
346         json->Put("hy", hasTiltY);
347         if (tiltY.has_value()) {
348             json->Put("ty", tiltY.value());
349         }
350         json->Put("d", deviceId);
351         json->Put("sty", static_cast<int32_t>(sourceType));
352         json->Put("sto", static_cast<int32_t>(sourceTool));
353     }
354 
FromJsonfinal355     void FromJson(const std::unique_ptr<JsonValue>& json)
356     {
357         id = json->GetInt("id");
358         x = json->GetDouble("x");
359         y = json->GetDouble("y");
360         screenX = json->GetDouble("sx");
361         screenY = json->GetDouble("sy");
362         type = static_cast<TouchType>(json->GetInt("ty"));
363         int64_t timeValue = json->GetInt64("ti");
364         time = TimeStamp(std::chrono::nanoseconds(timeValue));
365         size = json->GetDouble("si");
366         force = json->GetDouble("f");
367         int32_t hasTiltX = json->GetInt("hx");
368         int32_t hasTiltY = json->GetInt("hy");
369         if (hasTiltX) {
370             tiltX = json->GetDouble("tx");
371         }
372         if (hasTiltY) {
373             tiltY = json->GetDouble("ty");
374         }
375         deviceId = json->GetInt64("d");
376         sourceType = static_cast<SourceType>(json->GetInt("sty"));
377         sourceTool = static_cast<SourceTool>(json->GetInt("sto"));
378     }
379 
GetOffsetfinal380     Offset GetOffset() const
381     {
382         return Offset(x, y);
383     }
384 
GetScreenOffsetfinal385     Offset GetScreenOffset() const
386     {
387         return Offset(screenX, screenY);
388     }
389 
CovertIdfinal390     void CovertId()
391     {
392         if ((sourceType == SourceType::TOUCH) && (sourceTool == SourceTool::PEN)) {
393             id = id + TOUCH_TOOL_BASE_ID + static_cast<int32_t>(sourceTool);
394             originalId = TOUCH_TOOL_BASE_ID + static_cast<int32_t>(sourceTool);
395         }
396     }
397 
CreateScalePointfinal398     TouchEvent CreateScalePoint(float scale) const
399     {
400         if (NearZero(scale)) {
401             return CloneWith(1);
402         }
403         auto temp = pointers;
404         std::for_each(temp.begin(), temp.end(), [scale](auto&& point) {
405             point.x = point.x / scale;
406             point.y = point.y / scale;
407             point.screenX = point.screenX / scale;
408             point.screenY = point.screenY / scale;
409         });
410         return CloneWith(scale);
411     }
412 
UpdateScalePointfinal413     TouchEvent UpdateScalePoint(float scale, float offsetX, float offsetY, int32_t pointId) const
414     {
415         auto temp = pointers;
416         if (NearZero(scale)) {
417             std::for_each(temp.begin(), temp.end(), [offsetX, offsetY](auto&& point) {
418                 point.x = point.x - offsetX;
419                 point.y = point.y - offsetY;
420                 point.screenX = point.screenX - offsetX;
421                 point.screenY = point.screenY - offsetY;
422             });
423             return CloneWith(1, offsetX, offsetY, pointId);
424         }
425 
426         std::for_each(temp.begin(), temp.end(), [scale, offsetX, offsetY](auto&& point) {
427             point.x = (point.x - offsetX) / scale;
428             point.y = (point.y - offsetY) / scale;
429             point.screenX = (point.screenX - offsetX) / scale;
430             point.screenY = (point.screenY - offsetY) / scale;
431         });
432         return CloneWith(scale, offsetX, offsetY, pointId);
433     }
434 
UpdatePointersfinal435     TouchEvent UpdatePointers() const
436     {
437         TouchPoint point { .id = id,
438             .x = x,
439             .y = y,
440             .screenX = screenX,
441             .screenY = screenY,
442             .downTime = time,
443             .size = size,
444             .force = force,
445             .isPressed = (type == TouchType::DOWN) };
446         TouchEvent event;
447         event.SetId(id)
448             .SetX(x)
449             .SetY(y)
450             .SetScreenX(screenX)
451             .SetScreenY(screenY)
452             .SetType(type)
453             .SetTime(time)
454             .SetSize(size)
455             .SetForce(force)
456             .SetDeviceId(deviceId)
457             .SetTargetDisplayId(targetDisplayId)
458             .SetSourceType(sourceType)
459             .SetIsInterpolated(isInterpolated)
460             .SetPointerEvent(pointerEvent)
461             .SetOriginalId(originalId)
462             .SetIsPassThroughMode(isPassThroughMode);
463         event.pointers.emplace_back(std::move(point));
464         return event;
465     }
466 
IsPenHoverEventfinal467     bool IsPenHoverEvent() const
468     {
469         return sourceTool == SourceTool::PEN && (type == TouchType::PROXIMITY_IN ||
470         type == TouchType::PROXIMITY_OUT || (type == TouchType::MOVE && NearZero(force)));
471     }
472 };
473 
474 namespace Platform {
475 ACE_FORCE_EXPORT Offset GetTouchEventOriginOffset(const TouchEvent& event);
476 ACE_FORCE_EXPORT TimeStamp GetTouchEventOriginTimeStamp(const TouchEvent& event);
477 ACE_FORCE_EXPORT void UpdatePressedKeyCodes(std::vector<KeyCode>& pressedKeyCodes);
478 } // namespace Platform
479 
480 struct TouchRestrict final {
481     static constexpr uint32_t NONE = 0x00000000;
482     static constexpr uint32_t CLICK = 0x00000001;
483     static constexpr uint32_t LONG_PRESS = 0x00000010;
484     static constexpr uint32_t SWIPE_LEFT = 0x00000100;
485     static constexpr uint32_t SWIPE_RIGHT = 0x00000200;
486     static constexpr uint32_t SWIPE_UP = 0x00000400;
487     static constexpr uint32_t SWIPE_DOWN = 0x00000800;
488     static constexpr uint32_t SWIPE = 0x00000F00;
489     static constexpr uint32_t SWIPE_VERTICAL = 0x0000C00;   // Vertical
490     static constexpr uint32_t SWIPE_HORIZONTAL = 0x0000300; // Horizontal
491     static constexpr uint32_t TOUCH = 0xFFFFFFFF;
492 
493     uint32_t forbiddenType = NONE;
494 
UpdateForbiddenTypefinal495     void UpdateForbiddenType(uint32_t gestureType)
496     {
497         forbiddenType |= gestureType;
498     }
499     SourceType sourceType = SourceType::NONE;
500 
501     SourceType hitTestType = SourceType::TOUCH;
502 
503     InputEventType inputEventType = InputEventType::TOUCH_SCREEN;
504 
505     TouchEvent touchEvent;
506 
507     std::list<std::string> childTouchTestList;
508 
509     // use to dump event tree
510     NG::EventTreeType touchTestType = NG::EventTreeType::TOUCH;
511 };
512 
513 class TouchCallBackInfo : public BaseEventInfo {
514     DECLARE_RELATIONSHIP_OF_CLASSES(TouchCallBackInfo, BaseEventInfo);
515 
516 public:
TouchCallBackInfo(TouchType type)517     explicit TouchCallBackInfo(TouchType type) : BaseEventInfo("onTouchEvent"), touchType_(type) {}
518     ~TouchCallBackInfo() override = default;
519 
SetScreenX(float screenX)520     void SetScreenX(float screenX)
521     {
522         screenX_ = screenX;
523     }
GetScreenX()524     float GetScreenX() const
525     {
526         return screenX_;
527     }
SetScreenY(float screenY)528     void SetScreenY(float screenY)
529     {
530         screenY_ = screenY;
531     }
GetScreenY()532     float GetScreenY() const
533     {
534         return screenY_;
535     }
SetLocalX(float localX)536     void SetLocalX(float localX)
537     {
538         localX_ = localX;
539     }
GetLocalX()540     float GetLocalX() const
541     {
542         return localX_;
543     }
SetLocalY(float localY)544     void SetLocalY(float localY)
545     {
546         localY_ = localY;
547     }
GetLocalY()548     float GetLocalY() const
549     {
550         return localY_;
551     }
SetTouchType(TouchType type)552     void SetTouchType(TouchType type)
553     {
554         touchType_ = type;
555     }
GetTouchType()556     TouchType GetTouchType() const
557     {
558         return touchType_;
559     }
SetTimeStamp(const TimeStamp & time)560     void SetTimeStamp(const TimeStamp& time)
561     {
562         time_ = time;
563     }
GetTimeStamp()564     TimeStamp GetTimeStamp() const
565     {
566         return time_;
567     }
568 
569 private:
570     float screenX_ = 0.0f;
571     float screenY_ = 0.0f;
572     float localX_ = 0.0f;
573     float localY_ = 0.0f;
574     TouchType touchType_ = TouchType::UNKNOWN;
575     TimeStamp time_;
576 };
577 
578 class TouchLocationInfo : public BaseEventInfo {
579     DECLARE_RELATIONSHIP_OF_CLASSES(TouchLocationInfo, TypeInfoBase);
580 
581 public:
TouchLocationInfo(int32_t fingerId)582     explicit TouchLocationInfo(int32_t fingerId) : BaseEventInfo("default")
583     {
584         fingerId_ = fingerId;
585     }
TouchLocationInfo(const std::string & type,int32_t fingerId)586     explicit TouchLocationInfo(const std::string& type, int32_t fingerId) : BaseEventInfo(type)
587     {
588         fingerId_ = fingerId;
589     }
590     ~TouchLocationInfo() override = default;
591 
SetGlobalLocation(const Offset & globalLocation)592     TouchLocationInfo& SetGlobalLocation(const Offset& globalLocation)
593     {
594         globalLocation_ = globalLocation;
595         return *this;
596     }
SetLocalLocation(const Offset & localLocation)597     TouchLocationInfo& SetLocalLocation(const Offset& localLocation)
598     {
599         localLocation_ = localLocation;
600         return *this;
601     }
602 
SetScreenLocation(const Offset & screenLocation)603     TouchLocationInfo& SetScreenLocation(const Offset& screenLocation)
604     {
605         screenLocation_ = screenLocation;
606         return *this;
607     }
608 
GetScreenLocation()609     const Offset& GetScreenLocation() const
610     {
611         return screenLocation_;
612     }
613 
GetLocalLocation()614     const Offset& GetLocalLocation() const
615     {
616         return localLocation_;
617     }
GetGlobalLocation()618     const Offset& GetGlobalLocation() const
619     {
620         return globalLocation_;
621     }
GetFingerId()622     int32_t GetFingerId() const
623     {
624         return fingerId_;
625     }
626 
SetSize(double size)627     void SetSize(double size)
628     {
629         size_ = size;
630     }
631 
GetSize()632     double GetSize() const
633     {
634         return size_;
635     }
636 
SetTouchDeviceId(int64_t deviceId)637     void SetTouchDeviceId(int64_t deviceId)
638     {
639         touchDeviceId_ = deviceId;
640     }
641 
GetTouchDeviceId()642     int64_t GetTouchDeviceId() const
643     {
644         return touchDeviceId_;
645     }
646 
GetTouchType()647     TouchType GetTouchType() const
648     {
649         return touchType_;
650     }
SetTouchType(TouchType type)651     void SetTouchType(TouchType type)
652     {
653         touchType_ = type;
654     }
655 
656 private:
657     // The finger id is used to identify the point of contact between the finger and the screen. Different fingers have
658     // different ids.
659     int32_t fingerId_ = -1;
660 
661     // global position at which the touch point contacts the screen.
662     Offset globalLocation_;
663     // Different from global location, The local location refers to the location of the contact point relative to the
664     // current node which has the recognizer.
665     Offset localLocation_;
666 
667     Offset screenLocation_;
668 
669     // finger touch size
670     double size_ = 0.0;
671 
672     // input device id
673     int64_t touchDeviceId_ = 0;
674 
675     // touch type
676     TouchType touchType_ = TouchType::UNKNOWN;
677 };
678 
679 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>;
680 
681 struct StateRecord {
682     std::string procedure;
683     std::string extraInfo;
684     std::string state;
685     std::string disposal;
686     int64_t timestamp = 0;
687 
StateRecordStateRecord688     StateRecord(const std::string& procedure, const std::string& extraInfo, const std::string& state,
689         const std::string& disposal, int64_t timestamp) : procedure(procedure), extraInfo(extraInfo),
690         state(state), disposal(disposal), timestamp(timestamp)
691     {}
692 
DumpStateRecord693     void Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
694     {
695         std::stringstream oss;
696         oss << "procedure: " << procedure;
697         if (!state.empty()) {
698             oss << ", " << "state: " << state << ", "
699                 << "disposal: " << disposal;
700         }
701         oss << ", " << "timestamp: " << ConvertTimestampToStr(timestamp);
702         dumpList.emplace_back(std::make_pair(depth, oss.str()));
703     }
704 };
705 
706 struct GestureSnapshot : public virtual AceType {
707     DECLARE_ACE_TYPE(GestureSnapshot, AceType);
708 
709 public:
AddProcedureGestureSnapshot710     void AddProcedure(const std::string& procedure, const std::string& extraInfo,
711         const std::string& state, const std::string& disposal, int64_t timestamp)
712     {
713         if (timestamp == 0) {
714             timestamp = GetCurrentTimestamp();
715         }
716         stateHistory.emplace_back(StateRecord(procedure, extraInfo, state, disposal, timestamp));
717     }
718 
CheckNeedAddMoveGestureSnapshot719     bool CheckNeedAddMove(const std::string& state, const std::string& disposal)
720     {
721         return stateHistory.empty() ||
722             stateHistory.back().state != state || stateHistory.back().disposal != disposal;
723     }
724 
DumpGestureSnapshot725     void Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
726     {
727         std::stringstream oss;
728         oss << "frameNodeId: " << nodeId << ", "
729             << "type: " << type << ", "
730             << "depth: " << this->depth << ", "
731             << std::hex
732             << "id: 0x" << id << ", "
733             << "parentId: 0x" << parentId;
734         if (!customInfo.empty()) {
735             oss << ", " << "customInfo: " << customInfo;
736         }
737         dumpList.emplace_back(std::make_pair(depth + this->depth, oss.str()));
738         dumpList.emplace_back(std::make_pair(depth + 1 + this->depth, "stateHistory:"));
739         for (const auto& state : stateHistory) {
740             state.Dump(dumpList, depth + 1 + 1 + this->depth);
741         }
742     }
743 
TransTouchTypeGestureSnapshot744     static std::string TransTouchType(TouchType type)
745     {
746         switch (type) {
747             case TouchType::DOWN:
748                 return "TouchDown";
749             case TouchType::MOVE:
750                 return "TouchMove";
751             case TouchType::UP:
752                 return "TouchUp";
753             case TouchType::CANCEL:
754                 return "TouchCancel";
755             default:
756                 return std::string("Type:").append(std::to_string(static_cast<int32_t>(type)));
757         }
758     }
759 
760     int32_t nodeId = -1;
761     std::string type;
762     uint64_t id = 0;
763     uint64_t parentId = 0;
764     int32_t depth = 0;
765     std::string customInfo;
766     std::list<StateRecord> stateHistory;
767 };
768 
769 class ACE_EXPORT TouchEventTarget : public virtual AceType {
770     DECLARE_ACE_TYPE(TouchEventTarget, AceType);
771 
772 public:
773     TouchEventTarget() = default;
TouchEventTarget(std::string nodeName,int32_t nodeId)774     TouchEventTarget(std::string nodeName, int32_t nodeId) : nodeName_(std::move(nodeName)), nodeId_(nodeId) {}
775     ~TouchEventTarget() override = default;
776 
777     // if return false means need to stop event dispatch.
778     virtual bool DispatchEvent(const TouchEvent& point) = 0;
779     // if return false means need to stop event bubbling.
780     virtual bool HandleEvent(const TouchEvent& point) = 0;
HandleEvent(const AxisEvent & event)781     virtual bool HandleEvent(const AxisEvent& event)
782     {
783         return true;
784     }
OnFlushTouchEventsBegin()785     virtual void OnFlushTouchEventsBegin() {}
OnFlushTouchEventsEnd()786     virtual void OnFlushTouchEventsEnd() {}
GetAxisDirection()787     virtual Axis GetAxisDirection()
788     {
789         return direction_;
790     }
791 
SetTouchRestrict(const TouchRestrict & touchRestrict)792     void SetTouchRestrict(const TouchRestrict& touchRestrict)
793     {
794         touchRestrict_ = touchRestrict;
795     }
796 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)797     void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
798     {
799         getEventTargetImpl_ = getEventTargetImpl;
800     }
801 
GetEventTarget()802     std::optional<EventTarget> GetEventTarget() const
803     {
804         if (getEventTargetImpl_) {
805             return getEventTargetImpl_();
806         }
807         return std::nullopt;
808     }
809 
810     // Coordinate offset is used to calculate the local location of the touch point in the render node.
SetCoordinateOffset(const Offset & coordinateOffset)811     void SetCoordinateOffset(const Offset& coordinateOffset)
812     {
813         coordinateOffset_ = coordinateOffset;
814     }
815 
816     // Gets the coordinate offset to calculate the local location of the touch point by manually.
GetCoordinateOffset()817     const Offset& GetCoordinateOffset() const
818     {
819         return coordinateOffset_;
820     }
821 
SetSubPipelineGlobalOffset(const Offset & subPipelineGlobalOffset,float viewScale)822     void SetSubPipelineGlobalOffset(const Offset& subPipelineGlobalOffset, float viewScale)
823     {
824         subPipelineGlobalOffset_ = subPipelineGlobalOffset;
825         viewScale_ = viewScale;
826     }
827 
DispatchMultiContainerEvent(const TouchEvent & point)828     bool DispatchMultiContainerEvent(const TouchEvent& point)
829     {
830 #ifdef OHOS_STANDARD_SYSTEM
831         if (!subPipelineGlobalOffset_.IsZero()) {
832             auto multiContainerPoint = point.UpdateScalePoint(
833                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
834             return DispatchEvent(multiContainerPoint);
835         }
836 #endif
837         return DispatchEvent(point);
838     }
839 
HandleMultiContainerEvent(const TouchEvent & point)840     bool HandleMultiContainerEvent(const TouchEvent& point)
841     {
842 #ifdef OHOS_STANDARD_SYSTEM
843         if (!subPipelineGlobalOffset_.IsZero()) {
844             auto multiContainerPoint = point.UpdateScalePoint(
845                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
846             return HandleEvent(multiContainerPoint);
847         }
848 #endif
849         return HandleEvent(point);
850     }
851 
GetNodeName()852     std::string GetNodeName() const
853     {
854         return nodeName_;
855     }
856 
SetNodeId(int id)857     void SetNodeId(int id)
858     {
859         if (nodeId_ != -1) {
860             return;
861         }
862         nodeId_ = id;
863     }
864 
GetNodeId()865     int32_t GetNodeId() const
866     {
867         return nodeId_;
868     }
869 
AttachFrameNode(const WeakPtr<NG::FrameNode> & node)870     virtual void AttachFrameNode(const WeakPtr<NG::FrameNode>& node)
871     {
872         if (!(node_.Invalid())) {
873             return;
874         }
875         node_ = node;
876     }
877 
GetAttachedNode()878     WeakPtr<NG::FrameNode> GetAttachedNode() const
879     {
880         return node_;
881     }
882 
Dump()883     virtual RefPtr<GestureSnapshot> Dump() const
884     {
885         RefPtr<GestureSnapshot> info = AceType::MakeRefPtr<GestureSnapshot>();
886         info->type = GetTypeName();
887         info->id = reinterpret_cast<uintptr_t>(this);
888         return info;
889     }
890 
SetTargetComponent(const RefPtr<NG::TargetComponent> & targetComponent)891     void SetTargetComponent(const RefPtr<NG::TargetComponent>& targetComponent)
892     {
893         if (!targetComponent_) {
894             targetComponent_ = targetComponent;
895         }
896     }
897 
GetTargetComponent()898     RefPtr<NG::TargetComponent> GetTargetComponent()
899     {
900         return targetComponent_;
901     }
902 
SetIsPostEventResult(bool isPostEventResult)903     void SetIsPostEventResult(bool isPostEventResult)
904     {
905         isPostEventResult_ = isPostEventResult;
906     }
907 
IsPostEventResult()908     bool IsPostEventResult() const
909     {
910         return isPostEventResult_;
911     }
912 
913 private:
ShouldResponse()914     virtual bool ShouldResponse() { return true; };
915 
916 protected:
917     Offset coordinateOffset_;
918     GetEventTargetImpl getEventTargetImpl_;
919     TouchRestrict touchRestrict_ { TouchRestrict::NONE };
920     Offset subPipelineGlobalOffset_;
921     float viewScale_ = 1.0f;
922     std::string nodeName_ = "NULL";
923     int32_t nodeId_ = -1;
924     WeakPtr<NG::FrameNode> node_ = nullptr;
925     Axis direction_ = Axis::NONE;
926     RefPtr<NG::TargetComponent> targetComponent_;
927     bool isPostEventResult_ = false;
928     std::optional<TimeStamp> firstInputTime_;
929 };
930 
931 using TouchTestResult = std::list<RefPtr<TouchEventTarget>>;
932 using ResponseLinkResult = std::list<RefPtr<NG::NGGestureRecognizer>>;
933 
934 class TouchEventInfo : public BaseEventInfo {
935     DECLARE_RELATIONSHIP_OF_CLASSES(TouchEventInfo, BaseEventInfo);
936 
937 public:
TouchEventInfo(const std::string & type)938     explicit TouchEventInfo(const std::string& type) : BaseEventInfo(type) {}
939     ~TouchEventInfo() override = default;
940 
AddTouchLocationInfo(TouchLocationInfo && info)941     void AddTouchLocationInfo(TouchLocationInfo&& info)
942     {
943         touches_.emplace_back(info);
944     }
AddChangedTouchLocationInfo(TouchLocationInfo && info)945     void AddChangedTouchLocationInfo(TouchLocationInfo&& info)
946     {
947         changedTouches_.emplace_back(info);
948     }
AddHistoryLocationInfo(TouchLocationInfo && info)949     void AddHistoryLocationInfo(TouchLocationInfo&& info)
950     {
951         history_.emplace_back(std::move(info));
952     }
953 
GetTouches()954     const std::list<TouchLocationInfo>& GetTouches() const
955     {
956         return touches_;
957     }
GetChangedTouches()958     const std::list<TouchLocationInfo>& GetChangedTouches() const
959     {
960         return changedTouches_;
961     }
GetHistory()962     const std::list<TouchLocationInfo>& GetHistory() const
963     {
964         return history_;
965     }
AddHistoryPointerEvent(const std::shared_ptr<MMI::PointerEvent> & info)966     void AddHistoryPointerEvent(const std::shared_ptr<MMI::PointerEvent>& info)
967     {
968         historyPointerEvent_.emplace_back(info);
969     }
GetHistoryPointerEvent()970     const std::list<std::shared_ptr<MMI::PointerEvent>>& GetHistoryPointerEvent() const
971     {
972         return historyPointerEvent_;
973     }
SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)974     void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
975     {
976         pointerEvent_ = pointerEvent;
977     }
GetPointerEvent()978     const std::shared_ptr<MMI::PointerEvent>& GetPointerEvent() const
979     {
980         return pointerEvent_;
981     }
982 
SetTouchEventsEnd(bool isTouchEventsEnd)983     void SetTouchEventsEnd(bool isTouchEventsEnd)
984     {
985         isTouchEventsEnd_ = isTouchEventsEnd;
986     }
987 
GetTouchEventsEnd()988     bool GetTouchEventsEnd() const
989     {
990         return isTouchEventsEnd_;
991     }
992 
ConvertToTouchEvent()993     TouchEvent ConvertToTouchEvent() const
994     {
995         TouchEvent touchEvent;
996         if (!changedTouches_.empty()) {
997             touchEvent.x = static_cast<float>(changedTouches_.front().GetGlobalLocation().GetX());
998             touchEvent.y = static_cast<float>(changedTouches_.front().GetGlobalLocation().GetY());
999             touchEvent.screenX = static_cast<float>(changedTouches_.front().GetScreenLocation().GetX());
1000             touchEvent.screenY = static_cast<float>(changedTouches_.front().GetScreenLocation().GetY());
1001             touchEvent.localX = static_cast<float>(changedTouches_.front().GetLocalLocation().GetX());
1002             touchEvent.localY = static_cast<float>(changedTouches_.front().GetLocalLocation().GetY());
1003             touchEvent.id = changedTouches_.front().GetFingerId();
1004             touchEvent.force = changedTouches_.front().GetForce();
1005             touchEvent.type = changedTouches_.front().GetTouchType();
1006             touchEvent.tiltX = changedTouches_.front().GetTiltX();
1007             touchEvent.tiltY = changedTouches_.front().GetTiltY();
1008         }
1009         touchEvent.time = timeStamp_;
1010         return touchEvent;
1011     }
1012 private:
1013     std::shared_ptr<MMI::PointerEvent> pointerEvent_;
1014     std::list<TouchLocationInfo> touches_;
1015     std::list<TouchLocationInfo> changedTouches_;
1016     std::list<TouchLocationInfo> history_;
1017     std::list<std::shared_ptr<MMI::PointerEvent>> historyPointerEvent_;
1018     bool isTouchEventsEnd_ { false };
1019 };
1020 
1021 class ACE_EXPORT GestureEventResult : public AceType {
1022     DECLARE_ACE_TYPE(GestureEventResult, AceType)
1023 
1024 public:
1025     GestureEventResult() = default;
1026     ~GestureEventResult() = default;
1027 
1028     virtual void SetGestureEventResult(bool result) = 0;
1029     virtual void SetGestureEventResult(bool result, bool stopPropagation) = 0;
1030 };
1031 
1032 class NativeEmbeadTouchInfo : public BaseEventInfo {
1033     DECLARE_RELATIONSHIP_OF_CLASSES(NativeEmbeadTouchInfo, BaseEventInfo);
1034 
1035 public:
NativeEmbeadTouchInfo(const std::string & embedId,const TouchEventInfo & touchEventInfo,const RefPtr<GestureEventResult> & result)1036     NativeEmbeadTouchInfo(const std::string& embedId,
1037         const TouchEventInfo& touchEventInfo,
1038         const RefPtr<GestureEventResult>& result)
1039         : BaseEventInfo("NativeEmbeadTouchInfo"), embedId_(embedId), touchEvent_(touchEventInfo), result_(result) {}
1040     ~NativeEmbeadTouchInfo() override = default;
1041 
GetEmbedId()1042     const std::string& GetEmbedId() const
1043     {
1044         return embedId_;
1045     }
1046 
GetTouchEventInfo()1047     const TouchEventInfo& GetTouchEventInfo() const
1048     {
1049         return touchEvent_;
1050     }
GetResult()1051     const RefPtr<GestureEventResult>& GetResult() const
1052     {
1053         return result_;
1054     }
1055 private:
1056     std::string embedId_;
1057     TouchEventInfo touchEvent_;
1058     RefPtr<GestureEventResult> result_;
1059 };
1060 
1061 using TouchEventFunc = std::function<void(TouchEventInfo&)>;
1062 using OnTouchEventCallback = std::function<void(const TouchEventInfo&)>;
1063 using CatchTouchEventCallback = std::function<void()>;
1064 
1065 } // namespace OHOS::Ace
1066 
1067 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H
1068