• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     int32_t width = 0;
76     int32_t height = 0;
77     int32_t operatingHand = 0;
78 
CovertIdfinal79     void CovertId()
80     {
81         if (sourceTool == SourceTool::PEN) {
82             originalId = TOUCH_TOOL_BASE_ID + static_cast<int32_t>(sourceTool);
83             id = id + originalId;
84         }
85     }
86 };
87 
88 /**
89  * @brief TouchEvent contains the active change point and a list of all touch points.
90  */
91 struct TouchEvent final : public PointerEvent {
92     ~TouchEvent() = default;
93     // the active changed point info
94     // The ID is used to identify the point of contact between the finger and the screen. Different fingers have
95     // different ids.
96     int32_t postEventNodeId = 0;
97     int32_t id = 0;
98     TouchType type = TouchType::UNKNOWN;
99     TouchType pullType = TouchType::UNKNOWN;
100     double size = 0.0;
101     float force = 0.0f;
102     std::optional<float> tiltX;
103     std::optional<float> tiltY;
104     int64_t deviceId = 0;
105     int32_t targetDisplayId = 0;
106     SourceType sourceType = SourceType::NONE;
107     SourceTool sourceTool = SourceTool::UNKNOWN;
108     int32_t touchEventId = 0;
109     int32_t operatingHand = 0;
110     bool isInterpolated = false;
111     bool isMouseTouchTest = false;
112     bool isFalsified = false;
113     bool isPassThroughMode = false;
114 
115     // all points on the touch screen.
116     std::vector<TouchPoint> pointers;
117     std::shared_ptr<MMI::PointerEvent> pointerEvent { nullptr };
118     // historical points
119     std::vector<TouchEvent> history;
120     std::vector<KeyCode> pressedKeyCodes_;
121 
122     std::list<std::string> childTouchTestList;
123 
124     // Coordinates relative to the upper-left corner of the current component
125     float localX = 0.0f;
126     float localY = 0.0f;
127     int32_t originalId = 0;
128     bool isInjected = false;
129     bool isPrivacyMode = false;
130 
131     // Save historical touch point slope.
132     float inputXDeltaSlope = 0.0f;
133     float inputYDeltaSlope = 0.0f;
134     TimeStamp pressedTime;
135     int32_t width = 0;
136     int32_t height = 0;
137 
TouchEventfinal138     TouchEvent()
139     {
140         eventType = UIInputEventType::TOUCH;
141     }
142 
SetIdfinal143     TouchEvent& SetId(int32_t id)
144     {
145         this->id = id;
146         return *this;
147     }
148 
SetXfinal149     TouchEvent& SetX(float x)
150     {
151         this->x = x;
152         return *this;
153     }
154 
SetYfinal155     TouchEvent& SetY(float y)
156     {
157         this->y = y;
158         return *this;
159     }
160 
SetScreenXfinal161     TouchEvent& SetScreenX(float screenX)
162     {
163         this->screenX = screenX;
164         return *this;
165     }
166 
SetScreenYfinal167     TouchEvent& SetScreenY(float screenY)
168     {
169         this->screenY = screenY;
170         return *this;
171     }
172 
SetTimefinal173     TouchEvent& SetTime(TimeStamp time)
174     {
175         this->time = time;
176         return *this;
177     }
178 
GetTimeStampfinal179     TimeStamp GetTimeStamp() const
180     {
181         return this->time;
182     }
183 
SetTypefinal184     TouchEvent& SetType(TouchType type)
185     {
186         this->type = type;
187         return *this;
188     }
189 
SetPullTypefinal190     TouchEvent& SetPullType(TouchType pullType)
191     {
192         this->pullType = pullType;
193         return *this;
194     }
195 
SetSizefinal196     TouchEvent& SetSize(double size)
197     {
198         this->size = size;
199         return *this;
200     }
201 
SetForcefinal202     TouchEvent& SetForce(float force)
203     {
204         this->force = force;
205         return *this;
206     }
207 
SetTiltXfinal208     TouchEvent& SetTiltX(std::optional<float> tiltX)
209     {
210         this->tiltX = tiltX;
211         return *this;
212     }
213 
SetTiltYfinal214     TouchEvent& SetTiltY(std::optional<float> tiltY)
215     {
216         this->tiltY = tiltY;
217         return *this;
218     }
219 
SetDeviceIdfinal220     TouchEvent& SetDeviceId(int64_t deviceId)
221     {
222         this->deviceId = deviceId;
223         return *this;
224     }
225 
SetTargetDisplayIdfinal226     TouchEvent& SetTargetDisplayId(int32_t targetDisplayId)
227     {
228         this->targetDisplayId = targetDisplayId;
229         return *this;
230     }
231 
SetSourceTypefinal232     TouchEvent& SetSourceType(SourceType sourceType)
233     {
234         this->sourceType = sourceType;
235         return *this;
236     }
237 
SetSourceToolfinal238     TouchEvent& SetSourceTool(SourceTool sourceTool)
239     {
240         this->sourceTool = sourceTool;
241         return *this;
242     }
243 
SetTouchEventIdfinal244     TouchEvent& SetTouchEventId(int32_t touchEventId)
245     {
246         this->touchEventId = touchEventId;
247         return *this;
248     }
249 
SetIsInterpolatedfinal250     TouchEvent& SetIsInterpolated(bool isInterpolated)
251     {
252         this->isInterpolated = isInterpolated;
253         return *this;
254     }
255 
SetPointersfinal256     TouchEvent& SetPointers(std::vector<TouchPoint> pointers)
257     {
258         this->pointers = std::move(pointers);
259         return *this;
260     }
261 
SetPointerEventfinal262     TouchEvent& SetPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
263     {
264         this->pointerEvent = std::move(pointerEvent);
265         return *this;
266     }
267 
SetOriginalIdfinal268     TouchEvent& SetOriginalId(int32_t originalId)
269     {
270         this->originalId = originalId;
271         return *this;
272     }
273 
SetIsInjectedfinal274     TouchEvent& SetIsInjected(bool isInjected)
275     {
276         this->isInjected = isInjected;
277         return *this;
278     }
279 
SetInputXDeltaSlopefinal280     TouchEvent& SetInputXDeltaSlope(float inputXDeltaSlope)
281     {
282         this->inputXDeltaSlope = inputXDeltaSlope;
283         return *this;
284     }
285 
SetInputYDeltaSlopefinal286     TouchEvent& SetInputYDeltaSlope(float inputYDeltaSlope)
287     {
288         this->inputYDeltaSlope = inputYDeltaSlope;
289         return *this;
290     }
291 
SetPressedKeyCodesfinal292     TouchEvent& SetPressedKeyCodes(const std::vector<KeyCode>& pressedKeyCodes)
293     {
294         this->pressedKeyCodes_ = pressedKeyCodes;
295         return *this;
296     }
297 
SetIsPassThroughModefinal298     TouchEvent& SetIsPassThroughMode(bool isPassThroughMode)
299     {
300         this->isPassThroughMode = isPassThroughMode;
301         return *this;
302     }
303 
SetPressedTimefinal304     TouchEvent& SetPressedTime(TimeStamp pressedTime)
305     {
306         this->pressedTime = pressedTime;
307         return *this;
308     }
309 
SetWidthfinal310     TouchEvent& SetWidth(int32_t width)
311     {
312         this->width = width;
313         return *this;
314     }
315 
SetHeightfinal316     TouchEvent& SetHeight(int32_t height)
317     {
318         this->height = height;
319         return *this;
320     }
321 
SetOperatingHandfinal322     TouchEvent& SetOperatingHand(int32_t operatingHand)
323     {
324         this->operatingHand = operatingHand;
325         return *this;
326     }
327 
CloneWithfinal328     TouchEvent CloneWith(float scale) const
329     {
330         return CloneWith(scale, 0.0f, 0.0f, std::nullopt);
331     }
332 
CloneWithfinal333     TouchEvent CloneWith(float scale, float offsetX, float offsetY, std::optional<int32_t> pointId) const
334     {
335         TouchEvent event;
336         event.id = pointId.has_value() ? pointId.value() : id;
337         event.x = (x - offsetX) / scale;
338         event.y = (y - offsetY) / scale;
339         event.screenX = (screenX - offsetX) / scale;
340         event.screenY = (screenY - offsetY) / scale;
341         event.type = type;
342         event.pullType = pullType;
343         event.time = time;
344         event.size = size;
345         event.force = force;
346         event.tiltX = tiltX;
347         event.tiltY = tiltY;
348         event.deviceId = deviceId;
349         event.targetDisplayId = targetDisplayId;
350         event.sourceType = sourceType;
351         event.sourceTool = sourceTool;
352         event.touchEventId = touchEventId;
353         event.isInterpolated = isInterpolated;
354         event.pointers = std::move(pointers);
355         event.pointerEvent = std::move(pointerEvent);
356         event.pressedKeyCodes_ = std::move(pressedKeyCodes_);
357         event.originalId = originalId;
358         event.isInjected = isInjected;
359         event.isPrivacyMode = isPrivacyMode;
360         event.inputXDeltaSlope = inputXDeltaSlope;
361         event.inputYDeltaSlope = inputYDeltaSlope;
362         event.isPassThroughMode = isPassThroughMode;
363         event.width = width;
364         event.height = height;
365         event.pressedTime = pressedTime;
366         event.operatingHand = operatingHand;
367         return event;
368     }
369 
ToJsonValuefinal370     void ToJsonValue(std::unique_ptr<JsonValue>& json) const
371     {
372         json->Put("id", id);
373         json->Put("x", x);
374         json->Put("y", y);
375         json->Put("sx", screenX);
376         json->Put("sy", screenY);
377         json->Put("ty", static_cast<int32_t>(type));
378         int64_t timeValue = std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count();
379         json->Put("ti", timeValue);
380         json->Put("si", size);
381         json->Put("f", force);
382         int32_t hasTiltX = tiltX.has_value() ? 1 : 0;
383         json->Put("hx", hasTiltX);
384         if (hasTiltX) {
385             json->Put("tx", tiltX.value());
386         }
387         int32_t hasTiltY = tiltY.has_value() ? 1 : 0;
388         json->Put("hy", hasTiltY);
389         if (tiltY.has_value()) {
390             json->Put("ty", tiltY.value());
391         }
392         json->Put("d", deviceId);
393         json->Put("sty", static_cast<int32_t>(sourceType));
394         json->Put("sto", static_cast<int32_t>(sourceTool));
395     }
396 
FromJsonfinal397     void FromJson(const std::unique_ptr<JsonValue>& json)
398     {
399         id = json->GetInt("id");
400         x = json->GetDouble("x");
401         y = json->GetDouble("y");
402         screenX = json->GetDouble("sx");
403         screenY = json->GetDouble("sy");
404         type = static_cast<TouchType>(json->GetInt("ty"));
405         int64_t timeValue = json->GetInt64("ti");
406         time = TimeStamp(std::chrono::nanoseconds(timeValue));
407         size = json->GetDouble("si");
408         force = json->GetDouble("f");
409         int32_t hasTiltX = json->GetInt("hx");
410         int32_t hasTiltY = json->GetInt("hy");
411         if (hasTiltX) {
412             tiltX = json->GetDouble("tx");
413         }
414         if (hasTiltY) {
415             tiltY = json->GetDouble("ty");
416         }
417         deviceId = json->GetInt64("d");
418         sourceType = static_cast<SourceType>(json->GetInt("sty"));
419         sourceTool = static_cast<SourceTool>(json->GetInt("sto"));
420     }
421 
GetOffsetfinal422     Offset GetOffset() const
423     {
424         return Offset(x, y);
425     }
426 
GetScreenOffsetfinal427     Offset GetScreenOffset() const
428     {
429         return Offset(screenX, screenY);
430     }
431 
CovertIdfinal432     void CovertId()
433     {
434         if ((sourceType == SourceType::TOUCH) && (sourceTool == SourceTool::PEN)) {
435             id = id + TOUCH_TOOL_BASE_ID + static_cast<int32_t>(sourceTool);
436             originalId = TOUCH_TOOL_BASE_ID + static_cast<int32_t>(sourceTool);
437         }
438     }
439 
CreateScalePointfinal440     TouchEvent CreateScalePoint(float scale) const
441     {
442         if (NearZero(scale)) {
443             return CloneWith(1);
444         }
445         auto temp = pointers;
446         std::for_each(temp.begin(), temp.end(), [scale](auto&& point) {
447             point.x = point.x / scale;
448             point.y = point.y / scale;
449             point.screenX = point.screenX / scale;
450             point.screenY = point.screenY / scale;
451         });
452         return CloneWith(scale);
453     }
454 
UpdateScalePointfinal455     TouchEvent UpdateScalePoint(float scale, float offsetX, float offsetY, int32_t pointId) const
456     {
457         auto temp = pointers;
458         if (NearZero(scale)) {
459             std::for_each(temp.begin(), temp.end(), [offsetX, offsetY](auto&& point) {
460                 point.x = point.x - offsetX;
461                 point.y = point.y - offsetY;
462                 point.screenX = point.screenX - offsetX;
463                 point.screenY = point.screenY - offsetY;
464             });
465             return CloneWith(1, offsetX, offsetY, pointId);
466         }
467 
468         std::for_each(temp.begin(), temp.end(), [scale, offsetX, offsetY](auto&& point) {
469             point.x = (point.x - offsetX) / scale;
470             point.y = (point.y - offsetY) / scale;
471             point.screenX = (point.screenX - offsetX) / scale;
472             point.screenY = (point.screenY - offsetY) / scale;
473         });
474         return CloneWith(scale, offsetX, offsetY, pointId);
475     }
476 
UpdatePointersfinal477     TouchEvent UpdatePointers() const
478     {
479         TouchPoint point { .id = id,
480             .x = x,
481             .y = y,
482             .screenX = screenX,
483             .screenY = screenY,
484             .downTime = time,
485             .size = size,
486             .force = force,
487             .isPressed = (type == TouchType::DOWN),
488             .operatingHand = operatingHand };
489         TouchEvent event;
490         event.SetId(id)
491             .SetX(x)
492             .SetY(y)
493             .SetScreenX(screenX)
494             .SetScreenY(screenY)
495             .SetType(type)
496             .SetTime(time)
497             .SetSize(size)
498             .SetForce(force)
499             .SetDeviceId(deviceId)
500             .SetTargetDisplayId(targetDisplayId)
501             .SetSourceType(sourceType)
502             .SetIsInterpolated(isInterpolated)
503             .SetPointerEvent(pointerEvent)
504             .SetOriginalId(originalId)
505             .SetIsPassThroughMode(isPassThroughMode)
506             .SetOperatingHand(operatingHand);
507         event.pointers.emplace_back(std::move(point));
508         return event;
509     }
510 
IsPenHoverEventfinal511     bool IsPenHoverEvent() const
512     {
513         return sourceTool == SourceTool::PEN && (type == TouchType::PROXIMITY_IN ||
514         type == TouchType::PROXIMITY_OUT || (type == TouchType::MOVE && NearZero(force)));
515     }
516 };
517 
518 namespace Platform {
519 ACE_FORCE_EXPORT Offset GetTouchEventOriginOffset(const TouchEvent& event);
520 ACE_FORCE_EXPORT TimeStamp GetTouchEventOriginTimeStamp(const TouchEvent& event);
521 ACE_FORCE_EXPORT void UpdatePressedKeyCodes(std::vector<KeyCode>& pressedKeyCodes);
522 } // namespace Platform
523 
524 struct TouchRestrict final {
525     static constexpr uint32_t NONE = 0x00000000;
526     static constexpr uint32_t CLICK = 0x00000001;
527     static constexpr uint32_t LONG_PRESS = 0x00000010;
528     static constexpr uint32_t SWIPE_LEFT = 0x00000100;
529     static constexpr uint32_t SWIPE_RIGHT = 0x00000200;
530     static constexpr uint32_t SWIPE_UP = 0x00000400;
531     static constexpr uint32_t SWIPE_DOWN = 0x00000800;
532     static constexpr uint32_t SWIPE = 0x00000F00;
533     static constexpr uint32_t SWIPE_VERTICAL = 0x0000C00;   // Vertical
534     static constexpr uint32_t SWIPE_HORIZONTAL = 0x0000300; // Horizontal
535     static constexpr uint32_t TOUCH = 0xFFFFFFFF;
536 
537     uint32_t forbiddenType = NONE;
538 
UpdateForbiddenTypefinal539     void UpdateForbiddenType(uint32_t gestureType)
540     {
541         forbiddenType |= gestureType;
542     }
543     SourceType sourceType = SourceType::NONE;
544 
545     SourceType hitTestType = SourceType::TOUCH;
546 
547     InputEventType inputEventType = InputEventType::TOUCH_SCREEN;
548 
549     TouchEvent touchEvent;
550 
551     std::list<std::string> childTouchTestList;
552 
553     // use to dump event tree
554     NG::EventTreeType touchTestType = NG::EventTreeType::TOUCH;
555 };
556 
557 class TouchCallBackInfo : public BaseEventInfo {
558     DECLARE_RELATIONSHIP_OF_CLASSES(TouchCallBackInfo, BaseEventInfo);
559 
560 public:
TouchCallBackInfo(TouchType type)561     explicit TouchCallBackInfo(TouchType type) : BaseEventInfo("onTouchEvent"), touchType_(type) {}
562     ~TouchCallBackInfo() override = default;
563 
SetScreenX(float screenX)564     void SetScreenX(float screenX)
565     {
566         screenX_ = screenX;
567     }
GetScreenX()568     float GetScreenX() const
569     {
570         return screenX_;
571     }
SetScreenY(float screenY)572     void SetScreenY(float screenY)
573     {
574         screenY_ = screenY;
575     }
GetScreenY()576     float GetScreenY() const
577     {
578         return screenY_;
579     }
SetLocalX(float localX)580     void SetLocalX(float localX)
581     {
582         localX_ = localX;
583     }
GetLocalX()584     float GetLocalX() const
585     {
586         return localX_;
587     }
SetLocalY(float localY)588     void SetLocalY(float localY)
589     {
590         localY_ = localY;
591     }
GetLocalY()592     float GetLocalY() const
593     {
594         return localY_;
595     }
SetTouchType(TouchType type)596     void SetTouchType(TouchType type)
597     {
598         touchType_ = type;
599     }
GetTouchType()600     TouchType GetTouchType() const
601     {
602         return touchType_;
603     }
SetTimeStamp(const TimeStamp & time)604     void SetTimeStamp(const TimeStamp& time)
605     {
606         time_ = time;
607     }
GetTimeStamp()608     TimeStamp GetTimeStamp() const
609     {
610         return time_;
611     }
612 
613 private:
614     float screenX_ = 0.0f;
615     float screenY_ = 0.0f;
616     float localX_ = 0.0f;
617     float localY_ = 0.0f;
618     TouchType touchType_ = TouchType::UNKNOWN;
619     TimeStamp time_;
620 };
621 
622 class TouchLocationInfo : public BaseEventInfo {
623     DECLARE_RELATIONSHIP_OF_CLASSES(TouchLocationInfo, TypeInfoBase);
624 
625 public:
TouchLocationInfo(int32_t fingerId)626     explicit TouchLocationInfo(int32_t fingerId) : BaseEventInfo("default")
627     {
628         fingerId_ = fingerId;
629     }
TouchLocationInfo(const std::string & type,int32_t fingerId)630     explicit TouchLocationInfo(const std::string& type, int32_t fingerId) : BaseEventInfo(type)
631     {
632         fingerId_ = fingerId;
633     }
634     ~TouchLocationInfo() override = default;
635 
SetGlobalLocation(const Offset & globalLocation)636     TouchLocationInfo& SetGlobalLocation(const Offset& globalLocation)
637     {
638         globalLocation_ = globalLocation;
639         return *this;
640     }
SetLocalLocation(const Offset & localLocation)641     TouchLocationInfo& SetLocalLocation(const Offset& localLocation)
642     {
643         localLocation_ = localLocation;
644         return *this;
645     }
646 
SetScreenLocation(const Offset & screenLocation)647     TouchLocationInfo& SetScreenLocation(const Offset& screenLocation)
648     {
649         screenLocation_ = screenLocation;
650         return *this;
651     }
652 
GetScreenLocation()653     const Offset& GetScreenLocation() const
654     {
655         return screenLocation_;
656     }
657 
GetLocalLocation()658     const Offset& GetLocalLocation() const
659     {
660         return localLocation_;
661     }
GetGlobalLocation()662     const Offset& GetGlobalLocation() const
663     {
664         return globalLocation_;
665     }
GetFingerId()666     int32_t GetFingerId() const
667     {
668         return fingerId_;
669     }
670 
SetSize(double size)671     void SetSize(double size)
672     {
673         size_ = size;
674     }
675 
GetSize()676     double GetSize() const
677     {
678         return size_;
679     }
680 
SetTouchDeviceId(int64_t deviceId)681     void SetTouchDeviceId(int64_t deviceId)
682     {
683         touchDeviceId_ = deviceId;
684     }
685 
GetTouchDeviceId()686     int64_t GetTouchDeviceId() const
687     {
688         return touchDeviceId_;
689     }
690 
GetTouchType()691     TouchType GetTouchType() const
692     {
693         return touchType_;
694     }
SetTouchType(TouchType type)695     void SetTouchType(TouchType type)
696     {
697         touchType_ = type;
698     }
SetPressedTime(TimeStamp pressedTime)699     void SetPressedTime(TimeStamp pressedTime)
700     {
701         pressedTime_ = pressedTime;
702     }
GetPressedTime()703     TimeStamp GetPressedTime() const
704     {
705         return pressedTime_;
706     }
SetWidth(int32_t width)707     void SetWidth(int32_t width)
708     {
709         width_ = width;
710     }
GetWidth()711     int32_t GetWidth() const
712     {
713         return width_;
714     }
SetHeight(int32_t height)715     void SetHeight(int32_t height)
716     {
717         height_ = height;
718     }
GetHeight()719     int32_t GetHeight() const
720     {
721         return height_;
722     }
723 
724 private:
725     // The finger id is used to identify the point of contact between the finger and the screen. Different fingers have
726     // different ids.
727     int32_t fingerId_ = -1;
728 
729     // global position at which the touch point contacts the screen.
730     Offset globalLocation_;
731     // Different from global location, The local location refers to the location of the contact point relative to the
732     // current node which has the recognizer.
733     Offset localLocation_;
734 
735     Offset screenLocation_;
736 
737     // finger touch size
738     double size_ = 0.0;
739 
740     // input device id
741     int64_t touchDeviceId_ = 0;
742 
743     // touch type
744     TouchType touchType_ = TouchType::UNKNOWN;
745     TimeStamp pressedTime_;
746     int32_t width_ = 0;
747     int32_t height_ = 0;
748 };
749 
750 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>;
751 
752 struct StateRecord {
753     std::string procedure;
754     std::string extraInfo;
755     std::string state;
756     std::string disposal;
757     int64_t timestamp = 0;
758 
StateRecordStateRecord759     StateRecord(const std::string& procedure, const std::string& extraInfo, const std::string& state,
760         const std::string& disposal, int64_t timestamp) : procedure(procedure), extraInfo(extraInfo),
761         state(state), disposal(disposal), timestamp(timestamp)
762     {}
763 
DumpStateRecord764     void Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
765     {
766         std::stringstream oss;
767         oss << "procedure: " << procedure;
768         if (!state.empty()) {
769             oss << ", " << "state: " << state << ", "
770                 << "disposal: " << disposal;
771         }
772         oss << ", " << "timestamp: " << ConvertTimestampToStr(timestamp);
773         dumpList.emplace_back(std::make_pair(depth, oss.str()));
774     }
775 };
776 
777 struct GestureSnapshot : public virtual AceType {
778     DECLARE_ACE_TYPE(GestureSnapshot, AceType);
779 
780 public:
AddProcedureGestureSnapshot781     void AddProcedure(const std::string& procedure, const std::string& extraInfo,
782         const std::string& state, const std::string& disposal, int64_t timestamp)
783     {
784         if (timestamp == 0) {
785             timestamp = GetCurrentTimestamp();
786         }
787         stateHistory.emplace_back(StateRecord(procedure, extraInfo, state, disposal, timestamp));
788     }
789 
CheckNeedAddMoveGestureSnapshot790     bool CheckNeedAddMove(const std::string& state, const std::string& disposal)
791     {
792         return stateHistory.empty() ||
793             stateHistory.back().state != state || stateHistory.back().disposal != disposal;
794     }
795 
DumpGestureSnapshot796     void Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
797     {
798         std::stringstream oss;
799         oss << "frameNodeId: " << nodeId << ", "
800             << "type: " << type << ", "
801             << "depth: " << this->depth << ", "
802             << std::hex
803             << "id: 0x" << id << ", "
804             << "parentId: 0x" << parentId;
805         if (!customInfo.empty()) {
806             oss << ", " << "customInfo: " << customInfo;
807         }
808         dumpList.emplace_back(std::make_pair(depth + this->depth, oss.str()));
809         dumpList.emplace_back(std::make_pair(depth + 1 + this->depth, "stateHistory:"));
810         for (const auto& state : stateHistory) {
811             state.Dump(dumpList, depth + 1 + 1 + this->depth);
812         }
813     }
814 
TransTouchTypeGestureSnapshot815     static std::string TransTouchType(TouchType type)
816     {
817         switch (type) {
818             case TouchType::DOWN:
819                 return "TouchDown";
820             case TouchType::MOVE:
821                 return "TouchMove";
822             case TouchType::UP:
823                 return "TouchUp";
824             case TouchType::CANCEL:
825                 return "TouchCancel";
826             default:
827                 return std::string("Type:").append(std::to_string(static_cast<int32_t>(type)));
828         }
829     }
830 
831     int32_t nodeId = -1;
832     std::string type;
833     uint64_t id = 0;
834     uint64_t parentId = 0;
835     int32_t depth = 0;
836     std::string customInfo;
837     std::list<StateRecord> stateHistory;
838 };
839 
840 class ACE_EXPORT TouchEventTarget : public virtual AceType {
841     DECLARE_ACE_TYPE(TouchEventTarget, AceType);
842 
843 public:
844     TouchEventTarget() = default;
TouchEventTarget(std::string nodeName,int32_t nodeId)845     TouchEventTarget(std::string nodeName, int32_t nodeId) : nodeName_(std::move(nodeName)), nodeId_(nodeId) {}
846     ~TouchEventTarget() override = default;
847 
848     // if return false means need to stop event dispatch.
849     virtual bool DispatchEvent(const TouchEvent& point) = 0;
850     // if return false means need to stop event bubbling.
851     virtual bool HandleEvent(const TouchEvent& point) = 0;
HandleEvent(const AxisEvent & event)852     virtual bool HandleEvent(const AxisEvent& event)
853     {
854         return true;
855     }
OnFlushTouchEventsBegin()856     virtual void OnFlushTouchEventsBegin() {}
OnFlushTouchEventsEnd()857     virtual void OnFlushTouchEventsEnd() {}
GetAxisDirection()858     virtual Axis GetAxisDirection()
859     {
860         return direction_;
861     }
862 
SetTouchRestrict(const TouchRestrict & touchRestrict)863     void SetTouchRestrict(const TouchRestrict& touchRestrict)
864     {
865         touchRestrict_ = touchRestrict;
866     }
867 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)868     void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
869     {
870         getEventTargetImpl_ = getEventTargetImpl;
871     }
872 
GetEventTarget()873     std::optional<EventTarget> GetEventTarget() const
874     {
875         if (getEventTargetImpl_) {
876             return getEventTargetImpl_();
877         }
878         return std::nullopt;
879     }
880 
881     // Coordinate offset is used to calculate the local location of the touch point in the render node.
SetCoordinateOffset(const Offset & coordinateOffset)882     void SetCoordinateOffset(const Offset& coordinateOffset)
883     {
884         coordinateOffset_ = coordinateOffset;
885     }
886 
887     // Gets the coordinate offset to calculate the local location of the touch point by manually.
GetCoordinateOffset()888     const Offset& GetCoordinateOffset() const
889     {
890         return coordinateOffset_;
891     }
892 
SetSubPipelineGlobalOffset(const Offset & subPipelineGlobalOffset,float viewScale)893     void SetSubPipelineGlobalOffset(const Offset& subPipelineGlobalOffset, float viewScale)
894     {
895         subPipelineGlobalOffset_ = subPipelineGlobalOffset;
896         viewScale_ = viewScale;
897     }
898 
DispatchMultiContainerEvent(const TouchEvent & point)899     bool DispatchMultiContainerEvent(const TouchEvent& point)
900     {
901 #ifdef OHOS_STANDARD_SYSTEM
902         if (!subPipelineGlobalOffset_.IsZero()) {
903             auto multiContainerPoint = point.UpdateScalePoint(
904                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
905             return DispatchEvent(multiContainerPoint);
906         }
907 #endif
908         return DispatchEvent(point);
909     }
910 
HandleMultiContainerEvent(const TouchEvent & point)911     bool HandleMultiContainerEvent(const TouchEvent& point)
912     {
913 #ifdef OHOS_STANDARD_SYSTEM
914         if (!subPipelineGlobalOffset_.IsZero()) {
915             auto multiContainerPoint = point.UpdateScalePoint(
916                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
917             return HandleEvent(multiContainerPoint);
918         }
919 #endif
920         return HandleEvent(point);
921     }
922 
GetNodeName()923     std::string GetNodeName() const
924     {
925         return nodeName_;
926     }
927 
SetNodeId(int id)928     void SetNodeId(int id)
929     {
930         if (nodeId_ != -1) {
931             return;
932         }
933         nodeId_ = id;
934     }
935 
GetNodeId()936     int32_t GetNodeId() const
937     {
938         return nodeId_;
939     }
940 
AttachFrameNode(const WeakPtr<NG::FrameNode> & node)941     virtual void AttachFrameNode(const WeakPtr<NG::FrameNode>& node)
942     {
943         if (!(node_.Invalid())) {
944             return;
945         }
946         node_ = node;
947     }
948 
GetAttachedNode()949     WeakPtr<NG::FrameNode> GetAttachedNode() const
950     {
951         return node_;
952     }
953 
Dump()954     virtual RefPtr<GestureSnapshot> Dump() const
955     {
956         RefPtr<GestureSnapshot> info = AceType::MakeRefPtr<GestureSnapshot>();
957         info->type = GetTypeName();
958         info->id = reinterpret_cast<uintptr_t>(this);
959         return info;
960     }
961 
SetTargetComponent(const RefPtr<NG::TargetComponent> & targetComponent)962     void SetTargetComponent(const RefPtr<NG::TargetComponent>& targetComponent)
963     {
964         if (!targetComponent_) {
965             targetComponent_ = targetComponent;
966         }
967     }
968 
GetTargetComponent()969     RefPtr<NG::TargetComponent> GetTargetComponent()
970     {
971         return targetComponent_;
972     }
973 
SetIsPostEventResult(bool isPostEventResult)974     void SetIsPostEventResult(bool isPostEventResult)
975     {
976         isPostEventResult_ = isPostEventResult;
977     }
978 
IsPostEventResult()979     bool IsPostEventResult() const
980     {
981         return isPostEventResult_;
982     }
983 
984 private:
ShouldResponse()985     virtual bool ShouldResponse() { return true; };
986 
987 protected:
988     Offset coordinateOffset_;
989     GetEventTargetImpl getEventTargetImpl_;
990     TouchRestrict touchRestrict_ { TouchRestrict::NONE };
991     Offset subPipelineGlobalOffset_;
992     float viewScale_ = 1.0f;
993     std::string nodeName_ = "NULL";
994     int32_t nodeId_ = -1;
995     WeakPtr<NG::FrameNode> node_ = nullptr;
996     Axis direction_ = Axis::NONE;
997     RefPtr<NG::TargetComponent> targetComponent_;
998     bool isPostEventResult_ = false;
999     std::optional<TimeStamp> firstInputTime_;
1000 };
1001 
1002 using TouchTestResult = std::list<RefPtr<TouchEventTarget>>;
1003 using ResponseLinkResult = std::list<RefPtr<NG::NGGestureRecognizer>>;
1004 
1005 class TouchEventInfo : public BaseEventInfo {
1006     DECLARE_RELATIONSHIP_OF_CLASSES(TouchEventInfo, BaseEventInfo);
1007 
1008 public:
TouchEventInfo(const std::string & type)1009     explicit TouchEventInfo(const std::string& type) : BaseEventInfo(type) {}
1010     ~TouchEventInfo() override = default;
1011 
AddTouchLocationInfo(TouchLocationInfo && info)1012     void AddTouchLocationInfo(TouchLocationInfo&& info)
1013     {
1014         touches_.emplace_back(info);
1015     }
AddChangedTouchLocationInfo(TouchLocationInfo && info)1016     void AddChangedTouchLocationInfo(TouchLocationInfo&& info)
1017     {
1018         changedTouches_.emplace_back(info);
1019     }
AddHistoryLocationInfo(TouchLocationInfo && info)1020     void AddHistoryLocationInfo(TouchLocationInfo&& info)
1021     {
1022         history_.emplace_back(std::move(info));
1023     }
1024 
GetTouches()1025     const std::list<TouchLocationInfo>& GetTouches() const
1026     {
1027         return touches_;
1028     }
GetChangedTouches()1029     const std::list<TouchLocationInfo>& GetChangedTouches() const
1030     {
1031         return changedTouches_;
1032     }
GetHistory()1033     const std::list<TouchLocationInfo>& GetHistory() const
1034     {
1035         return history_;
1036     }
AddHistoryPointerEvent(const std::shared_ptr<MMI::PointerEvent> & info)1037     void AddHistoryPointerEvent(const std::shared_ptr<MMI::PointerEvent>& info)
1038     {
1039         historyPointerEvent_.emplace_back(info);
1040     }
GetHistoryPointerEvent()1041     const std::list<std::shared_ptr<MMI::PointerEvent>>& GetHistoryPointerEvent() const
1042     {
1043         return historyPointerEvent_;
1044     }
SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1045     void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1046     {
1047         pointerEvent_ = pointerEvent;
1048     }
GetPointerEvent()1049     const std::shared_ptr<MMI::PointerEvent>& GetPointerEvent() const
1050     {
1051         return pointerEvent_;
1052     }
1053 
SetTouchEventsEnd(bool isTouchEventsEnd)1054     void SetTouchEventsEnd(bool isTouchEventsEnd)
1055     {
1056         isTouchEventsEnd_ = isTouchEventsEnd;
1057     }
1058 
GetTouchEventsEnd()1059     bool GetTouchEventsEnd() const
1060     {
1061         return isTouchEventsEnd_;
1062     }
1063 
ConvertToTouchEvent()1064     TouchEvent ConvertToTouchEvent() const
1065     {
1066         TouchEvent touchEvent;
1067         if (!changedTouches_.empty()) {
1068             touchEvent.x = static_cast<float>(changedTouches_.front().GetGlobalLocation().GetX());
1069             touchEvent.y = static_cast<float>(changedTouches_.front().GetGlobalLocation().GetY());
1070             touchEvent.screenX = static_cast<float>(changedTouches_.front().GetScreenLocation().GetX());
1071             touchEvent.screenY = static_cast<float>(changedTouches_.front().GetScreenLocation().GetY());
1072             touchEvent.localX = static_cast<float>(changedTouches_.front().GetLocalLocation().GetX());
1073             touchEvent.localY = static_cast<float>(changedTouches_.front().GetLocalLocation().GetY());
1074             touchEvent.id = changedTouches_.front().GetFingerId();
1075             touchEvent.force = changedTouches_.front().GetForce();
1076             touchEvent.type = changedTouches_.front().GetTouchType();
1077             touchEvent.tiltX = changedTouches_.front().GetTiltX();
1078             touchEvent.tiltY = changedTouches_.front().GetTiltY();
1079             touchEvent.width = changedTouches_.front().GetWidth();
1080             touchEvent.height = changedTouches_.front().GetHeight();
1081             touchEvent.pressedTime = changedTouches_.front().GetPressedTime();
1082         }
1083         touchEvent.time = timeStamp_;
1084         return touchEvent;
1085     }
1086 private:
1087     std::shared_ptr<MMI::PointerEvent> pointerEvent_;
1088     std::list<TouchLocationInfo> touches_;
1089     std::list<TouchLocationInfo> changedTouches_;
1090     std::list<TouchLocationInfo> history_;
1091     std::list<std::shared_ptr<MMI::PointerEvent>> historyPointerEvent_;
1092     bool isTouchEventsEnd_ { false };
1093 };
1094 
1095 class ACE_EXPORT GestureEventResult : public AceType {
1096     DECLARE_ACE_TYPE(GestureEventResult, AceType)
1097 
1098 public:
1099     GestureEventResult() = default;
1100     ~GestureEventResult() = default;
1101 
1102     virtual void SetGestureEventResult(bool result) = 0;
1103     virtual void SetGestureEventResult(bool result, bool stopPropagation) = 0;
1104 };
1105 
1106 class NativeEmbeadTouchInfo : public BaseEventInfo {
1107     DECLARE_RELATIONSHIP_OF_CLASSES(NativeEmbeadTouchInfo, BaseEventInfo);
1108 
1109 public:
NativeEmbeadTouchInfo(const std::string & embedId,const TouchEventInfo & touchEventInfo,const RefPtr<GestureEventResult> & result)1110     NativeEmbeadTouchInfo(const std::string& embedId,
1111         const TouchEventInfo& touchEventInfo,
1112         const RefPtr<GestureEventResult>& result)
1113         : BaseEventInfo("NativeEmbeadTouchInfo"), embedId_(embedId), touchEvent_(touchEventInfo), result_(result) {}
1114     ~NativeEmbeadTouchInfo() override = default;
1115 
GetEmbedId()1116     const std::string& GetEmbedId() const
1117     {
1118         return embedId_;
1119     }
1120 
GetTouchEventInfo()1121     const TouchEventInfo& GetTouchEventInfo() const
1122     {
1123         return touchEvent_;
1124     }
GetResult()1125     const RefPtr<GestureEventResult>& GetResult() const
1126     {
1127         return result_;
1128     }
1129 private:
1130     std::string embedId_;
1131     TouchEventInfo touchEvent_;
1132     RefPtr<GestureEventResult> result_;
1133 };
1134 
1135 using TouchEventFunc = std::function<void(TouchEventInfo&)>;
1136 using OnTouchEventCallback = std::function<void(const TouchEventInfo&)>;
1137 using CatchTouchEventCallback = std::function<void()>;
1138 
1139 } // namespace OHOS::Ace
1140 
1141 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H
1142