• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "base/image/image_source.h"
17 #include "base/log/ace_trace.h"
18 #include "base/log/log_wrapper.h"
19 #include "base/memory/ace_type.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "core/common/container.h"
22 #include "core/common/interaction/interaction_data.h"
23 #include "core/common/interaction/interaction_interface.h"
24 #include "core/components/container_modal/container_modal_constants.h"
25 #include "core/components_ng/event/gesture_event_hub.h"
26 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
27 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
28 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
29 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
30 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
31 #include "core/components_ng/pattern/image/image_pattern.h"
32 #include "core/components_ng/pattern/relative_container/relative_container_pattern.h"
33 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
34 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
35 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
36 #include "core/common/vibrator/vibrator_utils.h"
37 
38 #if defined(PIXEL_MAP_SUPPORTED)
39 #include "image_source.h"
40 #endif
41 
42 #include "core/common/udmf/udmf_client.h"
43 #include "core/components_ng/render/adapter/component_snapshot.h"
44 #ifdef WEB_SUPPORTED
45 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
46 #include "core/components_ng/pattern/web/web_pattern.h"
47 #else
48 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
49 #endif
50 #endif
51 namespace OHOS::Ace::NG {
52 namespace {
53 #if defined(PIXEL_MAP_SUPPORTED)
54 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
55 constexpr int32_t MAX_BUILDER_DEPTH = 5;
56 #endif
57 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
58 constexpr int32_t DEFAULT_DRAG_DROP_STATUS = 0;
59 constexpr int32_t NEW_DRAG_DROP_STATUS = 1;
60 constexpr int32_t OLD_DRAG_DROP_STATUS = 3;
61 const std::unordered_set<std::string> OLD_FRAMEWORK_TAG = {
62     V2::WEB_ETS_TAG,
63     V2::TEXTAREA_ETS_TAG,
64     V2::TEXT_ETS_TAG,
65     V2::TEXTINPUT_ETS_TAG,
66     V2::SEARCH_Field_ETS_TAG,
67     V2::RICH_EDITOR_ETS_TAG,
68 };
69 const std::unordered_set<std::string> VALID_TAG = {
70     V2::WEB_ETS_TAG,
71 };
72 constexpr int32_t HALF_PIXELMAP = 2;
73 } // namespace
74 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
75 
IsPixelMapNeedScale() const76 bool GestureEventHub::IsPixelMapNeedScale() const
77 {
78     auto frameNode = GetFrameNode();
79     CHECK_NULL_RETURN(frameNode, false);
80     auto scale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
81     return scale != 1.0f;
82 }
83 
IsDragNewFwk() const84 bool GestureEventHub::IsDragNewFwk() const
85 {
86     return isDragNewFwk_;
87 }
88 
CheckNeedDragDropFrameworkStatus(const std::string & tag)89 bool CheckNeedDragDropFrameworkStatus(const std::string& tag)
90 {
91     auto dragDropFrameworkStatus = SystemProperties::GetDragDropFrameworkStatus();
92     if (dragDropFrameworkStatus == DEFAULT_DRAG_DROP_STATUS &&
93         (OLD_FRAMEWORK_TAG.find(tag) != OLD_FRAMEWORK_TAG.end())) {
94         return false;
95     } else if ((dragDropFrameworkStatus == NEW_DRAG_DROP_STATUS) && (VALID_TAG.find(tag) != VALID_TAG.end())) {
96         return false;
97     } else if (dragDropFrameworkStatus == OLD_DRAG_DROP_STATUS) {
98         return false;
99     }
100     return true;
101 }
102 
InitDragDropEvent()103 void GestureEventHub::InitDragDropEvent()
104 {
105     auto frameNode = GetFrameNode();
106     if (frameNode && CheckNeedDragDropFrameworkStatus(frameNode->GetTag())) {
107         SetDragDropEvent();
108         return;
109     }
110     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
111         auto gestureEventHub = weak.Upgrade();
112         CHECK_NULL_VOID(gestureEventHub);
113         gestureEventHub->HandleOnDragStart(info);
114     };
115 
116     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
117         auto gestureEventHub = weak.Upgrade();
118         CHECK_NULL_VOID(gestureEventHub);
119         gestureEventHub->HandleOnDragUpdate(info);
120     };
121 
122     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
123         auto gestureEventHub = weak.Upgrade();
124         CHECK_NULL_VOID(gestureEventHub);
125         gestureEventHub->HandleOnDragEnd(info);
126     };
127 
128     auto actionCancelTask = [weak = WeakClaim(this)]() {
129         auto gestureEventHub = weak.Upgrade();
130         CHECK_NULL_VOID(gestureEventHub);
131         gestureEventHub->HandleOnDragCancel();
132     };
133     auto dragEvent = MakeRefPtr<DragEvent>(
134         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
135     auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
136     SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
137     CHECK_NULL_VOID(dragEventActuator_);
138     dragEventActuator_->SetIsForDragDrop(false);
139 }
140 
IsAllowedDrag(RefPtr<EventHub> eventHub)141 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
142 {
143     auto frameNode = GetFrameNode();
144     CHECK_NULL_RETURN(frameNode, false);
145     auto pattern = frameNode->GetPattern();
146     CHECK_NULL_RETURN(pattern, false);
147 
148     if (frameNode->IsDraggable()) {
149         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
150             return false;
151         }
152     } else {
153         if (frameNode->IsUserSet()) {
154             return false;
155         }
156         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
157             return false;
158         }
159     }
160     return true;
161 }
162 
StartLongPressActionForWeb()163 void GestureEventHub::StartLongPressActionForWeb()
164 {
165     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
166     auto pipeline = PipelineContext::GetCurrentContext();
167     CHECK_NULL_VOID(pipeline);
168     auto taskScheduler = pipeline->GetTaskExecutor();
169     CHECK_NULL_VOID(taskScheduler);
170 
171     taskScheduler->PostTask(
172         [weak = WeakClaim(this)]() {
173             auto gestureHub = weak.Upgrade();
174             CHECK_NULL_VOID(gestureHub);
175             auto dragEventActuator = gestureHub->dragEventActuator_;
176             CHECK_NULL_VOID(dragEventActuator);
177             dragEventActuator->StartLongPressActionForWeb();
178         },
179         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
180 }
181 
CancelDragForWeb()182 void GestureEventHub::CancelDragForWeb()
183 {
184     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
185     auto pipeline = PipelineContext::GetCurrentContext();
186     CHECK_NULL_VOID(pipeline);
187     auto taskScheduler = pipeline->GetTaskExecutor();
188     CHECK_NULL_VOID(taskScheduler);
189 
190     taskScheduler->PostTask(
191         [weak = WeakClaim(this)]() {
192             auto gestureHub = weak.Upgrade();
193             CHECK_NULL_VOID(gestureHub);
194             auto dragEventActuator = gestureHub->dragEventActuator_;
195             CHECK_NULL_VOID(dragEventActuator);
196             dragEventActuator->CancelDragForWeb();
197         },
198         TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
199 }
200 
ResetDragActionForWeb()201 void GestureEventHub::ResetDragActionForWeb()
202 {
203     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
204     isReceivedDragGestureInfo_ = false;
205     CHECK_NULL_VOID(dragEventActuator_);
206     dragEventActuator_->ResetDragActionForWeb();
207 
208     // fix drag failed when long press drag after 500ms and before 800ms
209     // need to reset the state of the drag manager
210     auto pipeLine = PipelineContext::GetCurrentContext();
211     CHECK_NULL_VOID(pipeLine);
212     auto dragDropManager = pipeLine->GetDragDropManager();
213     CHECK_NULL_VOID(dragDropManager);
214     dragDropManager->ResetDragging();
215 }
216 
StartDragTaskForWeb()217 bool GestureEventHub::StartDragTaskForWeb()
218 {
219     if (!isReceivedDragGestureInfo_) {
220         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
221                                      "because not recv gesture info");
222         return false;
223     }
224 
225     isReceivedDragGestureInfo_ = false;
226     auto pipeline = PipelineContext::GetCurrentContext();
227     CHECK_NULL_RETURN(pipeline, false);
228     auto taskScheduler = pipeline->GetTaskExecutor();
229     CHECK_NULL_RETURN(taskScheduler, false);
230 
231     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
232     taskScheduler->PostTask(
233         [weak = WeakClaim(this)]() {
234             auto gestureHub = weak.Upgrade();
235             CHECK_NULL_VOID(gestureHub);
236             auto dragEventActuator = gestureHub->dragEventActuator_;
237             CHECK_NULL_VOID(dragEventActuator);
238             CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
239             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
240             dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
241         },
242         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
243     return true;
244 }
245 
CreatePixelMapFromString(const std::string & filePath)246 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
247 {
248     auto imageSource = ImageSource::Create(filePath);
249     CHECK_NULL_RETURN(imageSource, nullptr);
250     RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
251     return pixelMap;
252 }
253 
CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode,bool isMenuShow)254 void GestureEventHub::CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode, bool isMenuShow)
255 {
256     CHECK_NULL_VOID(frameNode);
257     auto frameTag = frameNode->GetTag();
258     auto hostPattern = frameNode->GetPattern<TextDragBase>();
259     if (hostPattern && GetTextDraggable() &&
260         (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG || frameTag == V2::TEXTINPUT_ETS_TAG ||
261             frameTag == V2::SEARCH_Field_ETS_TAG)) {
262         frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
263         frameNodeSize_ = SizeF(0.0f, 0.0f);
264     } else {
265         auto rect = DragDropFuncWrapper::GetPaintRectToScreen(frameNode) -
266             DragDropFuncWrapper::GetCurrentWindowOffset(PipelineContext::GetCurrentContextSafelyWithCheck());
267         frameNodeOffset_ = rect.GetOffset();
268         frameNodeSize_ = rect.GetSize();
269 #ifdef WEB_SUPPORTED
270         if (frameTag == V2::WEB_ETS_TAG) {
271             auto webPattern = frameNode->GetPattern<WebPattern>();
272             if (webPattern) {
273                 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
274                 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
275                 frameNodeSize_ = webPattern->GetDragPixelMapSize();
276             }
277         }
278 #endif
279     }
280 
281     // use menuPreview's size and offset for drag framework.
282     if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
283         auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
284         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
285             frameNodeOffset_ = menuPreviewRect.GetOffset();
286             frameNodeSize_ = menuPreviewRect.GetSize();
287         }
288     }
289 }
290 
GetDefaultPixelMapScale(const RefPtr<FrameNode> & frameNode,const GestureEvent & info,bool isMenuShow,RefPtr<PixelMap> pixelMap)291 float GestureEventHub::GetDefaultPixelMapScale(
292     const RefPtr<FrameNode>& frameNode, const GestureEvent& info, bool isMenuShow, RefPtr<PixelMap> pixelMap)
293 {
294     float defaultPixelMapScale =
295         info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
296     CHECK_NULL_RETURN(pixelMap, defaultPixelMapScale);
297     // use menuPreviewScale for drag framework. this is not final solution.
298     if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
299         auto menuPreviewRectWidth = frameNodeSize_.Width();
300         int32_t originPixelMapWidth = pixelMap->GetWidth();
301         if (GreatNotEqual(menuPreviewRectWidth, 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
302             menuPreviewRectWidth < originPixelMapWidth * menuPreviewScale_) {
303             defaultPixelMapScale = menuPreviewRectWidth / originPixelMapWidth;
304         } else {
305             defaultPixelMapScale = menuPreviewScale_;
306         }
307     }
308     return defaultPixelMapScale;
309 }
310 
CheckInSceneBoardWindow()311 bool CheckInSceneBoardWindow()
312 {
313     auto container = Container::Current();
314     CHECK_NULL_RETURN(container, false);
315     if (!container->IsSubContainer()) {
316         return container->IsScenceBoardWindow();
317     }
318     auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
319     container = Container::GetContainer(parentContainerId);
320     CHECK_NULL_RETURN(container, false);
321     return container->IsScenceBoardWindow();
322 }
323 
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)324 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
325 {
326     if (result.GetX() >= 0.0f) {
327         result.SetX(-1.0f);
328     }
329     if (result.GetX() + size.Width() <= 0.0f) {
330         result.SetX(1.0f - size.Width());
331     }
332     if (result.GetY() >= 0.0f) {
333         result.SetY(-1.0f);
334     }
335     if (result.GetY() + size.Height() <= 0.0f) {
336         result.SetY(1.0f - size.Height());
337     }
338 }
339 
ParseInnerRect(const std::string & extraInfo,const SizeF & size)340 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
341 {
342     auto innerRect = RectF();
343     if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
344         return innerRect;
345     }
346     auto extraJson = JsonUtil::ParseJsonString(extraInfo);
347     CHECK_NULL_RETURN(extraJson, innerRect);
348     auto extraOffsetX = extraJson->GetInt("drag_offset_x");
349     auto extraOffsetY = extraJson->GetInt("drag_offset_y");
350     if (extraOffsetX <= 0 || extraOffsetY <= 0) {
351         return innerRect;
352     }
353     innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
354         Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
355     innerRect.SetSize(size);
356     return innerRect;
357 }
358 
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const PreparedInfoForDrag & dragInfoData,const float scale,const RectF & innerRect) const359 OffsetF GestureEventHub::GetPixelMapOffset(const GestureEvent& info, const SizeF& size,
360     const PreparedInfoForDrag& dragInfoData, const float scale, const RectF& innerRect) const
361 {
362     OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
363     auto frameNode = GetFrameNode();
364     CHECK_NULL_RETURN(frameNode, result);
365     auto frameTag = frameNode->GetTag();
366     auto coordinateX = frameNodeOffset_.GetX();
367     auto coordinateY = frameNodeOffset_.GetY();
368     if (!innerRect.IsEmpty() && !NearZero(size.Width()) && !NearZero(size.Height())) {
369         auto rateX = innerRect.Width() / size.Width();
370         auto rateY = innerRect.Height() / size.Height();
371         result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
372         result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
373         CheckOffsetInPixelMap(result, size);
374         return result;
375     }
376     if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
377         NearZero(size.Width()) || NearZero(size.Height())) {
378         result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
379         result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
380     } else {
381         if (dragInfoData.isNeedCreateTiled) {
382             result.SetX(-size.Width() / HALF_PIXELMAP);
383             result.SetY(-size.Height() / HALF_PIXELMAP);
384         } else if (frameNode->GetDragPreviewOption().isTouchPointCalculationBasedOnFinalPreviewEnable) {
385             auto centerX = coordinateX + frameNodeSize_.Width() / HALF_PIXELMAP;
386             auto centerY = coordinateY + frameNodeSize_.Height() / HALF_PIXELMAP;
387             coordinateX = centerX - dragInfoData.dragPreviewRect.Width() / HALF_PIXELMAP;
388             coordinateY = centerY - dragInfoData.dragPreviewRect.Height() / HALF_PIXELMAP;
389             auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / dragInfoData.dragPreviewRect.Width();
390             auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / dragInfoData.dragPreviewRect.Height();
391             result.SetX(-rateX * size.Width());
392             result.SetY(-rateY * size.Height());
393         } else {
394             auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
395             auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
396             result.SetX(-rateX * size.Width());
397             result.SetY(-rateY * size.Height());
398         }
399     }
400     CheckOffsetInPixelMap(result, size);
401     TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.", result.GetX(), result.GetY());
402     return result;
403 }
404 
ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode,float & scale,float previewScale,float windowScale,float defaultMenuPreviewScale)405 void GestureEventHub::ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode, float& scale, float previewScale,
406     float windowScale, float defaultMenuPreviewScale)
407 {
408     auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
409     CHECK_NULL_VOID(imageGestureEventHub);
410     if (!IsPixelMapNeedScale()) {
411         if (CheckInSceneBoardWindow()) {
412             imageGestureEventHub->SetMenuPreviewScale(defaultMenuPreviewScale);
413         } else {
414             //if not in sceneboard,use default drag scale
415             scale = previewScale * windowScale;
416             imageGestureEventHub->SetMenuPreviewScale(previewScale);
417         }
418     } else {
419         imageGestureEventHub->SetMenuPreviewScale(scale);
420     }
421 }
422 
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)423 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
424 {
425     ACE_SCOPED_TRACE("drag: get scaled pixmal, %f", targetScale);
426     float preScale = 1.0f;
427     CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
428     auto frameNode = GetFrameNode();
429     RefPtr<PixelMap> preScaledPixelMap;
430     if (!(frameNode && frameNode->GetDragPreview().onlyForLifting)) {
431         preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
432     }
433     if (preScale == targetScale && preScaledPixelMap != nullptr) {
434         return preScaledPixelMap;
435     }
436 #if defined(PIXEL_MAP_SUPPORTED)
437     preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
438     if (!preScaledPixelMap) {
439         TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
440         preScaledPixelMap = defaultPixelMap;
441     }
442     if (!NearEqual(targetScale, 1.0f)) {
443         preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
444     }
445 #else
446     preScaledPixelMap = defaultPixelMap;
447 #endif
448     return preScaledPixelMap;
449 }
450 
GetPixelMapScale(const int32_t height,const int32_t width) const451 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
452 {
453     float scale = 1.0f;
454     if (height == 0 || width == 0) {
455         return scale;
456     }
457     auto frameNode = GetFrameNode();
458     CHECK_NULL_RETURN(frameNode, scale);
459     auto pipeline = frameNode->GetContextRefPtr();
460     CHECK_NULL_RETURN(pipeline, scale);
461     auto dragDropManager = pipeline->GetDragDropManager();
462     CHECK_NULL_RETURN(dragDropManager, scale);
463     auto windowScale = dragDropManager->GetWindowScale();
464     if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
465         return scale * windowScale;
466     }
467     int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
468     int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
469     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
470     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
471     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
472         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
473             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
474         }
475     } else {
476         if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
477             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
478             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
479                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
480         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
481                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
482             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
483                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
484         }
485     }
486     return scale * windowScale;
487 }
488 
GenerateMousePixelMap(const GestureEvent & info)489 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
490 {
491     auto frameNode = GetFrameNode();
492     CHECK_NULL_VOID(frameNode);
493     RefPtr<RenderContext> context;
494     if (GetTextDraggable()) {
495         auto pattern = frameNode->GetPattern<TextDragBase>();
496         CHECK_NULL_VOID(pattern);
497         auto dragNode = pattern->MoveDragNode();
498         CHECK_NULL_VOID(dragNode);
499         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
500         CHECK_NULL_VOID(pipeline);
501         pipeline->FlushPipelineImmediately();
502         context = dragNode->GetRenderContext();
503     } else {
504         context = frameNode->GetRenderContext();
505     }
506     CHECK_NULL_VOID(context);
507     auto thumbnailPixelMap = context->GetThumbnailPixelMap(false, GetTextDraggable());
508     CHECK_NULL_VOID(thumbnailPixelMap);
509     SetPixelMap(thumbnailPixelMap);
510 }
511 
HandleNotAllowDrag(const GestureEvent & info)512 void GestureEventHub::HandleNotAllowDrag(const GestureEvent& info)
513 {
514     auto frameNode = GetFrameNode();
515     CHECK_NULL_VOID(frameNode);
516     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
517         gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
518         isReceivedDragGestureInfo_ = true;
519         TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
520     }
521 }
522 
HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)523 void GestureEventHub::HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)
524 {
525     CHECK_NULL_VOID(frameNode);
526     dragframeNodeInfo_.frameNode = frameNode;
527     auto pipeline = frameNode->GetContextRefPtr();
528     CHECK_NULL_VOID(pipeline);
529     auto dragDropManager = pipeline->GetDragDropManager();
530     CHECK_NULL_VOID(dragDropManager);
531     auto grayedState = dragDropManager->GetGrayedState();
532     if (grayedState) {
533         return;
534     }
535     auto overlayManager = pipeline->GetOverlayManager();
536     CHECK_NULL_VOID(overlayManager);
537     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
538     if (!gatherNodeChildrenInfo.empty()) {
539         for (const auto& itemFrameNode : gatherNodeChildrenInfo) {
540             auto node = itemFrameNode.preImageNode.Upgrade();
541             CHECK_NULL_VOID(node);
542             dragframeNodeInfo_.gatherFrameNode.push_back(node);
543             DragAnimationHelper::DoDragStartGrayedAnimation(node);
544         }
545         dragframeNodeInfo_.gatherFrameNode.push_back(frameNode);
546     }
547     DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
548     dragDropManager->SetGrayedState(true);
549 }
550 
HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)551 void GestureEventHub::HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)
552 {
553     CHECK_NULL_VOID(frameNode);
554     dragframeNodeInfo_.frameNode = frameNode;
555     auto pipeline = frameNode->GetContextRefPtr();
556     CHECK_NULL_VOID(pipeline);
557     auto dragDropManager = pipeline->GetDragDropManager();
558     CHECK_NULL_VOID(dragDropManager);
559     auto grayedState = dragDropManager->GetGrayedState();
560     if (grayedState) {
561         return;
562     }
563     auto size = GetSelectItemSize();
564     if (size) {
565         auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
566         CHECK_NULL_VOID(fatherNode);
567         auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
568         CHECK_NULL_VOID(scrollPattern);
569         auto children = scrollPattern->GetVisibleSelectedItems();
570         dragframeNodeInfo_.gatherFrameNode = children;
571         for (const auto& itemFrameNode : children) {
572             DragAnimationHelper::DoDragStartGrayedAnimation(itemFrameNode);
573         }
574     } else {
575         DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
576     }
577     dragDropManager->SetGrayedState(true);
578 }
579 
IsNeedSwitchToSubWindow(const PreparedInfoForDrag & dragInfoData) const580 bool GestureEventHub::IsNeedSwitchToSubWindow(const PreparedInfoForDrag& dragInfoData) const
581 {
582     auto frameNode = GetFrameNode();
583     CHECK_NULL_RETURN(frameNode, false);
584     auto focusHub = frameNode->GetFocusHub();
585     CHECK_NULL_RETURN(focusHub, false);
586     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
587     CHECK_NULL_RETURN(pipeline, false);
588     auto dragDropManager = pipeline->GetDragDropManager();
589     CHECK_NULL_RETURN(dragDropManager, false);
590     if (dragInfoData.isMenuShow) {
591         return true;
592     }
593     if (dragInfoData.isNeedCreateTiled) {
594         return false;
595     }
596     if (IsPixelMapNeedScale() || DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr) {
597         return true;
598     }
599     CHECK_NULL_RETURN(dragEventActuator_, false);
600     return dragEventActuator_->IsNeedGather();
601 }
602 
HandleOnDragStart(const GestureEvent & info)603 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
604 {
605     TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
606     auto frameNode = GetFrameNode();
607     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
608     if (!frameNode || !pipeline || !CheckAllowDrag(info, pipeline, frameNode)) {
609         TAG_LOGE(AceLogTag::ACE_DRAG, "Check not allow drag");
610         HandleNotAllowDrag(info);
611         return;
612     }
613 
614     // set menu window touchable
615     auto mainPipeline = PipelineContext::GetMainPipelineContext();
616     DragDropFuncWrapper::SetMenuSubWindowTouchable((mainPipeline != pipeline));
617     // set drag drop status is moving
618     DragDropGlobalController::GetInstance().UpdateDragDropInitiatingStatus(frameNode, DragDropInitiatingStatus::MOVING);
619 
620     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
621         SetMouseDragMonitorState(true);
622     }
623 
624     CalcFrameNodeOffsetAndSize(frameNode, DragDropGlobalController::GetInstance().IsMenuShowing());
625 
626     // create drag event
627     auto event = CreateDragEvent(info, pipeline, frameNode);
628 
629     /*
630      * Users may remove frameNode in the js callback function "onDragStart "triggered below,
631      * so save the offset of the framenode relative to the window in advance
632      */
633     DragDropInfo dragPreviewInfo;
634     auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
635     auto continueFunc = [id = Container::CurrentId(), weak = WeakClaim(this), dragPreviewInfo, info, event,
636         dragDropInfo, frameNode, pipeline]() {
637         ContainerScope scope(id);
638         auto gestureEventHub = weak.Upgrade();
639         CHECK_NULL_VOID(gestureEventHub);
640         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
641             gestureEventHub->SetMouseDragMonitorState(true);
642         }
643         gestureEventHub->DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
644     };
645     auto dragDropManager = pipeline->GetDragDropManager();
646     CHECK_NULL_VOID(dragDropManager);
647     if (DragDropGlobalController::GetInstance().GetDragStartRequestStatus() == DragStartRequestStatus::READY) {
648         DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
649     } else {
650         dragDropManager->SetDelayDragCallBack(continueFunc);
651         TAG_LOGI(AceLogTag::ACE_DRAG, "drag start pended");
652     }
653 }
654 
ParsePixelMapAsync(DragDropInfo & dragDropInfo,const DragDropInfo & dragPreviewInfo,const GestureEvent & info)655 bool GestureEventHub::ParsePixelMapAsync(DragDropInfo& dragDropInfo, const DragDropInfo& dragPreviewInfo,
656     const GestureEvent& info)
657 {
658     auto frameNode = GetFrameNode();
659     CHECK_NULL_RETURN(frameNode, false);
660     if (DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice())) {
661         ACE_SCOPED_TRACE("drag: create titled pixelMap");
662         dragDropInfo.pixelMap = DragDropFuncWrapper::CreateTiledPixelMap(frameNode);
663         return true;
664     }
665 
666     if (dragPreviewInfo.inspectorId != "") {
667         ACE_SCOPED_TRACE("drag: handling with inspector");
668         auto dragPreviewPixelMap = GetDragPreviewPixelMap();
669         TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
670         if (dragPreviewPixelMap == nullptr) {
671             dragPreviewPixelMap = DragDropFuncWrapper::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
672         }
673         dragDropInfo.pixelMap = dragPreviewPixelMap;
674         return true;
675     }
676 
677     if (info.GetSourceDevice() != SourceType::MOUSE) {
678         if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
679             if (dragPreviewPixelMap_ != nullptr) {
680                 ACE_SCOPED_TRACE("drag: handling with drag preview");
681                 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
682                 dragDropInfo.pixelMap = dragPreviewPixelMap_;
683                 return true;
684             }
685         }
686         if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode == nullptr &&
687             dragPreviewInfo.pixelMap == nullptr && dragPreviewInfo.customNode == nullptr && pixelMap_ != nullptr &&
688             !frameNode->GetDragPreview().onlyForLifting) {
689             dragDropInfo.pixelMap = pixelMap_;
690             return true;
691         }
692     }
693 
694     if (dragPreviewInfo.pixelMap != nullptr) {
695         ACE_SCOPED_TRACE("drag: handling with pixelmap directly");
696         dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
697         TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
698         return true;
699     } else if (dragPreviewInfo.customNode != nullptr) {
700         dragDropInfo.customNode = dragPreviewInfo.customNode;
701     }
702     return dragDropInfo.pixelMap;
703 }
704 
DoOnDragStartHandling(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event,DragDropInfo dragPreviewInfo,const RefPtr<PipelineContext> & pipeline)705 void GestureEventHub::DoOnDragStartHandling(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
706     DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event, DragDropInfo dragPreviewInfo,
707     const RefPtr<PipelineContext>& pipeline)
708 {
709     GetUnifiedData(frameNode->GetTag(), dragDropInfo, event);
710     // set drag pointer status
711     auto dragDropManager = pipeline->GetDragDropManager();
712     CHECK_NULL_VOID(dragDropManager);
713     dragDropManager->SetDraggingPointer(info.GetPointerId());
714     dragDropManager->SetDraggingPressedState(true);
715 
716     if (ParsePixelMapAsync(dragDropInfo, dragPreviewInfo, info)) {
717         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
718         return;
719     }
720 
721 #if defined(PIXEL_MAP_SUPPORTED)
722     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
723         ACE_SCOPED_TRACE("drag: handling for custom builder");
724         StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
725         return;
726     }
727 #endif
728     TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
729     ACE_SCOPED_TRACE("drag: handling without preview");
730     if (!dragDropInfo.pixelMap) {
731         if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && GetTextDraggable() && pixelMap_) {
732             dragDropInfo.pixelMap = pixelMap_;
733         } else {
734             GenerateMousePixelMap(info);
735             dragDropInfo.pixelMap = pixelMap_;
736         }
737     }
738     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && !dragDropInfo.pixelMap) {
739         TAG_LOGD(AceLogTag::ACE_DRAG, "no any pixmap got, get node snapshot final try");
740         ACE_SCOPED_TRACE("drag: no any pixmap got, get node snapshot final try");
741         dragDropInfo.pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
742     }
743     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
744 }
745 
HideMenu()746 void GestureEventHub::HideMenu()
747 {
748     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
749     CHECK_NULL_VOID(pipeline);
750     auto dragDrogDropManager = pipeline->GetDragDropManager();
751     CHECK_NULL_VOID(dragDrogDropManager);
752     TAG_LOGI(AceLogTag::ACE_DRAG, "Hide menu. showPreviewAnimation false, startDrag true.");
753     SubwindowManager::GetInstance()->HideMenuNG(false, true);
754     auto menuWrapperNode = dragDrogDropManager->GetMenuWrapperNode();
755     CHECK_NULL_VOID(menuWrapperNode);
756     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
757     CHECK_NULL_VOID(menuWrapperPattern);
758     auto imageNode = menuWrapperPattern->GetPreview();
759     CHECK_NULL_VOID(imageNode);
760     auto imageContext = imageNode->GetRenderContext();
761     CHECK_NULL_VOID(imageContext);
762     imageContext->UpdateOpacity(0.0f);
763 }
764 
CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode,PreparedInfoForDrag & data)765 void CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode, PreparedInfoForDrag& data)
766 {
767     CHECK_NULL_VOID(menuWrapperNode);
768     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
769     CHECK_NULL_VOID(menuWrapperPattern);
770     auto menuPreview = menuWrapperPattern->GetPreview();
771     CHECK_NULL_VOID(menuPreview);
772     auto pipeline = PipelineContext::GetCurrentContextPtrSafelyWithCheck();
773     auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
774     CHECK_NULL_VOID(menuTheme);
775     auto previewBorderRadiusValue = menuTheme->GetPreviewBorderRadius();
776     data.borderRadius = BorderRadiusProperty(previewBorderRadiusValue);
777     auto menuNode = menuWrapperPattern->GetMenu();
778     CHECK_NULL_VOID(menuNode);
779     auto menuPattern = menuNode->GetPattern<MenuPattern>();
780     CHECK_NULL_VOID(menuPattern);
781     auto isShowHoverImage = menuPattern->GetIsShowHoverImage();
782     data.menuPreviewNode = menuPreview;
783     data.menuPreviewRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
784     if (!isShowHoverImage) {
785         return;
786     }
787     auto animationInfo = menuWrapperPattern->GetPreviewMenuAnimationInfo();
788     auto previewNode = menuWrapperPattern->GetHoverImageCustomPreview();
789     CHECK_NULL_VOID(previewNode);
790     auto previewPattern = previewNode->GetPattern<MenuPreviewPattern>();
791     CHECK_NULL_VOID(previewPattern);
792     auto rate = animationInfo.clipRate;
793     auto clipStartWidth = previewPattern->GetHoverImageAfterScaleWidth();
794     auto clipStartHeight = previewPattern->GetHoverImageAfterScaleHeight();
795     auto clipEndWidth = previewPattern->GetStackAfterScaleActualWidth();
796     auto clipEndHeight = previewPattern->GetStackAfterScaleActualHeight();
797     auto curentWidth = rate * (clipEndWidth - clipStartWidth) + clipStartWidth;
798     auto curentHeight = rate * (clipEndHeight - clipStartHeight) + clipStartHeight;
799     auto centerX = data.menuPreviewRect.GetX() + data.menuPreviewRect.Width() / 2;
800     auto centerY = data.menuPreviewRect.GetY() + data.menuPreviewRect.Height() / 2;
801     auto x = centerX - curentWidth / 2;
802     auto y = centerY - curentHeight / 2;
803     data.menuPreviewRect = RectF(x, y, curentWidth, curentHeight);
804     data.borderRadius = animationInfo.borderRadius;
805 }
806 
PrepareDragStartInfo(RefPtr<PipelineContext> & pipeline,PreparedInfoForDrag & data)807 void GestureEventHub::PrepareDragStartInfo(RefPtr<PipelineContext>& pipeline, PreparedInfoForDrag& data)
808 {
809     CHECK_NULL_VOID(pipeline);
810     auto dragDropManager = pipeline->GetDragDropManager();
811     CHECK_NULL_VOID(dragDropManager);
812     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
813     CHECK_NULL_VOID(menuWrapperNode);
814     CalcPreviewPaintRect(menuWrapperNode, data);
815     auto previewPaintRect = data.menuPreviewRect;
816     auto relativeContainerNode =
817         FrameNode::GetOrCreateFrameNode(V2::RELATIVE_CONTAINER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
818             []() { return AceType::MakeRefPtr<OHOS::Ace::NG::RelativeContainerPattern>(); });
819     CHECK_NULL_VOID(relativeContainerNode);
820     data.relativeContainerNode = relativeContainerNode;
821     auto relativeContainerLayoutProperty = relativeContainerNode->GetLayoutProperty();
822     CHECK_NULL_VOID(relativeContainerLayoutProperty);
823     relativeContainerLayoutProperty->UpdateUserDefinedIdealSize(
824         { CalcLength(previewPaintRect.Width(), DimensionUnit::PX),
825             CalcLength(previewPaintRect.Height(), DimensionUnit::PX) });
826     auto relativeContainerRenderContext = relativeContainerNode->GetRenderContext();
827     CHECK_NULL_VOID(relativeContainerRenderContext);
828     relativeContainerRenderContext->UpdateTransformTranslate({ 0, 0, 0.0f });
829 }
830 
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)831 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
832     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
833 {
834     ACE_SCOPED_TRACE("drag: to start");
835     auto dragNodePipeline = frameNode->GetContextRefPtr();
836     CHECK_NULL_VOID(dragNodePipeline);
837     auto overlayManager = dragNodePipeline->GetOverlayManager();
838     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
839     CHECK_NULL_VOID(pipeline);
840 
841     auto dragDropManager = pipeline->GetDragDropManager();
842     CHECK_NULL_VOID(dragDropManager);
843 
844     bool needChangeFwkForLeaveWindow = false;
845     if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
846         auto rootNode = dragDropManager->GetRootNode();
847         CHECK_NULL_VOID(rootNode);
848         auto geometryNode = rootNode->GetGeometryNode();
849         CHECK_NULL_VOID(geometryNode);
850         RectF rectF = geometryNode->GetFrameRect();
851         auto point = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
852         if (!rectF.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
853             needChangeFwkForLeaveWindow = true;
854         }
855     }
856     auto eventHub = eventHub_.Upgrade();
857     CHECK_NULL_VOID(eventHub);
858     if (dragDropProxy_) {
859         dragDropProxy_ = nullptr;
860     }
861     CHECK_NULL_VOID(dragEvent);
862     auto eventRet = dragEvent->GetResult();
863     if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
864         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
865         FireCustomerOnDragEnd(pipeline, eventHub);
866         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
867             SetMouseDragMonitorState(false);
868         }
869         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::APP_REFUSE_DRAG);
870         return;
871     }
872     std::string udKey;
873     auto unifiedData = dragEvent->GetData();
874     if (unifiedData) {
875         DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
876     }
877     int32_t recordsSize = GetBadgeNumber(unifiedData);
878     auto ret = SetDragData(unifiedData, udKey);
879     if (ret != 0) {
880         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
881         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
882     }
883 
884     std::map<std::string, int64_t> summary;
885     ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
886     if (ret != 0) {
887         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
888     }
889     dragDropManager->SetSummaryMap(summary);
890     RefPtr<PixelMap> pixelMap = dragDropInfo.pixelMap;
891     if (pixelMap) {
892         SetPixelMap(pixelMap);
893     } else if (pixelMap == nullptr) {
894         FireCustomerOnDragEnd(pipeline, eventHub);
895         TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
896         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
897             SetMouseDragMonitorState(false);
898         }
899         return;
900     }
901     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
902     if (dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
903         (info.GetSourceDevice() == SourceType::MOUSE) ? HandleDragThroughMouse(frameNode)
904                                                       : HandleDragThroughTouch(frameNode);
905     }
906     SetDragGatherPixelMaps(info);
907     dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
908     bool isMenuShow = DragDropGlobalController::GetInstance().IsMenuShowing();
909     if (isMenuShow) {
910         dragDropManager->SetIsDragWithContextMenu(true);
911         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
912     } else {
913         dragDropManager->SetIsDragWithContextMenu(false);
914     }
915     float defaultPixelMapScale = GetDefaultPixelMapScale(frameNode, info, isMenuShow, pixelMap);
916     auto windowScale = dragDropManager->GetWindowScale();
917     float scale = windowScale * defaultPixelMapScale;
918     auto isNeedCreateTiled =
919         DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice());
920     PreparedInfoForDrag data = { isMenuShow, recordsSize, defaultPixelMapScale, isNeedCreateTiled, OffsetF(),
921         OffsetF(), pixelMap, nullptr };
922     data.dragPreviewRect = RectF(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight());
923     dragDropManager->ResetContextMenuDragPosition();
924     RefPtr<Subwindow> subWindow = nullptr;
925     if (!needChangeFwkForLeaveWindow && IsNeedSwitchToSubWindow(data)) {
926         GestureEventHub::PrepareDragStartInfo(pipeline, data);
927         auto imageNode = overlayManager->GetPixelMapContentNode();
928         DragAnimationHelper::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale, data);
929         CHECK_NULL_VOID(imageNode);
930         data.imageNode = imageNode;
931         data.dragPreviewOffsetToScreen = GetDragPreviewInitPositionToScreen(context, data);
932         float previewScale =
933             info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
934         if (IsPixelMapNeedScale()) {
935             previewScale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
936             scale = previewScale * windowScale;
937         }
938         data.previewScale = previewScale;
939         // use menu preview scale replace default pixelMap scale.
940         if (isMenuShow) {
941             ProcessMenuPreviewScale(imageNode, scale, previewScale, windowScale, defaultPixelMapScale);
942         }
943         {
944             ACE_SCOPED_TRACE("drag: sub window show");
945             auto mainPipeline = PipelineContext::GetMainPipelineContext();
946             subWindow = SubwindowManager::GetInstance()->ShowPreviewNG((pipeline != mainPipeline));
947         }
948     }
949     if (!overlayManager->GetIsOnAnimation()) {
950         if (dragEventActuator_ != nullptr) {
951             dragEventActuator_->SetIsNotInPreviewState(true);
952         }
953     }
954     RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
955     CHECK_NULL_VOID(dragEventActuator_);
956     dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
957     dragPreviewPixelMap_ = nullptr;
958     CHECK_NULL_VOID(pixelMapDuplicated);
959     auto width = pixelMapDuplicated->GetWidth();
960     auto height = pixelMapDuplicated->GetHeight();
961     auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
962                                 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
963                                 : dragDropInfo.extraInfo;
964     auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
965     auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), data, scale, innerRect);
966     windowScale = NearZero(windowScale) ? 1.0f : windowScale;
967     dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
968     DragDropFuncWrapper::ResetNode(frameNode);
969     auto arkExtraInfoJson = JsonUtil::Create(true);
970     auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
971     auto dipScale = pipeline->GetDipScale();
972     arkExtraInfoJson->Put("scale", scale);
973     arkExtraInfoJson->Put("dip_scale", dipScale);
974     arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
975     arkExtraInfoJson->Put("event_id", info.GetPointerEventId());
976     UpdateExtraInfo(frameNode, arkExtraInfoJson, scale, data);
977     auto container = Container::Current();
978     CHECK_NULL_VOID(container);
979     DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, container->GetInstanceId());
980     auto windowId = container->GetWindowId();
981     ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
982     auto dragMoveLastPoint = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
983     DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
984         static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(),
985         static_cast<int32_t>(info.GetSourceTool()), dragMoveLastPoint.GetScreenX(),
986         dragMoveLastPoint.GetScreenY(), info.GetTargetDisplayId(), windowId, true, false, summary };
987     std::string summarys = DragDropFuncWrapper::GetSummaryString(summary);
988     DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
989     TAG_LOGI(AceLogTag::ACE_DRAG,
990         "Start drag, frameNode is %{public}s, pixelMap width %{public}d height %{public}d, "
991         "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, extraInfo length %{public}d, "
992         "pointerId %{public}d, toolType %{public}d, displayId %{public}d, windowId %{public}d, summary %{public}s, "
993         "eventId %{public}d.",
994         frameNode->GetTag().c_str(), width, height, scale, DragDropFuncWrapper::GetAnonyString(udKey).c_str(),
995         recordsSize, static_cast<int32_t>(extraInfoLimited.length()), info.GetPointerId(),
996         static_cast<int32_t>(info.GetSourceTool()), info.GetTargetDisplayId(), windowId, summarys.c_str(),
997         info.GetPointerEventId());
998     dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
999     {
1000         ACE_SCOPED_TRACE("drag: call msdp start drag");
1001         ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1002     }
1003     if (ret != 0) {
1004         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAGFWK_START_FAIL);
1005         if (subWindow) {
1006             SubwindowManager::GetInstance()->HidePreviewNG();
1007             overlayManager->RemovePixelMap();
1008         }
1009         FireCustomerOnDragEnd(pipeline, eventHub);
1010         TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1011         return;
1012     }
1013     StartVibratorByDrag(frameNode);
1014     dragEventActuator_->NotifyDragStart();
1015     DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAG_START_SUCCESS);
1016     bool isSwitchedToSubWindow = false;
1017     if (!needChangeFwkForLeaveWindow && subWindow && TryDoDragStartAnimation(context, subWindow, info, data)) {
1018         dragDropManager->SetIsReDragStart(pipeline != dragNodePipeline);
1019         isSwitchedToSubWindow = true;
1020     } else {
1021         dragDropManager->SetIsReDragStart(false);
1022         HideMenu();
1023         DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1024     }
1025     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && isSwitchedToSubWindow) {
1026         ret = RegisterCoordinationListener(pipeline);
1027         if (ret != 0) {
1028             TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1029         }
1030     }
1031     dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1032     dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1033     auto eventManager = pipeline->GetEventManager();
1034     CHECK_NULL_VOID(eventManager);
1035     eventManager->DoMouseActionRelease();
1036     eventManager->SetIsDragging(true);
1037     if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && needChangeFwkForLeaveWindow) {
1038         overlayManager->RemovePixelMap();
1039         overlayManager->RemovePreviewBadgeNode();
1040         overlayManager->RemoveGatherNode();
1041         dragEventActuator_->NotifyTransDragWindowToFwk();
1042         pipeline->AddAfterRenderTask([]() {
1043             ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1044             InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1045         });
1046     } else if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1047         dragEventActuator_->GetIsNotInPreviewState()) {
1048         if (!isSwitchedToSubWindow) {
1049             overlayManager->RemovePixelMap();
1050             overlayManager->RemovePreviewBadgeNode();
1051             overlayManager->RemoveGatherNode();
1052             dragEventActuator_->NotifyTransDragWindowToFwk();
1053             pipeline->AddAfterRenderTask([]() {
1054                 ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1055                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1056             });
1057         }
1058     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1059         if (!isSwitchedToSubWindow) {
1060             dragEventActuator_->NotifyTransDragWindowToFwk();
1061             pipeline->AddDragWindowVisibleTask([]() {
1062                 ACE_SCOPED_TRACE("drag: set drag window visible, mouse");
1063                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1064             });
1065             pipeline->RequestFrame();
1066         }
1067         dragDropManager->SetIsDragWindowShow(true);
1068     }
1069     dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1070     dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1071     CHECK_NULL_VOID(dragDropProxy_);
1072     dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1073     if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1074         dragDropManager->SetIsDisableDefaultDropAnimation(true);
1075         dragDropManager->OnDragEnd(
1076             DragPointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1077     }
1078 }
1079 
StartVibratorByDrag(const RefPtr<FrameNode> & frameNode)1080 void GestureEventHub::StartVibratorByDrag(const RefPtr<FrameNode>& frameNode)
1081 {
1082     bool enableHapticFeedback = frameNode->GetDragPreviewOption().enableHapticFeedback;
1083     auto parent = frameNode->GetAncestorNodeOfFrame(false);
1084     if (parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG) {
1085         enableHapticFeedback = parent->GetDragPreviewOption().enableHapticFeedback;
1086     }
1087     if (!enableHapticFeedback || !DragDropGlobalController::GetInstance().IsDragFilterShowing()) {
1088         return;
1089     }
1090     TAG_LOGI(AceLogTag::ACE_DRAG, "Enable haptic feedback, start vibrator by drag.");
1091     VibratorUtils::StartViratorDirectly("haptic.drag");
1092     DragDropGlobalController::GetInstance().UpdateDragFilterShowingStatus(false);
1093 }
1094 
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale,const PreparedInfoForDrag & dragInfoData)1095 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode, std::unique_ptr<JsonValue>& arkExtraInfoJson,
1096     float scale, const PreparedInfoForDrag& dragInfoData)
1097 {
1098     double opacity = frameNode->GetDragPreviewOption().options.opacity;
1099     auto optionInfo = frameNode->GetDragPreviewOption().options;
1100     arkExtraInfoJson->Put("dip_opacity", opacity);
1101     TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1102         arkExtraInfoJson->ToString().c_str());
1103 
1104     if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1105         optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1106     }
1107     DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1108     if (dragInfoData.isNeedCreateTiled) {
1109         return;
1110     }
1111     DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1112 }
1113 
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1114 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1115 {
1116     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1117     CHECK_NULL_RETURN(pipeline, -1);
1118     auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1119         ContainerScope scope(id);
1120         auto context = weak.Upgrade();
1121         CHECK_NULL_VOID(context);
1122         auto dragDropManager = context->GetDragDropManager();
1123         CHECK_NULL_VOID(dragDropManager);
1124         auto taskScheduler = context->GetTaskExecutor();
1125         CHECK_NULL_VOID(taskScheduler);
1126         taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1127             TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1128     };
1129     return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1130 }
1131 
HandleOnDragUpdate(const GestureEvent & info)1132 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1133 {
1134     gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1135 }
1136 
HandleDragEndAction(const DragframeNodeInfo & info)1137 void GestureEventHub::HandleDragEndAction(const DragframeNodeInfo& info)
1138 {
1139     auto weakFrameNode = info.frameNode;
1140     auto frameNode = weakFrameNode.Upgrade();
1141     CHECK_NULL_VOID(frameNode);
1142     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1143     if (!dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
1144         return;
1145     }
1146     auto pipeline = frameNode->GetContextRefPtr();
1147     CHECK_NULL_VOID(pipeline);
1148     auto dragDropManager = pipeline->GetDragDropManager();
1149     CHECK_NULL_VOID(dragDropManager);
1150     auto state = dragDropManager->GetGrayedState();
1151     if (!state) {
1152         return;
1153     }
1154     if (!info.gatherFrameNode.empty()) {
1155         auto gatherFrameNode = info.gatherFrameNode;
1156         for (const auto& itemFrameNode : gatherFrameNode) {
1157             DragAnimationHelper::SetPreOpacity(itemFrameNode);
1158         }
1159     } else {
1160         DragAnimationHelper::SetPreOpacity(frameNode);
1161     }
1162     dragDropManager->SetGrayedState(false);
1163 }
1164 
HandleOnDragEnd(const GestureEvent & info)1165 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1166 {
1167     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
1168     const static int32_t PLATFORM_VERSION_TEN = 10;
1169     if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1170         auto eventHub = eventHub_.Upgrade();
1171         CHECK_NULL_VOID(eventHub);
1172 
1173         auto frameNode = GetFrameNode();
1174         CHECK_NULL_VOID(frameNode);
1175 
1176         // Only the onDrop callback of dragged frame node is triggered.
1177         // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1178         if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1179             RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1180             if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1181                 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1182                 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1183             } else {
1184                 event->SetX(info.GetGlobalPoint().GetX());
1185                 event->SetY(info.GetGlobalPoint().GetY());
1186             }
1187             event->SetScreenX(info.GetScreenLocation().GetX());
1188             event->SetScreenY(info.GetScreenLocation().GetY());
1189             event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1190             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1191             eventHub->HandleInternalOnDrop(event, "");
1192         }
1193     }
1194     HandleDragEndAction(dragframeNodeInfo_);
1195     CHECK_NULL_VOID(dragDropProxy_);
1196     dragDropProxy_->DestroyDragWindow();
1197     dragDropProxy_ = nullptr;
1198 }
1199 
HandleOnDragCancel()1200 void GestureEventHub::HandleOnDragCancel()
1201 {
1202     CHECK_NULL_VOID(dragDropProxy_);
1203     dragDropProxy_->DestroyDragWindow();
1204     dragDropProxy_ = nullptr;
1205 }
1206 
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1207 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1208 {
1209     CHECK_NULL_RETURN(unifiedData, -1);
1210     ACE_SCOPED_TRACE("drag: set drag data to udmf");
1211     return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1212 }
1213 
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1214 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1215 {
1216     auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1217     auto eventHub = hub.Upgrade();
1218     CHECK_NULL_RETURN(eventHub, ret);
1219     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1220     CHECK_NULL_RETURN(pipeline, ret);
1221     auto taskScheduler = pipeline->GetTaskExecutor();
1222     CHECK_NULL_RETURN(taskScheduler, ret);
1223     auto dragDropManager = pipeline->GetDragDropManager();
1224     CHECK_NULL_RETURN(dragDropManager, ret);
1225     auto eventManager = pipeline->GetEventManager();
1226     RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1227     auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager,
1228                         dragframeNodeInfo = dragframeNodeInfo_,
1229                         gestureEventHubPtr = AceType::Claim(this)](const DragNotifyMsgCore& notifyMessage) {
1230         ContainerScope scope(id);
1231         taskScheduler->PostTask(
1232             [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id, dragframeNodeInfo,
1233                 gestureEventHubPtr]() {
1234                 auto container = Container::GetContainer(id);
1235                 if (!container) {
1236                     TAG_LOGE(AceLogTag::ACE_DRAG, "handle drag end callback, can not get container.");
1237                     return;
1238                 }
1239                 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1240                 TAG_LOGI(
1241                     AceLogTag::ACE_DRAG, "handle drag end callback, windowId is %{public}d.", container->GetWindowId());
1242                 dragDropManager->ResetDragEndOption(notifyMessage, dragEvent, id);
1243                 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1244                 if (ret != 0) {
1245                     TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1246                 }
1247                 if (eventManager) {
1248                     eventManager->DoMouseActionRelease();
1249                 }
1250                 if (notifyMessage.isInnerAndOuterTriggerBothNeeded) {
1251                     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1252                 }
1253                 if (eventHub->HasOnDragEnd()) {
1254                     (eventHub->GetOnDragEnd())(dragEvent);
1255                 }
1256                 gestureEventHubPtr->HandleDragEndAction(dragframeNodeInfo);
1257                 auto dragEventActuator = gestureEventHubPtr->GetDragEventActuator();
1258                 CHECK_NULL_VOID(dragEventActuator);
1259                 dragEventActuator->NotifyDragEnd();
1260             },
1261             TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1262     };
1263     return callback;
1264 }
1265 
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1266 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1267     DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1268 {
1269     ACE_SCOPED_TRACE("drag: execute user onDragStart");
1270     DragDropInfo dragDropInfo;
1271     CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1272     dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1273     auto eventHub = eventHub_.Upgrade();
1274     CHECK_NULL_RETURN(eventHub, dragDropInfo);
1275     auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1276     auto onDragStart = eventHub->GetOnDragStart();
1277     if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1278         onDragStart = eventHub->GetDefaultOnDragStart();
1279         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1280     }
1281     dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1282     if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1283         GenerateMousePixelMap(info);
1284     }
1285     dragDropInfo = onDragStart(dragEvent, extraParams);
1286 
1287     auto frameTag = frameNode->GetTag();
1288     if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1289         TAG_LOGD(AceLogTag::ACE_DRAG,
1290             "Get drag drop info, pixelmap and customNode are set to null "
1291             "when frameTag is %{public}s",
1292             frameTag.c_str());
1293         dragDropInfo.pixelMap = nullptr;
1294         dragDropInfo.customNode = nullptr;
1295     } else {
1296         auto dragPreview = frameNode->GetDragPreview();
1297         if (dragPreview.onlyForLifting) {
1298             return dragDropInfo;
1299         }
1300         if (!dragPreview.customNode && dragPreview.delayCreating && dragPreview.buildFunc) {
1301             dragPreview.customNode = dragPreview.buildFunc();
1302         }
1303         frameNode->SetDragPreview(dragPreview);
1304         dragPreviewInfo = dragPreview;
1305     }
1306     return dragDropInfo;
1307 }
1308 
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1309 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(
1310     const std::string& frameTag, DragDropInfo& dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1311 {
1312     auto eventHub = eventHub_.Upgrade();
1313     CHECK_NULL_RETURN(eventHub, nullptr);
1314     auto unifiedData = dragEvent->GetData();
1315     bool hasData = static_cast<bool>(unifiedData);
1316     if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1317         auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1318         if (dragDropInfo.extraInfo.empty()) {
1319             dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1320         }
1321         CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1322         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1323         unifiedData = dragEvent->GetData();
1324     }
1325     auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1326     CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1327     if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1328         defaultOnDragStart(dragEvent, "");
1329     }
1330     return unifiedData;
1331 }
1332 
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1333 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1334 {
1335     isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1336 }
1337 
IsDragForbidden() const1338 bool GestureEventHub::IsDragForbidden() const
1339 {
1340     return isDragForbiddenForWholeSubTree_;
1341 }
1342 
SetDragGatherPixelMaps(const GestureEvent & info)1343 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1344 {
1345     CHECK_NULL_VOID(dragEventActuator_);
1346     if (!dragEventActuator_->IsNeedGather()) {
1347         return;
1348     }
1349     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1350         SetMouseDragGatherPixelMaps();
1351     } else {
1352         SetNotMouseDragGatherPixelMaps();
1353     }
1354 }
1355 
SetMouseDragGatherPixelMaps()1356 void GestureEventHub::SetMouseDragGatherPixelMaps()
1357 {
1358     auto frameNode = GetFrameNode();
1359     CHECK_NULL_VOID(frameNode);
1360     if (frameNode->GetDragPreviewOption().isMultiTiled && !dragEventActuator_->GetRestartDrag()) {
1361         return;
1362     }
1363     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1364     CHECK_NULL_VOID(pipeline);
1365     auto dragDropManager = pipeline->GetDragDropManager();
1366     CHECK_NULL_VOID(dragDropManager);
1367     dragDropManager->ClearGatherPixelMap();
1368     CHECK_NULL_VOID(dragEventActuator_);
1369     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1370     CHECK_NULL_VOID(fatherNode);
1371     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1372     CHECK_NULL_VOID(scrollPattern);
1373     auto children = scrollPattern->GetVisibleSelectedItems();
1374     int cnt = 0;
1375     for (const auto& itemFrameNode : children) {
1376         if (itemFrameNode == frameNode) {
1377             continue;
1378         }
1379         CHECK_NULL_VOID(itemFrameNode);
1380         DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
1381         auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
1382         CHECK_NULL_VOID(gestureHub);
1383         auto itemPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1384         if (!itemPreviewPixelMap) {
1385             continue;
1386         }
1387         dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1388         cnt++;
1389         if (cnt > 1) {
1390             break;
1391         }
1392     }
1393 }
1394 
SetNotMouseDragGatherPixelMaps()1395 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
1396 {
1397     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1398     CHECK_NULL_VOID(pipeline);
1399     auto dragDropManager = pipeline->GetDragDropManager();
1400     CHECK_NULL_VOID(dragDropManager);
1401     dragDropManager->ClearGatherPixelMap();
1402     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1403     CHECK_NULL_VOID(mainPipeline);
1404     auto overlayManager = mainPipeline->GetOverlayManager();
1405     CHECK_NULL_VOID(overlayManager);
1406     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
1407     int cnt = 0;
1408     for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
1409         auto imageNode = (*iter).imageNode.Upgrade();
1410         CHECK_NULL_VOID(imageNode);
1411         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1412         CHECK_NULL_VOID(imageLayoutProperty);
1413         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
1414         auto itemPreviewPixelMap = imageSourceInfo.GetPixmap();
1415         if (!itemPreviewPixelMap) {
1416             continue;
1417         }
1418         dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1419         cnt++;
1420         if (cnt > 1) {
1421             break;
1422         }
1423     }
1424 }
1425 
GetSelectItemSize()1426 int32_t GestureEventHub::GetSelectItemSize()
1427 {
1428     CHECK_NULL_RETURN(dragEventActuator_, 0);
1429     if (!dragEventActuator_->IsNeedGather()) {
1430         return 0;
1431     }
1432     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(GetFrameNode());
1433     CHECK_NULL_RETURN(fatherNode, 0);
1434     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1435     CHECK_NULL_RETURN(scrollPattern, 0);
1436     auto children = scrollPattern->GetVisibleSelectedItems();
1437     return children.size();
1438 }
1439 
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1440 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1441 {
1442     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1443     auto eventHub = hub.Upgrade();
1444     CHECK_NULL_VOID(eventHub);
1445     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1446     CHECK_NULL_VOID(pipeline);
1447     auto dragDropManager = pipeline->GetDragDropManager();
1448     CHECK_NULL_VOID(dragDropManager);
1449     dragDropManager->RemoveDeadlineTimer();
1450     auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1451     CHECK_NULL_VOID(dragEvent);
1452     dragEvent->SetResult(DragRet::DRAG_FAIL);
1453     dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
1454     dragDropManager->DoDragReset();
1455     dragDropManager->SetIsDragged(false);
1456     dragDropManager->ResetDragging();
1457     dragDropManager->SetDraggingPointer(-1);
1458     dragDropManager->SetDraggingPressedState(false);
1459     dragDropManager->ResetDragPreviewInfo();
1460     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1461     if (eventHub->HasOnDragEnd()) {
1462         (eventHub->GetOnDragEnd())(dragEvent);
1463     }
1464 }
1465 
1466 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)1467 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
1468 {
1469     CHECK_NULL_VOID(customNode);
1470     bool hasImageNode = false;
1471     std::list<RefPtr<FrameNode>> imageNodes;
1472     int32_t depth = 1;
1473     PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
1474     CheckImageDecode(imageNodes);
1475     imageNodes.clear();
1476 }
1477 
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)1478 void GestureEventHub::PrintIfImageNode(
1479     const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
1480 {
1481     if (depth > MAX_BUILDER_DEPTH) {
1482         return;
1483     }
1484     if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
1485         auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
1486         CHECK_NULL_VOID(frameNode);
1487         auto pattern = frameNode->GetPattern<ImagePattern>();
1488         CHECK_NULL_VOID(pattern);
1489         hasImageNode = true;
1490         imageNodes.push_back(frameNode);
1491         TAG_LOGI(AceLogTag::ACE_DRAG,
1492             "customNode has ImageNode, syncLoad: %{public}d, decode complete: %{public}d",
1493             pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
1494     }
1495 
1496     auto children = builderNode->GetChildren();
1497     for (const auto& child : children) {
1498         PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
1499     }
1500 }
1501 
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)1502 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
1503 {
1504     if (imageNodes.empty()) {
1505         return;
1506     }
1507 
1508     for (const auto& imageNode : imageNodes) {
1509         auto pattern = imageNode->GetPattern<ImagePattern>();
1510         CHECK_NULL_VOID(pattern);
1511         if (!pattern->GetCanvasImage()) {
1512             TAG_LOGW(AceLogTag::ACE_DRAG, "ImageNode did not complete decoding");
1513         }
1514     }
1515 }
1516 
StartDragForCustomBuilderSync(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1517 bool GestureEventHub::StartDragForCustomBuilderSync(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1518     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1519 {
1520     SnapshotParam param;
1521     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
1522     {
1523         ACE_SCOPED_TRACE("drag: try get builder snapshot sync");
1524         pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
1525     }
1526 
1527     if (pixelMap == nullptr) {
1528         // try failed, need fall back to use async way
1529         return false;
1530     }
1531 
1532     // get snapshot successfully, go ahead
1533     dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1534     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1535     return true;
1536 }
1537 
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1538 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1539     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1540 {
1541     if (StartDragForCustomBuilderSync(info, pipeline, frameNode, dragDropInfo, event)) {
1542         return;
1543     }
1544 
1545     TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
1546     auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode,
1547         dragDropInfo, event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>
1548         finishCallback) mutable {
1549         ContainerScope scope(id);
1550         ACE_SCOPED_TRACE("drag: get snapshot async done, post task to UI for next handling");
1551         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
1552         if (pixelMap != nullptr) {
1553             dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1554         } else {
1555             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1556         }
1557         auto taskScheduler = pipeline->GetTaskExecutor();
1558         CHECK_NULL_VOID(taskScheduler);
1559         taskScheduler->PostTask(
1560             [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event, finishCallback]() {
1561                 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail finished, start drag.");
1562                 if (finishCallback) {
1563                     finishCallback();
1564                 }
1565                 CHECK_NULL_VOID(gestureEventHubPtr);
1566                 CHECK_NULL_VOID(frameNode);
1567                 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1568             },
1569             TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
1570     };
1571     SnapshotParam param;
1572     param.delay = CREATE_PIXELMAP_TIME;
1573     param.checkImageStatus = true;
1574     param.options.waitUntilRenderFinished = true;
1575     ACE_SCOPED_TRACE("drag: try sync failed, to get snapshot async");
1576     NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
1577     PrintBuilderNode(dragDropInfo.customNode);
1578 }
1579 #endif
1580 
GetDragPreviewInitPositionToScreen(const RefPtr<PipelineBase> & context,PreparedInfoForDrag & data)1581 OffsetF GestureEventHub::GetDragPreviewInitPositionToScreen(
1582     const RefPtr<PipelineBase>& context, PreparedInfoForDrag& data)
1583 {
1584     auto frameNode = GetFrameNode();
1585     CHECK_NULL_RETURN(frameNode, OffsetF());
1586     OffsetF previewOffset;
1587     OffsetF pixelMapHalfSize = data.pixelMap ? OffsetF(data.pixelMap->GetWidth() / 2.0f,
1588         data.pixelMap->GetHeight() / 2.0f) : OffsetF();
1589     previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(frameNode) - pixelMapHalfSize;
1590     auto frameTag = frameNode->GetTag();
1591     if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1592         auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1593         CHECK_NULL_RETURN(textDragPattern, previewOffset);
1594         auto dragNode = textDragPattern->MoveDragNode();
1595         if (dragNode) {
1596             previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(dragNode) - pixelMapHalfSize;
1597             return previewOffset;
1598         }
1599     }
1600 
1601     if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1602         auto offset = DragDropFuncWrapper::GetCurrentWindowOffset(context);
1603         return frameNodeOffset_ + offset;
1604     }
1605 
1606     if (data.isMenuShow) {
1607         OffsetF menuPreviewCenter = frameNodeOffset_ + OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f;
1608         menuPreviewCenter += DragDropFuncWrapper::GetCurrentWindowOffset(context);
1609         if (data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
1610             !data.isMenuShow) {
1611             previewOffset = menuPreviewCenter - pixelMapHalfSize + data.dragMovePosition;
1612         }
1613         if ((data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
1614                 data.imageNode->GetDragPreviewOption().sizeChangeEffect ==
1615                 DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) &&
1616             data.isMenuShow) {
1617             previewOffset = menuPreviewCenter - OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f +
1618                             data.dragMovePosition;
1619         }
1620     }
1621     return previewOffset;
1622 }
1623 
GetBadgeNumber(const RefPtr<UnifiedData> & unifiedData)1624 int32_t GestureEventHub::GetBadgeNumber(const RefPtr<UnifiedData>& unifiedData)
1625 {
1626     auto frameNode = GetFrameNode();
1627     CHECK_NULL_RETURN(frameNode, 1);
1628     auto pattern = frameNode->GetPattern();
1629     CHECK_NULL_RETURN(pattern, 1);
1630     int32_t badgeNumber = 1;
1631     pattern->ResetDragOption();
1632     if (pattern->GetDragRecordSize() >= 0) {
1633         badgeNumber = pattern->GetDragRecordSize();
1634     } else if (unifiedData) {
1635         auto recordSize = unifiedData->GetSize();
1636         badgeNumber = recordSize > 1 ? recordSize : 1;
1637     }
1638 
1639     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1640     auto customBadgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
1641     auto selectItemSize = GetSelectItemSize();
1642     if (customBadgeNumber.has_value()) {
1643         badgeNumber = customBadgeNumber.value();
1644         TAG_LOGI(AceLogTag::ACE_DRAG, "Use custom badge number, value is %{public}d", badgeNumber);
1645     } else if (selectItemSize > 1) {
1646         badgeNumber = selectItemSize;
1647         TAG_LOGI(AceLogTag::ACE_DRAG, "Use select item size, value is %{public}d", badgeNumber);
1648     }
1649     return badgeNumber;
1650 }
1651 
TryDoDragStartAnimation(const RefPtr<PipelineBase> & context,const RefPtr<Subwindow> & subWindow,const GestureEvent & info,PreparedInfoForDrag & data)1652 bool GestureEventHub::TryDoDragStartAnimation(const RefPtr<PipelineBase>& context, const RefPtr<Subwindow>& subWindow,
1653     const GestureEvent& info, PreparedInfoForDrag& data)
1654 {
1655     auto frameNode = GetFrameNode();
1656     auto container = Container::Current();
1657     auto eventHub = eventHub_.Upgrade();
1658     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1659     if (!subWindow || !frameNode || !container || !pipeline || !eventHub || !data.imageNode) {
1660         return false;
1661     }
1662 
1663     auto dragNodePipeline = frameNode->GetContextRefPtr();
1664     CHECK_NULL_RETURN(dragNodePipeline, false);
1665     auto overlayManager = dragNodePipeline->GetOverlayManager();
1666     CHECK_NULL_RETURN(overlayManager, false);
1667     auto isExpandDisplay = DragDropFuncWrapper::IsExpandDisplay(context);
1668     auto dragDropManager = DragDropFuncWrapper::GetDragDropManagerForDragAnimation(context, dragNodePipeline,
1669         subWindow, isExpandDisplay, container->GetInstanceId());
1670     CHECK_NULL_RETURN(dragDropManager, false);
1671     dragDropManager->SetIsDragWithContextMenu(data.isMenuShow);
1672 
1673     // create text node
1674     auto subWindowOffset = isExpandDisplay ? subWindow->GetWindowRect().GetOffset() : OffsetF();
1675     auto textNode = DragAnimationHelper::CreateBadgeTextNode(data.badgeNumber);
1676     data.textNode = textNode;
1677     DragAnimationHelper::SetNodeVisible(textNode, false);
1678     // create gatherNode
1679     auto originGatherNode = overlayManager->GetGatherNode();
1680     OffsetF positionToWindow = originGatherNode ? originGatherNode->GetPositionToWindowWithTransform() : OffsetF();
1681     std::vector<GatherNodeChildInfo> childrenInfo;
1682     auto gatherNode = DragAnimationHelper::GetOrCreateGatherNode(overlayManager, dragEventActuator_, childrenInfo);
1683     data.gatherNode = gatherNode;
1684     auto gatherNodeOffset = isExpandDisplay
1685             ? DragDropManager::GetTouchOffsetRelativeToSubwindow(dragNodePipeline->GetInstanceId()) + positionToWindow
1686             : positionToWindow;
1687     DragEventActuator::UpdateGatherAnimatePosition(childrenInfo, gatherNodeOffset);
1688 
1689     // mount node
1690     auto subWindowOverlayManager = subWindow->GetOverlayManager();
1691     CHECK_NULL_RETURN(subWindowOverlayManager, false);
1692     DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, childrenInfo);
1693     DragAnimationHelper::MountPixelMap(
1694         subWindowOverlayManager, eventHub->GetOrCreateGestureEventHub(), data, true);
1695 
1696     // update position
1697     UpdateNodePositionBeforeStartAnimation(frameNode, data, subWindowOffset);
1698     HideMenu();
1699     pipeline->FlushSyncGeometryNodeTasks();
1700     overlayManager->RemovePixelMap();
1701     DragAnimationHelper::ShowBadgeAnimation(textNode);
1702     DragAnimationHelper::HideDragNodeCopy(overlayManager);
1703 
1704     dragDropManager->DoDragStartAnimation(
1705         subWindowOverlayManager, info, eventHub->GetOrCreateGestureEventHub(), data);
1706     return true;
1707 }
1708 
UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode> & frameNode,PreparedInfoForDrag & data,const OffsetF & subWindowOffset)1709 void GestureEventHub::UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode>& frameNode,
1710     PreparedInfoForDrag& data, const OffsetF& subWindowOffset)
1711 {
1712     CHECK_NULL_VOID(frameNode);
1713     if (frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT || !data.isMenuShow) {
1714         DragAnimationHelper::UpdateBadgeTextNodePosition(frameNode, data.textNode, data.badgeNumber, data.previewScale,
1715             data.dragPreviewOffsetToScreen - subWindowOffset);
1716         DragDropFuncWrapper::UpdateNodePositionToScreen(data.imageNode, data.dragPreviewOffsetToScreen);
1717         DragAnimationHelper::PreLayout(data.imageNode);
1718     } else {
1719         DragDropFuncWrapper::UpdateNodePositionToScreen(data.relativeContainerNode, data.dragPreviewOffsetToScreen);
1720         DragAnimationHelper::PreLayout(data.relativeContainerNode);
1721     }
1722 }
1723 
CheckAllowDrag(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1724 bool GestureEventHub::CheckAllowDrag(const GestureEvent& info, const RefPtr<PipelineBase>& context,
1725     const RefPtr<FrameNode>& frameNode)
1726 {
1727     auto eventHub = eventHub_.Upgrade();
1728     CHECK_NULL_RETURN(eventHub, false);
1729     CHECK_NULL_RETURN(frameNode, false);
1730     if (!eventHub->HasOnDragStart()) {
1731         TAG_LOGE(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
1732         return false;
1733     }
1734     if (!IsAllowedDrag(eventHub)) {
1735         auto pattern = frameNode->GetPattern();
1736         CHECK_NULL_RETURN(pattern, false);
1737         TAG_LOGE(AceLogTag::ACE_DRAG,
1738             "FrameNode is not allow drag, tag is %{public}s"
1739             "draggable is %{public}d, drag start event is %{public}d,"
1740             "default support drag is %{public}d, user set is %{public}d.",
1741             frameNode->GetTag().c_str(), frameNode->IsDraggable(), eventHub->HasOnDragStart(),
1742             pattern->DefaultSupportDrag(), frameNode->IsUserSet());
1743         return false;
1744     }
1745     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1746     CHECK_NULL_RETURN(pipeline, false);
1747     auto eventManager = pipeline->GetEventManager();
1748     CHECK_NULL_RETURN(eventManager, false);
1749     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
1750         TAG_LOGE(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
1751         return false;
1752     }
1753 
1754     return true;
1755 }
1756 
CreateDragEvent(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1757 RefPtr<OHOS::Ace::DragEvent> GestureEventHub::CreateDragEvent(const GestureEvent& info,
1758     const RefPtr<PipelineBase>& context, const RefPtr<FrameNode>& frameNode)
1759 {
1760     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1761     CHECK_NULL_RETURN(frameNode, event);
1762     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1763     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1764         CHECK_NULL_RETURN(pipeline, event);
1765         event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1766         event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1767     } else {
1768         event->SetX(info.GetGlobalPoint().GetX());
1769         event->SetY(info.GetGlobalPoint().GetY());
1770     }
1771     event->SetScreenX(info.GetScreenLocation().GetX());
1772     event->SetScreenY(info.GetScreenLocation().GetY());
1773     event->SetDisplayX(info.GetScreenLocation().GetX());
1774     event->SetDisplayY(info.GetScreenLocation().GetY());
1775     event->SetSourceTool(info.GetSourceTool());
1776     return event;
1777 }
1778 
SetMouseDragMonitorState(bool state)1779 void GestureEventHub::SetMouseDragMonitorState(bool state)
1780 {
1781     auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
1782     if (ret != 0) {
1783         TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
1784             state, ret);
1785         return;
1786     }
1787     TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
1788 }
1789 
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)1790 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
1791 {
1792     if (setIsShow) {
1793         bindMenuStatus_.isBindCustomMenu = true;
1794         bindMenuStatus_.isShow = isShow;
1795         bindMenuStatus_.isShowPreviewMode = previewMode;
1796     } else {
1797         bindMenuStatus_.isBindLongPressMenu = true;
1798         bindMenuStatus_.longPressPreviewMode = previewMode;
1799     }
1800 }
1801 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)1802 void GestureEventHub::AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
1803 {
1804     if (!scrollableActuator_) {
1805         scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this));
1806     }
1807     scrollableActuator_->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
1808 }
1809 
1810 // Set by user define, which will replace old one.
SetDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1811 void GestureEventHub::SetDragEvent(
1812     const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1813 {
1814     if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1815         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1816     }
1817     dragEventActuator_->ReplaceDragEvent(dragEvent);
1818 }
1819 
SetDragDropEvent()1820 void GestureEventHub::SetDragDropEvent()
1821 {
1822     if (!dragEventActuator_ || !dragEventActuator_->GetIsNewFwk()) {
1823         isDragNewFwk_ = true;
1824         dragEventActuator_ = MakeRefPtr<DragDropEventActuator>(WeakClaim(this));
1825     }
1826 }
1827 
SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1828 void GestureEventHub::SetCustomDragEvent(
1829     const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1830 {
1831     if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1832         isDragNewFwk_ = false;
1833         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1834     }
1835     dragEventActuator_->SetCustomDragEvent(dragEvent);
1836 }
1837 
HasDragEvent() const1838 bool GestureEventHub::HasDragEvent() const
1839 {
1840     return dragEventActuator_ && (dragEventActuator_->HasDragEvent() || dragEventActuator_->GetIsNewFwk());
1841 }
1842 
RemoveDragEvent()1843 void GestureEventHub::RemoveDragEvent()
1844 {
1845     if (!dragEventActuator_) {
1846         return;
1847     }
1848     if (dragEventActuator_->GetIsNewFwk()) {
1849         dragEventActuator_ = nullptr;
1850         return;
1851     }
1852     dragEventActuator_->ClearDragEvent();
1853 }
1854 
SetThumbnailCallback(std::function<void (Offset)> && callback)1855 void GestureEventHub::SetThumbnailCallback(std::function<void(Offset)>&& callback)
1856 {
1857     if (dragEventActuator_) {
1858         dragEventActuator_->SetThumbnailCallback(std::move(callback));
1859     }
1860 }
1861 
GetTextDraggable() const1862 bool GestureEventHub::GetTextDraggable() const
1863 {
1864     return textDraggable_;
1865 }
1866 
SetTextDraggable(bool draggable)1867 void GestureEventHub::SetTextDraggable(bool draggable)
1868 {
1869     textDraggable_ = draggable;
1870 }
1871 
SetIsTextDraggable(bool isTextDraggable)1872 void GestureEventHub::SetIsTextDraggable(bool isTextDraggable)
1873 {
1874     isTextDraggable_ = isTextDraggable;
1875 }
1876 
GetIsTextDraggable()1877 bool GestureEventHub::GetIsTextDraggable()
1878 {
1879     return isTextDraggable_;
1880 }
1881 
SetPreviewMode(MenuPreviewMode mode)1882 void GestureEventHub::SetPreviewMode(MenuPreviewMode mode)
1883 {
1884     previewMode_ = mode;
1885 }
1886 
GetPreviewMode()1887 MenuPreviewMode GestureEventHub::GetPreviewMode()
1888 {
1889     return previewMode_;
1890 }
1891 
SetContextMenuShowStatus(bool contextMenuShowStatus)1892 void GestureEventHub::SetContextMenuShowStatus(bool contextMenuShowStatus)
1893 {
1894     contextMenuShowStatus_ = contextMenuShowStatus;
1895 }
1896 
GetContextMenuShowStatus()1897 bool GestureEventHub::GetContextMenuShowStatus()
1898 {
1899     return contextMenuShowStatus_;
1900 }
1901 
SetMenuBindingType(MenuBindingType menuBindingType)1902 void GestureEventHub::SetMenuBindingType(MenuBindingType menuBindingType)
1903 {
1904     menuBindingType_ = menuBindingType;
1905 }
1906 
GetMenuBindingType()1907 MenuBindingType GestureEventHub::GetMenuBindingType()
1908 {
1909     return menuBindingType_;
1910 }
1911 
SetPixelMap(RefPtr<PixelMap> pixelMap)1912 void GestureEventHub::SetPixelMap(RefPtr<PixelMap> pixelMap)
1913 {
1914     pixelMap_ = pixelMap;
1915 }
1916 
GetPixelMap()1917 RefPtr<PixelMap> GestureEventHub::GetPixelMap()
1918 {
1919     return pixelMap_;
1920 }
1921 
SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)1922 void GestureEventHub::SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)
1923 {
1924     dragPreviewPixelMap_ = pixelMap;
1925 }
1926 
GetDragEventActuator()1927 RefPtr<DragEventActuator> GestureEventHub::GetDragEventActuator()
1928 {
1929     return dragEventActuator_;
1930 }
1931 
GetDragPreviewPixelMap()1932 RefPtr<PixelMap> GestureEventHub::GetDragPreviewPixelMap()
1933 {
1934     return dragPreviewPixelMap_;
1935 }
1936 
SetMenuPreviewScale(float menuPreviewScale)1937 void GestureEventHub::SetMenuPreviewScale(float menuPreviewScale)
1938 {
1939     menuPreviewScale_ = menuPreviewScale;
1940 }
1941 
GetMenuPreviewScale() const1942 float GestureEventHub::GetMenuPreviewScale() const
1943 {
1944     return menuPreviewScale_;
1945 }
1946 
GetBindMenuStatus() const1947 const BindMenuStatus& GestureEventHub::GetBindMenuStatus() const
1948 {
1949     return bindMenuStatus_;
1950 }
1951 
1952 } // namespace OHOS::Ace::NG
1953