• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/event/gesture_event_hub.h"
17 
18 #include <cstdint>
19 #include <list>
20 
21 #include "base/log/log_wrapper.h"
22 #include "base/memory/ace_type.h"
23 #include "base/subwindow/subwindow_manager.h"
24 #include "base/utils/time_util.h"
25 #include "base/image/image_source.h"
26 #include "core/common/container.h"
27 #include "core/common/interaction/interaction_data.h"
28 #include "core/common/interaction/interaction_interface.h"
29 #include "core/components/common/layout/grid_system_manager.h"
30 #include "core/components/container_modal/container_modal_constants.h"
31 #include "core/components_ng/base/frame_node.h"
32 #include "core/components_ng/event/click_event.h"
33 #include "core/components_ng/event/event_hub.h"
34 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
35 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
36 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
37 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
38 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
39 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
40 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
41 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
42 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
43 #include "core/gestures/gesture_info.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45 
46 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
47 #include "image_source.h"
48 #endif
49 
50 #include "core/common/udmf/udmf_client.h"
51 #include "core/components_ng/render/adapter/component_snapshot.h"
52 namespace OHOS::Ace::NG {
53 namespace {
54 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
55 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
56 #endif
57 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
58 } // namespace
59 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
60 constexpr const char* HIT_TEST_MODE[] = {
61     "HitTestMode.Default",
62     "HitTestMode.Block",
63     "HitTestMode.Transparent",
64     "HitTestMode.None",
65 };
66 
GestureEventHub(const WeakPtr<EventHub> & eventHub)67 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
68 
GetFrameNode() const69 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
70 {
71     auto eventHub = eventHub_.Upgrade();
72     return eventHub ? eventHub->GetFrameNode() : nullptr;
73 }
74 
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint,const RefPtr<TargetComponent> & targetComponent)75 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
76     TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint,
77     const RefPtr<TargetComponent>& targetComponent)
78 {
79     auto host = GetFrameNode();
80     CHECK_NULL_RETURN(host, false);
81     auto eventHub = eventHub_.Upgrade();
82     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
83     if (scrollableActuator_) {
84         scrollableActuator_->CollectTouchTarget(
85             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, localPoint, host, targetComponent);
86     }
87     size_t idx = innerTargets.size();
88     size_t newIdx = 0;
89     if (touchEventActuator_) {
90         touchEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
91     }
92     if (clickEventActuator_) {
93         clickEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
94     }
95     if (userParallelClickEventActuator_) {
96         auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
97         if (clickRecognizer) {
98             clickRecognizer->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, true));
99             clickRecognizer->SetOnAction(userParallelClickEventActuator_->GetClickEvent());
100             clickRecognizer->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
101             clickRecognizer->SetGetEventTargetImpl(getEventTargetImpl);
102         }
103     }
104     if (panEventActuator_) {
105         panEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
106     }
107 
108     TouchTestResult dragTargets;
109     if (longPressEventActuator_) {
110         longPressEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
111     }
112     if (dragEventActuator_) {
113         dragEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
114     }
115 
116     std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
117     for (const auto& item : dragTargets) {
118         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
119         if (recognizer) {
120             recognizer->BeginReferee(touchId);
121             recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
122             recognizer->SetTargetComponent(targetComponent);
123             if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
124                 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
125                 if (group) {
126                     group->SetChildrenTargetComponent(targetComponent);
127                 }
128             }
129         }
130         longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
131     }
132     if (!longPressRecognizers.empty()) {
133         // this node has long press and drag event, combine into parallelRecognizer.
134         if (!nodeParallelRecognizer_) {
135             nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
136         } else {
137             nodeParallelRecognizer_->AddChildren(longPressRecognizers);
138         }
139         innerTargets.emplace_back(nodeParallelRecognizer_);
140     } else {
141         nodeParallelRecognizer_.Reset();
142     }
143 
144     std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
145     for (auto const& eventTarget : innerTargets) {
146         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
147         if (recognizer) {
148             auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
149             if (!recognizerGroup && newIdx >= idx) {
150                 recognizer->SetNodeId(host->GetId());
151                 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
152                 recognizer->SetTargetComponent(targetComponent);
153                 recognizer->SetIsSystemGesture(true);
154             }
155             recognizer->BeginReferee(touchId);
156             innerRecognizers.push_back(std::move(recognizer));
157         } else {
158             eventTarget->SetNodeId(host->GetId());
159             eventTarget->AttachFrameNode(WeakPtr<FrameNode>(host));
160             eventTarget->SetTargetComponent(targetComponent);
161             finalResult.push_back(eventTarget);
162         }
163         newIdx++; // not process previous recognizers
164     }
165 
166     ProcessTouchTestHierarchy(coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId, targetComponent);
167 
168     return false;
169 }
170 
OnModifyDone()171 void GestureEventHub::OnModifyDone()
172 {
173     if (recreateGesture_) {
174         UpdateGestureHierarchy();
175         recreateGesture_ = false;
176     }
177 }
178 
PackInnerRecognizer(const Offset & offset,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)179 RefPtr<NGGestureRecognizer> GestureEventHub::PackInnerRecognizer(
180     const Offset& offset, std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, int32_t touchId,
181     const RefPtr<TargetComponent>& targetComponent)
182 {
183     RefPtr<NGGestureRecognizer> current;
184     // Pack inner recognizer include self inner recognizer and children.
185     if (innerRecognizers.size() == 1) {
186         current = *innerRecognizers.begin();
187     } else if (innerRecognizers.size() > 1) {
188         if (!innerExclusiveRecognizer_) {
189             innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
190         } else {
191             innerExclusiveRecognizer_->AddChildren(innerRecognizers);
192         }
193         innerExclusiveRecognizer_->SetCoordinateOffset(offset);
194         innerExclusiveRecognizer_->BeginReferee(touchId);
195         auto host = GetFrameNode();
196         innerExclusiveRecognizer_->AttachFrameNode(WeakPtr<FrameNode>(host));
197         innerExclusiveRecognizer_->SetTargetComponent(targetComponent);
198         current = innerExclusiveRecognizer_;
199     }
200 
201     return current;
202 }
203 
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)204 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
205     std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId,
206     const RefPtr<TargetComponent>& targetComponent)
207 {
208     auto host = GetFrameNode();
209     if (!host) {
210         for (auto&& recognizer : innerRecognizers) {
211             finalResult.emplace_back(std::move(recognizer));
212         }
213         return;
214     }
215 
216     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
217     RefPtr<NGGestureRecognizer> current;
218     current = PackInnerRecognizer(offset, innerRecognizers, touchId, targetComponent);
219     auto eventHub = eventHub_.Upgrade();
220     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
221     auto context = host->GetContext();
222     int32_t parallelIndex = 0;
223     int32_t exclusiveIndex = 0;
224     for (auto const& recognizer : gestureHierarchy_) {
225         if (!recognizer) {
226             continue;
227         }
228         auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
229         if (recognizerGroup) {
230             recognizerGroup->SetRecognizerInfoRecursively(offset, host, targetComponent, getEventTargetImpl);
231         }
232 
233         recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
234         recognizer->SetTargetComponent(targetComponent);
235         recognizer->SetCoordinateOffset(offset);
236         recognizer->BeginReferee(touchId, true);
237         recognizer->SetGetEventTargetImpl(getEventTargetImpl);
238         auto gestureMask = recognizer->GetPriorityMask();
239         if (gestureMask == GestureMask::IgnoreInternal) {
240             // In ignore case, dropped the self inner recognizer and children recognizer.
241             current = recognizer;
242             continue;
243         }
244         auto priority = recognizer->GetPriority();
245         std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
246         if (priority == GesturePriority::Parallel) {
247             if (current) {
248                 recognizers.push_front(current);
249             }
250             if (recognizers.size() > 1) {
251                 if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
252                     externalParallelRecognizer_.emplace_back(
253                         AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
254                 } else {
255                     externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
256                 }
257                 externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
258                 externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
259                 externalParallelRecognizer_[parallelIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
260                 externalParallelRecognizer_[parallelIndex]->SetTargetComponent(targetComponent);
261                 current = externalParallelRecognizer_[parallelIndex];
262                 parallelIndex++;
263             } else if (recognizers.size() == 1) {
264                 current = *recognizers.begin();
265             }
266         } else {
267             if (current) {
268                 if (priority == GesturePriority::Low) {
269                     recognizers.push_front(current);
270                 } else {
271                     recognizers.push_back(current);
272                 }
273             }
274 
275             if (recognizers.size() > 1) {
276                 if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
277                     externalExclusiveRecognizer_.emplace_back(
278                         AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
279                 } else {
280                     externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
281                 }
282                 externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
283                 externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
284                 externalExclusiveRecognizer_[exclusiveIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
285                 externalExclusiveRecognizer_[exclusiveIndex]->SetTargetComponent(targetComponent);
286                 current = externalExclusiveRecognizer_[exclusiveIndex];
287                 exclusiveIndex++;
288             } else if (recognizers.size() == 1) {
289                 current = *recognizers.begin();
290             }
291         }
292     }
293 
294     if (current) {
295         finalResult.emplace_back(std::move(current));
296     }
297 }
298 
UpdateGestureHierarchy()299 void GestureEventHub::UpdateGestureHierarchy()
300 {
301     auto host = GetFrameNode();
302     CHECK_NULL_VOID(host);
303     bool success = gestures_.size() == gestureHierarchy_.size();
304     if (success) {
305         auto iter = gestures_.begin();
306         auto recognizerIter = gestureHierarchy_.begin();
307         for (; iter != gestures_.end(); iter++, recognizerIter++) {
308             auto newRecognizer = (*iter)->CreateRecognizer();
309             success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
310             if (!success) {
311                 break;
312             }
313         }
314     }
315 
316     if (success) {
317         gestures_.clear();
318         return;
319     }
320 
321     gestureHierarchy_.clear();
322     for (auto const& gesture : gestures_) {
323         if (!gesture) {
324             continue;
325         }
326         auto recognizer = gesture->CreateRecognizer();
327 
328         auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
329         if (clickRecognizer) {
330             clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
331         }
332 
333         auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
334         if (longPressRecognizer) {
335             longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
336             auto pattern = host->GetPattern();
337             if (pattern && longPressRecognizer->HasAction()) {
338                 longPressRecognizer->SetOnLongPressRecorder(pattern->GetLongPressEventRecorder());
339             }
340         }
341 
342         if (!recognizer) {
343             continue;
344         }
345         auto priority = gesture->GetPriority();
346         auto gestureMask = gesture->GetGestureMask();
347         recognizer->SetPriority(priority);
348         recognizer->SetPriorityMask(gestureMask);
349         gestureHierarchy_.emplace_back(recognizer);
350     }
351     gestures_.clear();
352 }
353 
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)354 void GestureEventHub::CombineIntoExclusiveRecognizer(
355     const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
356 {
357     TouchTestResult finalResult;
358     std::list<RefPtr<NGGestureRecognizer>> recognizers;
359     const auto coordinateOffset = globalPoint - localPoint;
360     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
361     for (auto const& eventTarget : result) {
362         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
363         if (recognizer) {
364             recognizers.push_back(std::move(recognizer));
365         } else {
366             finalResult.push_back(eventTarget);
367         }
368     }
369 
370     RefPtr<NGGestureRecognizer> current;
371     if (recognizers.size() == 1) {
372         current = *recognizers.begin();
373     } else if (recognizers.size() > 1) {
374         if (!nodeExclusiveRecognizer_) {
375             nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
376         } else {
377             nodeExclusiveRecognizer_->AddChildren(recognizers);
378         }
379         nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
380         nodeExclusiveRecognizer_->BeginReferee(touchId);
381         current = nodeExclusiveRecognizer_;
382     }
383 
384     if (current) {
385         finalResult.emplace_back(std::move(current));
386     }
387     result.swap(finalResult);
388 }
389 
IsPixelMapNeedScale() const390 bool GestureEventHub::IsPixelMapNeedScale() const
391 {
392     CHECK_NULL_RETURN(pixelMap_, false);
393     auto frameNode = GetFrameNode();
394     CHECK_NULL_RETURN(frameNode, false);
395     auto width = pixelMap_->GetWidth();
396     auto maxWidth = GridSystemManager::GetInstance().GetMaxWidthWithColumnType(GridColumnType::DRAG_PANEL);
397     if (frameNode->GetTag() == V2::WEB_ETS_TAG ||
398         frameNode->GetDragPreviewOption().mode == DragPreviewMode::DISABLE_SCALE || width == 0 || width < maxWidth) {
399         return false;
400     }
401     return true;
402 }
403 
InitDragDropEvent()404 void GestureEventHub::InitDragDropEvent()
405 {
406     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
407         auto gestureEventHub = weak.Upgrade();
408         CHECK_NULL_VOID(gestureEventHub);
409         gestureEventHub->HandleOnDragStart(info);
410     };
411 
412     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
413         auto gestureEventHub = weak.Upgrade();
414         CHECK_NULL_VOID(gestureEventHub);
415         gestureEventHub->HandleOnDragUpdate(info);
416     };
417 
418     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
419         auto gestureEventHub = weak.Upgrade();
420         CHECK_NULL_VOID(gestureEventHub);
421         gestureEventHub->HandleOnDragEnd(info);
422     };
423 
424     auto actionCancelTask = [weak = WeakClaim(this)]() {
425         auto gestureEventHub = weak.Upgrade();
426         CHECK_NULL_VOID(gestureEventHub);
427         gestureEventHub->HandleOnDragCancel();
428     };
429 
430     auto dragEvent = MakeRefPtr<DragEvent>(
431         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
432     SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
433 }
434 
IsAllowedDrag(RefPtr<EventHub> eventHub)435 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
436 {
437     auto frameNode = GetFrameNode();
438     CHECK_NULL_RETURN(frameNode, false);
439     auto pattern = frameNode->GetPattern();
440     CHECK_NULL_RETURN(pattern, false);
441 
442     if (frameNode->IsDraggable()) {
443         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
444             return false;
445         }
446     } else {
447         if (frameNode->IsUserSet()) {
448             return false;
449         }
450         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
451             return false;
452         }
453     }
454     return true;
455 }
456 
StartLongPressActionForWeb()457 void GestureEventHub::StartLongPressActionForWeb()
458 {
459     auto pipeline = PipelineContext::GetCurrentContext();
460     CHECK_NULL_VOID(pipeline);
461     auto taskScheduler = pipeline->GetTaskExecutor();
462     CHECK_NULL_VOID(taskScheduler);
463 
464     taskScheduler->PostTask(
465         [weak = WeakClaim(this)]() {
466             auto gestureHub = weak.Upgrade();
467             CHECK_NULL_VOID(gestureHub);
468             auto dragEventActuator = gestureHub->dragEventActuator_;
469             CHECK_NULL_VOID(dragEventActuator);
470             dragEventActuator->StartLongPressActionForWeb();
471         },
472         TaskExecutor::TaskType::UI);
473 }
474 
CancelDragForWeb()475 void GestureEventHub::CancelDragForWeb()
476 {
477     auto pipeline = PipelineContext::GetCurrentContext();
478     CHECK_NULL_VOID(pipeline);
479     auto taskScheduler = pipeline->GetTaskExecutor();
480     CHECK_NULL_VOID(taskScheduler);
481 
482     taskScheduler->PostTask(
483         [weak = WeakClaim(this)]() {
484             auto gestureHub = weak.Upgrade();
485             CHECK_NULL_VOID(gestureHub);
486             auto dragEventActuator = gestureHub->dragEventActuator_;
487             CHECK_NULL_VOID(dragEventActuator);
488             dragEventActuator->CancelDragForWeb();
489         },
490         TaskExecutor::TaskType::UI);
491 }
492 
ResetDragActionForWeb()493 void GestureEventHub::ResetDragActionForWeb()
494 {
495     isReceivedDragGestureInfo_ = false;
496     CHECK_NULL_VOID(dragEventActuator_);
497     dragEventActuator_->ResetDragActionForWeb();
498 }
499 
StartDragTaskForWeb()500 void GestureEventHub::StartDragTaskForWeb()
501 {
502     if (!isReceivedDragGestureInfo_) {
503         return;
504     }
505 
506     isReceivedDragGestureInfo_ = false;
507     auto pipeline = PipelineContext::GetCurrentContext();
508     CHECK_NULL_VOID(pipeline);
509     auto taskScheduler = pipeline->GetTaskExecutor();
510     CHECK_NULL_VOID(taskScheduler);
511 
512     taskScheduler->PostTask(
513         [weak = WeakClaim(this)]() {
514             auto gestureHub = weak.Upgrade();
515             CHECK_NULL_VOID(gestureHub);
516             auto dragEventActuator = gestureHub->dragEventActuator_;
517             CHECK_NULL_VOID(dragEventActuator);
518             dragEventActuator->StartDragTaskForWeb(gestureHub->gestureInfoForWeb_);
519         },
520         TaskExecutor::TaskType::UI);
521 }
522 
CreatePixelMapFromString(const std::string & filePath)523 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
524 {
525     auto imageSource = ImageSource::Create(filePath);
526     CHECK_NULL_RETURN(imageSource, nullptr);
527     RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
528     return pixelMap;
529 }
530 
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale,const bool needScale) const531 OffsetF GestureEventHub::GetPixelMapOffset(
532     const GestureEvent& info, const SizeF& size, const float scale, const bool needScale) const
533 {
534     OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
535     auto frameNode = GetFrameNode();
536     CHECK_NULL_RETURN(frameNode, result);
537     auto frameTag = frameNode->GetTag();
538     if (frameTag == V2::WEB_ETS_TAG) {
539         result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
540         result.SetY(size.Height() * PIXELMAP_HEIGHT_RATE);
541     } else if (needScale) {
542         result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
543         result.SetY(PIXELMAP_DRAG_DEFAULT_HEIGHT);
544     } else {
545         auto coordinateX = frameNodeOffset_.GetX() > SystemProperties::GetDevicePhysicalWidth()
546                                ? frameNodeOffset_.GetX() - SystemProperties::GetDevicePhysicalWidth()
547                                : frameNodeOffset_.GetX();
548         auto coordinateY = frameNodeOffset_.GetY();
549         auto differentScale = (NearZero(frameNodeSize_.Width()) || NearZero(size.Width()))
550                                   ? 1.0f
551                                   : frameNodeSize_.Width() * DEFALUT_DRAG_PPIXELMAP_SCALE / size.Width();
552         result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()) / differentScale);
553         result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()) / differentScale);
554     }
555     if (result.GetX() >= 0.0f) {
556         result.SetX(-1.0f);
557     }
558     if (result.GetX() + size.Width() <= 0.0f) {
559         result.SetX(1.0f - size.Width());
560     }
561     if (result.GetY() >= 0.0f) {
562         result.SetY(-1.0f);
563     }
564     if (result.GetY() + size.Height() <= 0.0f) {
565         result.SetY(1.0f - size.Height());
566     }
567     TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.",
568         result.GetX(), result.GetY());
569     return result;
570 }
571 
GetPixelMapScale(const int32_t height,const int32_t width) const572 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
573 {
574     float scale = 1.0f;
575     if (height == 0 || width == 0) {
576         return scale;
577     }
578     auto frameNode = GetFrameNode();
579     CHECK_NULL_RETURN(frameNode, scale);
580     auto pipeline = PipelineContext::GetCurrentContext();
581     CHECK_NULL_RETURN(pipeline, scale);
582     auto dragDropManager = pipeline->GetDragDropManager();
583     CHECK_NULL_RETURN(dragDropManager, scale);
584     auto windowScale = dragDropManager->GetWindowScale();
585     if (frameNode->GetDragPreviewOption().mode == DragPreviewMode::DISABLE_SCALE ||
586         !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
587         return scale * windowScale;
588     }
589     int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
590     int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
591     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
592     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
593     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
594         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
595             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
596         }
597     } else {
598         if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
599             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
600             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
601                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
602         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
603                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
604             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
605                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
606         }
607     }
608     return scale * windowScale;
609 }
610 
GenerateMousePixelMap(const GestureEvent & info)611 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
612 {
613     auto frameNode = GetFrameNode();
614     CHECK_NULL_VOID(frameNode);
615     RefPtr<RenderContext> context;
616     if (GetTextDraggable()) {
617         auto pattern = frameNode->GetPattern<TextDragBase>();
618         CHECK_NULL_VOID(pattern);
619         auto dragNode = pattern->MoveDragNode();
620         CHECK_NULL_VOID(dragNode);
621         auto pipeline = PipelineContext::GetCurrentContext();
622         CHECK_NULL_VOID(pipeline);
623         pipeline->FlushPipelineImmediately();
624         context = dragNode->GetRenderContext();
625     } else {
626         context = frameNode->GetRenderContext();
627     }
628     CHECK_NULL_VOID(context);
629     auto thumbnailPixelMap = context->GetThumbnailPixelMap();
630     CHECK_NULL_VOID(thumbnailPixelMap);
631     SetPixelMap(thumbnailPixelMap);
632 }
633 
HandleNotallowDrag(const GestureEvent & info)634 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
635 {
636     auto frameNode = GetFrameNode();
637     CHECK_NULL_VOID(frameNode);
638     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
639         gestureInfoForWeb_ = info;
640         isReceivedDragGestureInfo_ = true;
641     }
642 }
643 
HandleOnDragStart(const GestureEvent & info)644 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
645 {
646     TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
647     auto eventHub = eventHub_.Upgrade();
648     CHECK_NULL_VOID(eventHub);
649     if (!eventHub->HasOnDragStart()) {
650         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
651         return;
652     }
653 
654     auto frameNode = GetFrameNode();
655     CHECK_NULL_VOID(frameNode);
656     auto pattern = frameNode->GetPattern();
657     CHECK_NULL_VOID(pattern);
658     if (!IsAllowedDrag(eventHub)) {
659         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not allow drag, tag is %{public}s, id is %{public}s,"
660             "draggable is %{public}d, drag start event is %{public}d,"
661             "default support drag is %{public}d, user set is %{public}d.",
662             frameNode->GetTag().c_str(), frameNode->GetInspectorId()->c_str(),
663             frameNode->IsDraggable(), eventHub->HasOnDragStart(),
664             pattern->DefaultSupportDrag(), frameNode->IsUserSet());
665         HandleNotallowDrag(info);
666         return;
667     }
668     auto pipeline = PipelineContext::GetCurrentContext();
669     CHECK_NULL_VOID(pipeline);
670     auto eventManager = pipeline->GetEventManager();
671     CHECK_NULL_VOID(eventManager);
672     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
673         TAG_LOGD(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
674         return;
675     }
676     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
677     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
678         event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
679         event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
680     } else {
681         event->SetX(info.GetGlobalPoint().GetX());
682         event->SetY(info.GetGlobalPoint().GetY());
683     }
684     event->SetScreenX(info.GetScreenLocation().GetX());
685     event->SetScreenY(info.GetScreenLocation().GetY());
686 
687     auto frameTag = frameNode->GetTag();
688     auto hostPattern = frameNode->GetPattern<TextDragBase>();
689     if (hostPattern && GetTextDraggable() && (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
690                         frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG)) {
691         frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
692         frameNodeSize_ = SizeF(0.0f, 0.0f);
693     } else {
694         auto geometryNode = frameNode->GetGeometryNode();
695         if (geometryNode) {
696             frameNodeSize_ = geometryNode->GetFrameSize();
697         } else {
698             frameNodeSize_ = SizeF(0.0f, 0.0f);
699         }
700         auto rectCenter = frameNode->GetPaintRectCenter();
701         frameNodeOffset_ = OffsetF(rectCenter.GetX() - frameNodeSize_.Width() / 2.0f,
702             rectCenter.GetY() - frameNodeSize_.Height() / 2.0f);
703     }
704     /*
705      * Users may remove frameNode in the js callback function "onDragStart "triggered below,
706      * so save the offset of the framenode relative to the window in advance
707      */
708     auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
709     auto dragDropInfo = (eventHub->GetOnDragStart())(event, extraParams);
710     auto dragPreviewInfo = frameNode->GetDragPreview();
711     auto dragDropManager = pipeline->GetDragDropManager();
712     CHECK_NULL_VOID(dragDropManager);
713     dragDropManager->SetDraggingPointer(info.GetPointerId());
714     dragDropManager->SetDraggingPressedState(true);
715     if (info.GetSourceDevice() != SourceType::MOUSE) {
716         if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
717             if (dragPreviewPixelMap_ != nullptr) {
718                 dragDropInfo.pixelMap = dragPreviewPixelMap_;
719                 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
720                 return;
721             }
722         }
723     }
724 
725     if (dragPreviewInfo.pixelMap != nullptr) {
726         dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
727         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
728         return;
729     } else if (dragPreviewInfo.customNode != nullptr) {
730         dragDropInfo.customNode = dragPreviewInfo.customNode;
731     }
732 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
733     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
734         auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this),
735                             frameNode, dragDropInfo, event](
736                             std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>) mutable {
737             ContainerScope scope(id);
738             if (pixelMap != nullptr) {
739                 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
740             }
741             auto taskScheduler = pipeline->GetTaskExecutor();
742             CHECK_NULL_VOID(taskScheduler);
743             taskScheduler->PostTask(
744                 [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event]() {
745                     CHECK_NULL_VOID(gestureEventHubPtr);
746                     CHECK_NULL_VOID(frameNode);
747                     gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
748                 },
749                 TaskExecutor::TaskType::UI);
750         };
751         NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), false, CREATE_PIXELMAP_TIME);
752         return;
753     }
754 #endif
755     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
756 }
757 
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,const DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)758 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
759     const RefPtr<FrameNode> frameNode, const DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
760 {
761     auto eventHub = eventHub_.Upgrade();
762     CHECK_NULL_VOID(eventHub);
763     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
764     CHECK_NULL_VOID(pipeline);
765 
766     auto dragDropManager = pipeline->GetDragDropManager();
767     CHECK_NULL_VOID(dragDropManager);
768     if (dragDropProxy_) {
769         dragDropProxy_ = nullptr;
770     }
771     CHECK_NULL_VOID(dragEvent);
772     auto eventRet = dragEvent->GetResult();
773     if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
774         return;
775     }
776     if (GetTextDraggable() && !GetIsTextDraggable()) {
777         TAG_LOGI(AceLogTag::ACE_DRAG, "Start drag, forbidden drag");
778         return;
779     }
780     std::string udKey;
781     int32_t recordsSize = 1;
782     auto unifiedData = dragEvent->GetData();
783     CHECK_NULL_VOID(frameNode);
784     auto pattern = frameNode->GetPattern();
785     CHECK_NULL_VOID(pattern);
786     pattern->ResetDragOption();
787     if (pattern->GetDragRecordSize() >= 0) {
788         recordsSize = pattern->GetDragRecordSize();
789     } else if (unifiedData) {
790         auto recordSize = unifiedData->GetSize();
791         recordsSize = recordSize > 1 ? recordSize : 1;
792     }
793     auto ret = SetDragData(unifiedData, udKey);
794     if (ret != 0) {
795         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
796     }
797 
798     std::map<std::string, int64_t> summary;
799     ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
800     dragDropManager->SetSummaryMap(summary);
801     RefPtr<PixelMap> pixelMap;
802     if (dragDropInfo.pixelMap != nullptr) {
803         pixelMap = dragDropInfo.pixelMap;
804         SetPixelMap(dragDropInfo.pixelMap);
805     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
806         dragDropManager->SetIsMouseDrag(true);
807         pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
808         CHECK_NULL_VOID(pixelMap);
809         auto taskScheduler = pipeline->GetTaskExecutor();
810         CHECK_NULL_VOID(taskScheduler);
811         GenerateMousePixelMap(info);
812         if (pixelMap_) {
813             pixelMap = pixelMap_;
814         }
815     } else {
816         CHECK_NULL_VOID(pixelMap_);
817         if (pixelMap == nullptr) {
818             pixelMap = pixelMap_;
819         }
820     }
821     float defaultPixelMapScale =
822         info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
823     float scale = GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth()) * defaultPixelMapScale;
824     auto overlayManager = pipeline->GetOverlayManager();
825     if (IsPixelMapNeedScale()) {
826         RefPtr<FrameNode> imageNode = overlayManager->GetPixelMapContentNode();
827         DragEventActuator::CreatePreviewNode(frameNode, imageNode);
828         CHECK_NULL_VOID(imageNode);
829         scale = static_cast<float>(imageNode->GetPreviewScaleVal());
830         auto window = SubwindowManager::GetInstance()->ShowPreviewNG();
831         if (window) {
832             overlayManager = window->GetOverlayManager();
833             CHECK_NULL_VOID(overlayManager);
834             DragEventActuator::MountPixelMap(overlayManager, eventHub->GetGestureEventHub(), imageNode);
835             dragDropManager->DoDragStartAnimation(overlayManager, info);
836             if (pixelMap_ != nullptr) {
837                 pixelMap = pixelMap_;
838             }
839         }
840     }
841     if (!overlayManager->GetIsOnAnimation()) {
842         if (dragEventActuator_ != nullptr) {
843             dragEventActuator_->SetIsNotInPreviewState(true);
844         }
845     }
846     TAG_LOGI(AceLogTag::ACE_DRAG, "Start drag, animation is %{public}d, pixelMap scale is %{public}f",
847         overlayManager->GetIsOnAnimation(), scale);
848     pixelMap->Scale(scale, scale, AceAntiAliasingOption::HIGH);
849     auto width = pixelMap->GetWidth();
850     auto height = pixelMap->GetHeight();
851     auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale, !NearEqual(scale, defaultPixelMapScale));
852     auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
853                                 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
854                                 : dragDropInfo.extraInfo;
855     auto arkExtraInfoJson = JsonUtil::Create(true);
856     auto dipScale = pipeline->GetDipScale();
857     arkExtraInfoJson->Put("dip_scale", dipScale);
858     ShadowInfoCore shadowInfo { pixelMap, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
859     DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
860         static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(), info.GetScreenLocation().GetX(),
861         info.GetScreenLocation().GetY(), info.GetTargetDisplayId(), true, false, summary };
862     ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
863     if (ret != 0) {
864         if (dragDropManager->IsNeedScaleDragPreview()) {
865             SubwindowManager::GetInstance()->HidePreviewNG();
866             overlayManager->RemovePixelMap();
867         }
868         TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
869         return;
870     }
871     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && IsPixelMapNeedScale()) {
872         ret = RegisterCoordinationListener(pipeline);
873         if (ret != 0) {
874             TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
875         }
876     }
877     dragDropManager->UpdateDragStyle();
878     dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
879     dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
880     auto eventManager = pipeline->GetEventManager();
881     CHECK_NULL_VOID(eventManager);
882     eventManager->DoMouseActionRelease();
883     eventManager->SetIsDragging(true);
884     if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
885         dragEventActuator_->GetIsNotInPreviewState()) {
886         if (!dragDropManager->IsNeedScaleDragPreview()) {
887             overlayManager->RemovePixelMap();
888             pipeline->AddAfterRenderTask([]() { InteractionInterface::GetInstance()->SetDragWindowVisible(true); });
889         }
890     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
891         if (!dragDropManager->IsNeedScaleDragPreview()) {
892             pipeline->AddDragWindowVisibleTask([]() {
893                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
894             });
895         }
896         dragDropManager->SetIsDragWindowShow(true);
897     }
898     dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
899     dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
900     CHECK_NULL_VOID(dragDropProxy_);
901     dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
902     if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
903         dragDropManager->OnDragEnd(
904             PointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
905     }
906 }
907 
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)908 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
909 {
910     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
911     CHECK_NULL_RETURN(pipeline, -1);
912     auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
913         ContainerScope scope(id);
914         auto context = weak.Upgrade();
915         CHECK_NULL_VOID(context);
916         auto dragDropManager = context->GetDragDropManager();
917         CHECK_NULL_VOID(dragDropManager);
918         auto taskScheduler = context->GetTaskExecutor();
919         CHECK_NULL_VOID(taskScheduler);
920         taskScheduler->PostTask([dragDropManager]() {
921             dragDropManager->HideDragPreviewOverlay();
922             }, TaskExecutor::TaskType::UI);
923     };
924     return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
925 }
926 
HandleOnDragUpdate(const GestureEvent & info)927 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
928 {
929     gestureInfoForWeb_ = info;
930     CHECK_NULL_VOID(dragDropProxy_);
931     auto pipeline = PipelineContext::GetCurrentContext();
932     CHECK_NULL_VOID(pipeline);
933     auto dragDropManager = pipeline->GetDragDropManager();
934     if (dragDropManager->IsDragged()) {
935         dragDropProxy_->OnDragMove(info);
936     }
937 }
938 
HandleOnDragEnd(const GestureEvent & info)939 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
940 {
941     auto pipeline = NG::PipelineContext::GetCurrentContext();
942     const static int32_t PLATFORM_VERSION_TEN = 10;
943     if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
944         auto eventHub = eventHub_.Upgrade();
945         CHECK_NULL_VOID(eventHub);
946 
947         auto frameNode = GetFrameNode();
948         CHECK_NULL_VOID(frameNode);
949 
950         // Only the onDrop callback of dragged frame node is triggered.
951         // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
952         if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
953             RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
954             if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
955                 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
956                 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
957             } else {
958                 event->SetX(info.GetGlobalPoint().GetX());
959                 event->SetY(info.GetGlobalPoint().GetY());
960             }
961             event->SetScreenX(info.GetScreenLocation().GetX());
962             event->SetScreenY(info.GetScreenLocation().GetY());
963             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
964             eventHub->HandleInternalOnDrop(event, "");
965         }
966     }
967     CHECK_NULL_VOID(dragDropProxy_);
968     dragDropProxy_->DestroyDragWindow();
969     dragDropProxy_ = nullptr;
970 }
971 
HandleOnDragCancel()972 void GestureEventHub::HandleOnDragCancel()
973 {
974     CHECK_NULL_VOID(dragDropProxy_);
975     dragDropProxy_->DestroyDragWindow();
976     dragDropProxy_ = nullptr;
977 }
978 
SetFocusClickEvent(GestureEventFunc && clickEvent)979 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
980 {
981     auto eventHub = eventHub_.Upgrade();
982     CHECK_NULL_VOID(eventHub);
983     auto focusHub = eventHub->GetFocusHub();
984     CHECK_NULL_VOID(focusHub);
985     focusHub->SetOnClickCallback(std::move(clickEvent));
986 }
987 
988 // helper function to ensure clickActuator is initialized
CheckClickActuator()989 void GestureEventHub::CheckClickActuator()
990 {
991     if (!clickEventActuator_) {
992         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
993         clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
994     }
995 
996     if (parallelCombineClick && !userParallelClickEventActuator_) {
997         userParallelClickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
998         userParallelClickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
999     }
1000 }
1001 
SetUserOnClick(GestureEventFunc && clickEvent)1002 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent)
1003 {
1004     CheckClickActuator();
1005     if (parallelCombineClick) {
1006         userParallelClickEventActuator_->SetUserCallback(std::move(clickEvent));
1007         SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1008     } else {
1009         clickEventActuator_->SetUserCallback(std::move(clickEvent));
1010         SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1011     }
1012 }
1013 
SetOnGestureJudgeBegin(GestureJudgeFunc && gestureJudgeFunc)1014 void GestureEventHub::SetOnGestureJudgeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1015 {
1016     gestureJudgeFunc_ = std::move(gestureJudgeFunc);
1017 }
1018 
SetOnGestureJudgeNativeBegin(GestureJudgeFunc && gestureJudgeFunc)1019 void GestureEventHub::SetOnGestureJudgeNativeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1020 {
1021     gestureJudgeNativeFunc_ = std::move(gestureJudgeFunc);
1022 }
1023 
AddClickEvent(const RefPtr<ClickEvent> & clickEvent)1024 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent)
1025 {
1026     CheckClickActuator();
1027     clickEventActuator_->AddClickEvent(clickEvent);
1028 
1029     SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1030 }
1031 
1032 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)1033 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
1034 {
1035     if (showMenu_) {
1036         RemoveClickEvent(showMenu_);
1037     }
1038     showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
1039     AddClickEvent(showMenu_);
1040 }
1041 
GetOnAccessibilityEventFunc()1042 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
1043 {
1044     auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
1045         auto gestureHub = weak.Upgrade();
1046         CHECK_NULL_VOID(gestureHub);
1047         auto node = gestureHub->GetFrameNode();
1048         CHECK_NULL_VOID(node);
1049         node->OnAccessibilityEvent(eventType);
1050     };
1051     return callback;
1052 }
1053 
ActClick(std::shared_ptr<JsonValue> secComphandle)1054 bool GestureEventHub::ActClick(std::shared_ptr<JsonValue> secComphandle)
1055 {
1056     auto host = GetFrameNode();
1057     CHECK_NULL_RETURN(host, false);
1058     GestureEventFunc click;
1059     GestureEvent info;
1060     std::chrono::microseconds microseconds(GetMicroTickCount());
1061     TimeStamp time(microseconds);
1062     info.SetTimeStamp(time);
1063     EventTarget clickEventTarget;
1064     clickEventTarget.id = host->GetId();
1065     clickEventTarget.type = host->GetTag();
1066 #ifdef SECURITY_COMPONENT_ENABLE
1067     info.SetSecCompHandleEvent(secComphandle);
1068 #endif
1069     auto geometryNode = host->GetGeometryNode();
1070     CHECK_NULL_RETURN(geometryNode, false);
1071     auto offset = geometryNode->GetFrameOffset();
1072     auto size = geometryNode->GetFrameSize();
1073     clickEventTarget.area.SetOffset(DimensionOffset(offset));
1074     clickEventTarget.area.SetHeight(Dimension(size.Height()));
1075     clickEventTarget.area.SetWidth(Dimension(size.Width()));
1076     clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1077     info.SetTarget(clickEventTarget);
1078     Offset globalOffset(offset.GetX(), offset.GetY());
1079     info.SetGlobalLocation(globalOffset);
1080     if (clickEventActuator_) {
1081         click = clickEventActuator_->GetClickEvent();
1082         CHECK_NULL_RETURN(click, true);
1083         click(info);
1084         return true;
1085     }
1086     RefPtr<ClickRecognizer> clickRecognizer;
1087     for (auto gestureRecognizer : gestureHierarchy_) {
1088         clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
1089         if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
1090             click = clickRecognizer->GetTapActionFunc();
1091             click(info);
1092             host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
1093             return true;
1094         }
1095     }
1096     return false;
1097 }
1098 
ActLongClick()1099 bool GestureEventHub::ActLongClick()
1100 {
1101     auto host = GetFrameNode();
1102     CHECK_NULL_RETURN(host, false);
1103     GestureEventFunc click;
1104     GestureEvent info;
1105     std::chrono::microseconds microseconds(GetMicroTickCount());
1106     TimeStamp time(microseconds);
1107     info.SetTimeStamp(time);
1108     EventTarget longPressTarget;
1109     longPressTarget.id = host->GetId();
1110     longPressTarget.type = host->GetTag();
1111     auto geometryNode = host->GetGeometryNode();
1112     CHECK_NULL_RETURN(geometryNode, false);
1113     auto offset = geometryNode->GetFrameOffset();
1114     auto size = geometryNode->GetFrameSize();
1115     longPressTarget.area.SetOffset(DimensionOffset(offset));
1116     longPressTarget.area.SetHeight(Dimension(size.Height()));
1117     longPressTarget.area.SetWidth(Dimension(size.Width()));
1118     longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1119     info.SetTarget(longPressTarget);
1120     Offset globalOffset(offset.GetX(), offset.GetY());
1121     info.SetGlobalLocation(globalOffset);
1122     if (longPressEventActuator_) {
1123         click = longPressEventActuator_->GetGestureEventFunc();
1124         CHECK_NULL_RETURN(click, true);
1125         click(info);
1126         return true;
1127     }
1128     RefPtr<LongPressRecognizer> longPressRecognizer;
1129     for (auto gestureRecognizer : gestureHierarchy_) {
1130         longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1131         if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1132             click = longPressRecognizer->GetLongPressActionFunc();
1133             click(info);
1134             host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
1135             return true;
1136         }
1137     }
1138     return false;
1139 }
1140 
GetHitTestModeStr() const1141 std::string GestureEventHub::GetHitTestModeStr() const
1142 {
1143     auto mode = static_cast<int32_t>(hitTestMode_);
1144     if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
1145         return HIT_TEST_MODE[0];
1146     }
1147     return HIT_TEST_MODE[mode];
1148 }
1149 
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)1150 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
1151 {
1152     auto host = node.Upgrade();
1153     CHECK_NULL_RETURN(host, false);
1154     CHECK_NULL_RETURN(clickEventActuator_, false);
1155     auto click = clickEventActuator_->GetClickEvent();
1156     CHECK_NULL_RETURN(click, false);
1157     GestureEvent info;
1158     info.SetSourceDevice(event.sourceType);
1159     info.SetTimeStamp(event.timeStamp);
1160     EventTarget target;
1161     target.id = host->GetId();
1162     target.type = host->GetTag();
1163     auto geometryNode = host->GetGeometryNode();
1164     CHECK_NULL_RETURN(geometryNode, false);
1165     auto offset = geometryNode->GetFrameOffset();
1166     auto size = geometryNode->GetFrameSize();
1167     target.area.SetOffset(DimensionOffset(offset));
1168     target.area.SetHeight(Dimension(size.Height()));
1169     target.area.SetWidth(Dimension(size.Width()));
1170     target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1171     info.SetTarget(target);
1172     click(info);
1173     return true;
1174 }
1175 
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1176 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1177 {
1178     CHECK_NULL_RETURN(unifiedData, -1);
1179     return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1180 }
1181 
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1182 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1183 {
1184     auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1185     auto eventHub = hub.Upgrade();
1186     CHECK_NULL_RETURN(eventHub, ret);
1187     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1188     CHECK_NULL_RETURN(pipeline, ret);
1189     auto taskScheduler = pipeline->GetTaskExecutor();
1190     CHECK_NULL_RETURN(taskScheduler, ret);
1191     auto dragDropManager = pipeline->GetDragDropManager();
1192     CHECK_NULL_RETURN(dragDropManager, ret);
1193     auto eventManager = pipeline->GetEventManager();
1194     RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1195     auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1196                         const DragNotifyMsgCore& notifyMessage) {
1197         ContainerScope scope(id);
1198         taskScheduler->PostTask(
1199             [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage]() {
1200                 dragDropManager->SetDragResult(notifyMessage, dragEvent);
1201                 dragDropManager->SetIsDragged(false);
1202                 dragDropManager->ResetDragging();
1203                 dragDropManager->SetDraggingPointer(-1);
1204                 dragDropManager->SetDraggingPressedState(false);
1205                 dragDropManager->ResetDragPreviewInfo();
1206                 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1207                 if (ret != 0) {
1208                     TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1209                 }
1210                 if (eventManager) {
1211                     eventManager->DoMouseActionRelease();
1212                 }
1213                 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1214                 if (eventHub->HasOnDragEnd()) {
1215                     (eventHub->GetOnDragEnd())(dragEvent);
1216                 }
1217             },
1218             TaskExecutor::TaskType::UI);
1219     };
1220     return callback;
1221 }
1222 
IsAccessibilityClickable()1223 bool GestureEventHub::IsAccessibilityClickable()
1224 {
1225     bool ret = IsClickable();
1226     RefPtr<ClickRecognizer> clickRecognizer;
1227     for (auto gestureRecognizer : gestureHierarchy_) {
1228         clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
1229         if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
1230             return true;
1231         }
1232     }
1233     return ret;
1234 }
1235 
IsAccessibilityLongClickable()1236 bool GestureEventHub::IsAccessibilityLongClickable()
1237 {
1238     bool ret = IsLongClickable();
1239     RefPtr<LongPressRecognizer> longPressRecognizer;
1240     for (auto gestureRecognizer : gestureHierarchy_) {
1241         longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1242         if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1243             return true;
1244         }
1245     }
1246     return ret;
1247 }
1248 
GetMonopolizeEvents() const1249 bool GestureEventHub::GetMonopolizeEvents() const
1250 {
1251     return monopolizeEvents_;
1252 }
1253 
SetMonopolizeEvents(bool monopolizeEvents)1254 void GestureEventHub::SetMonopolizeEvents(bool monopolizeEvents)
1255 {
1256     monopolizeEvents_ = monopolizeEvents;
1257 }
1258 
ClearUserOnClick()1259 void GestureEventHub::ClearUserOnClick()
1260 {
1261     if (clickEventActuator_) {
1262         clickEventActuator_->ClearUserCallback();
1263     }
1264 }
1265 
ClearUserOnTouch()1266 void GestureEventHub::ClearUserOnTouch()
1267 {
1268     if (touchEventActuator_) {
1269         touchEventActuator_->ClearUserCallback();
1270     }
1271 }
1272 
CopyGestures(const RefPtr<GestureEventHub> & gestureEventHub)1273 void GestureEventHub::CopyGestures(const RefPtr<GestureEventHub>& gestureEventHub)
1274 {
1275     CHECK_NULL_VOID(gestureEventHub);
1276     gestures_ = gestureEventHub->backupGestures_;
1277     recreateGesture_ = true;
1278 }
1279 
CopyEvent(const RefPtr<GestureEventHub> & gestureEventHub)1280 void GestureEventHub::CopyEvent(const RefPtr<GestureEventHub>& gestureEventHub)
1281 {
1282     CHECK_NULL_VOID(gestureEventHub);
1283     auto originalTouchEventActuator = gestureEventHub->touchEventActuator_;
1284     if (originalTouchEventActuator) {
1285         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1286         touchEventActuator_->CopyTouchEvent(originalTouchEventActuator);
1287     }
1288 
1289     auto originalClickEventActuator = gestureEventHub->clickEventActuator_;
1290     if (originalClickEventActuator) {
1291         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1292         clickEventActuator_->CopyClickEvent(originalClickEventActuator);
1293     }
1294 
1295     auto originalLongPressEventActuator = gestureEventHub->longPressEventActuator_;
1296     if (originalLongPressEventActuator) {
1297         longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
1298         longPressEventActuator_->CopyLongPressEvent(originalLongPressEventActuator);
1299     }
1300 
1301     auto originalDragEventActuator = gestureEventHub->dragEventActuator_;
1302     if (originalDragEventActuator) {
1303         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), originalDragEventActuator->GetDirection(),
1304             originalDragEventActuator->GetFingers(), originalDragEventActuator->GetDistance());
1305         dragEventActuator_->CopyDragEvent(originalDragEventActuator);
1306     }
1307     auto originalShowMenu = gestureEventHub->showMenu_;
1308     if (originalShowMenu) {
1309         if (showMenu_) {
1310             RemoveClickEvent(showMenu_);
1311         }
1312         auto originalGetGestureEventFunc = originalShowMenu->GetGestureEventFunc();
1313         showMenu_= MakeRefPtr<ClickEvent>(std::move(originalGetGestureEventFunc));
1314         AddClickEvent(showMenu_);
1315     }
1316 }
1317 } // namespace OHOS::Ace::NG
1318