• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "core/components_ng/manager/drag_drop/drag_drop_manager.h"
17 
18 #include "base/geometry/point.h"
19 #include "base/geometry/rect.h"
20 #include "base/log/ace_trace.h"
21 #include "base/subwindow/subwindow_manager.h"
22 #include "base/utils/system_properties.h"
23 #include "base/utils/time_util.h"
24 #include "base/utils/utils.h"
25 #include "core/common/container_scope.h"
26 #include "core/common/interaction/interaction_data.h"
27 #include "core/common/interaction/interaction_interface.h"
28 #include "core/components/common/layout/grid_column_info.h"
29 #include "core/components/common/layout/grid_system_manager.h"
30 #include "core/components_ng/base/frame_node.h"
31 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
32 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
33 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
34 #include "core/components_ng/manager/drag_drop/drag_drop_spring_loading/drag_drop_spring_loading_detector.h"
35 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
36 #include "core/components_ng/pattern/grid/grid_event_hub.h"
37 #include "core/components_ng/pattern/list/list_event_hub.h"
38 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
39 #include "core/components_ng/pattern/root/root_pattern.h"
40 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
41 #include "core/components_v2/inspector/inspector_constants.h"
42 #include "core/pipeline_ng/pipeline_context.h"
43 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
44 
45 #ifdef ENABLE_ROSEN_BACKEND
46 #include "render_service_client/core/transaction/rs_transaction.h"
47 #include "render_service_client/core/transaction/rs_sync_transaction_controller.h"
48 #include "render_service_client/core/transaction/rs_sync_transaction_handler.h"
49 #include "render_service_client/core/ui/rs_ui_director.h"
50 #endif
51 
52 
53 namespace OHOS::Ace::NG {
54 namespace {
55 int64_t g_proxyId = 0;
56 constexpr Dimension PRESERVE_HEIGHT = 8.0_vp;
57 constexpr float FIRST_PIXELMAP_OPACITY = 0.6f;
58 constexpr float SECOND_PIXELMAP_OPACITY = 0.3f;
59 constexpr float FIRST_PIXELMAP_ANGLE = 8.0f;
60 constexpr float SECOND_PIXELMAP_ANGLE = -8.0f;
61 constexpr int32_t FIRST_GATHER_PIXEL_MAP = 1;
62 constexpr int32_t SECOND_GATHER_PIXEL_MAP = 2;
63 constexpr int32_t SQUARE_NUMBER = 2;
64 constexpr float TOUCH_DRAG_PIXELMAP_SCALE = 1.05f;
65 constexpr int32_t MAX_RETRY_TIMES = 3;
66 constexpr int32_t MAX_RETRY_DURATION = 800;
67 constexpr float MOVE_DISTANCE_LIMIT = 20.0f;
68 constexpr uint64_t MOVE_TIME_LIMIT = 6L;
69 constexpr float MAX_DISTANCE_TO_PRE_POINTER = 3.0f;
70 constexpr float DEFAULT_SPRING_RESPONSE = 0.347f;
71 constexpr float MIN_SPRING_RESPONSE = 0.05f;
72 constexpr float DEL_SPRING_RESPONSE = 0.005f;
73 constexpr float MIN_UI_EXTENSION_BOUNDARY_DISTANCE = 5.0f;
74 constexpr float MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE = 5.0f;
75 constexpr int32_t RESERVED_DEVICEID_1 = 0xAAAAAAFF;
76 constexpr int32_t RESERVED_DEVICEID_2 = 0xAAAAAAFE;
77 constexpr uint32_t TASK_DELAY_TIME = 5 * 1000;
78 constexpr uint32_t DROP_DELAY_TIME = 2 * 1000;
79 constexpr double DEVICE_TYPE_UNKOWN = 0.0;
80 constexpr double DEVICE_TYPE_SMALL = 600.0;
81 constexpr double DEVICE_TYPE_MEDIUM = 840.0;
82 constexpr int32_t SCALE_TYPE_FIRST = 2;
83 constexpr int32_t SCALE_TYPE_SECOND = 3;
84 constexpr int32_t SCALE_TYPE_THIRD = 4;
85 const RefPtr<InterpolatingSpring> DRAG_TRANSITION_ANIMATION_CURVE =
86     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 380.0f, 34.0f);
87 } // namespace
88 
GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode> & menuWrapperNode)89 RefPtr<RenderContext> GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode>& menuWrapperNode)
90 {
91     CHECK_NULL_RETURN(menuWrapperNode, nullptr);
92     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
93     CHECK_NULL_RETURN(menuWrapperPattern, nullptr);
94     auto menuNode = menuWrapperPattern->GetMenu();
95     CHECK_NULL_RETURN(menuNode, nullptr);
96     return menuNode->GetRenderContext();
97 }
98 
GetMenuWrapperNodeFromDrag()99 RefPtr<FrameNode> GetMenuWrapperNodeFromDrag()
100 {
101     auto pipelineContext = PipelineContext::GetMainPipelineContext();
102     CHECK_NULL_RETURN(pipelineContext, nullptr);
103     auto mainDragDropManager = pipelineContext->GetDragDropManager();
104     CHECK_NULL_RETURN(mainDragDropManager, nullptr);
105     return mainDragDropManager->GetMenuWrapperNode();
106 }
107 
DragDropManager()108 DragDropManager::DragDropManager()
109 {
110     if (DragDropGlobalController::GetInstance().IsAlreadyGetAppGlobalDrag()) {
111         return;
112     }
113     bool state = false;
114     auto result = InteractionInterface::GetInstance()->GetAppDragSwitchState(state);
115     if (result != 0) {
116         TAG_LOGI(AceLogTag::ACE_DRAG, "get app drag switch state failed!");
117         return;
118     }
119     DragDropGlobalController::GetInstance().SetIsAppGlobalDragEnabled(state);
120 }
121 
GetDragMoveLastPointByCurrentPointer(int32_t pointerId)122 const Point DragDropManager::GetDragMoveLastPointByCurrentPointer(int32_t pointerId)
123 {
124     auto it = fingerPointInfo_.find(pointerId);
125     if (it != fingerPointInfo_.end()) {
126         return it->second;
127     }
128     return Point(0, 0);
129 }
130 
UpdatePointInfoForFinger(int32_t pointerId,Point point)131 void DragDropManager::UpdatePointInfoForFinger(int32_t pointerId, Point point)
132 {
133     fingerPointInfo_[pointerId] = point;
134 }
135 
SetDelayDragCallBack(const std::function<void ()> & cb)136 void DragDropManager::SetDelayDragCallBack(const std::function<void()>& cb) noexcept
137 {
138     DragDropGlobalController::GetInstance().SetAsyncDragCallback(cb);
139 }
140 
SetCallAnsyncDragEnd(const std::function<void (DragStartRequestStatus)> & cb)141 void DragDropManager::SetCallAnsyncDragEnd(const std::function<void(DragStartRequestStatus)>& cb)
142 {
143     DragDropGlobalController::GetInstance().SetCallAnsyncDragEnd(cb);
144 }
145 
ExecuteDeadlineTimer()146 void DragDropManager::ExecuteDeadlineTimer()
147 {
148     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
149     CHECK_NULL_VOID(pipeline);
150     auto taskScheduler = pipeline->GetTaskExecutor();
151     CHECK_NULL_VOID(taskScheduler);
152     taskScheduler->PostDelayedTask(
153         [weakManager = WeakClaim(this)]() {
154             auto dragDropManager = weakManager.Upgrade();
155             CHECK_NULL_VOID(dragDropManager);
156             if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
157                 DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
158             }
159             dragDropManager->RemoveDeadlineTimer();
160         },
161         TaskExecutor::TaskType::UI, TASK_DELAY_TIME, "ArkUIDragDeadlineTimer");
162 }
163 
RemoveDeadlineTimer()164 void DragDropManager::RemoveDeadlineTimer()
165 {
166     DragDropGlobalController::GetInstance().SetAsyncDragCallback(nullptr);
167     DragDropGlobalController::GetInstance().SetDragStartRequestStatus(DragStartRequestStatus::READY);
168     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
169     CHECK_NULL_VOID(pipeline);
170     auto taskScheduler = pipeline->GetTaskExecutor();
171     CHECK_NULL_VOID(taskScheduler);
172     taskScheduler->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIDragDeadlineTimer");
173 }
174 
HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)175 void DragDropManager::HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)
176 {
177     if (dragStartRequestStatus == DragStartRequestStatus::WAITING) {
178         ExecuteDeadlineTimer();
179         DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
180     }
181     if (dragStartRequestStatus == DragStartRequestStatus::READY &&
182         DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
183         DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
184         DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
185         RemoveDeadlineTimer();
186     }
187 }
188 
CreateAndShowItemDragOverlay(const RefPtr<PixelMap> & pixelMap,const GestureEvent & info,const RefPtr<EventHub> & eventHub)189 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
190     const RefPtr<PixelMap>& pixelMap, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
191 {
192     CHECK_NULL_RETURN(pixelMap, nullptr);
193     // create Image for drag
194     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
195         []() { return AceType::MakeRefPtr<ImagePattern>(); });
196     CHECK_NULL_RETURN(imageNode, nullptr);
197     auto imagePattern = imageNode->GetPattern<ImagePattern>();
198     CHECK_NULL_RETURN(imagePattern, nullptr);
199     imagePattern->SetSyncLoad(true);
200     auto prop = imageNode->GetLayoutProperty<ImageLayoutProperty>();
201     CHECK_NULL_RETURN(prop, nullptr);
202     prop->UpdateAutoResize(false);
203     prop->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
204     auto targetSize = CalcSize(NG::CalcLength(pixelMap->GetWidth()), NG::CalcLength(pixelMap->GetHeight()));
205     prop->UpdateUserDefinedIdealSize(targetSize);
206     auto renderProp = imageNode->GetPaintProperty<ImageRenderProperty>();
207     renderProp->UpdateImageInterpolation(ImageInterpolation::HIGH);
208     imageNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
209     imageNode->MarkModifyDone();
210     imageNode->SetLayoutDirtyMarked(true);
211     imageNode->SetActive(true);
212     auto context = imageNode->GetContext();
213     if (context) {
214         context->FlushUITaskWithSingleDirtyNode(imageNode);
215     }
216     auto imageContext = imageNode->GetRenderContext();
217     CHECK_NULL_RETURN(imageContext, nullptr);
218     imageContext->UpdatePosition(
219         OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - pixelMap->GetWidth() / 2), // 2: Average factor.
220             Dimension(info.GetGlobalPoint().GetY() - pixelMap->GetHeight() / 2)));             // 2: Average factor.
221     imageContext->OnModifyDone();
222 
223     AddItemDrag(imageNode, eventHub);
224 
225     itemDragOverlayNode_ = imageNode;
226     SetIsDragged(true);
227     isDragCancel_ = false;
228     currentId_ = ++g_proxyId;
229     return MakeRefPtr<DragDropProxy>(currentId_);
230 }
231 
CreateAndShowItemDragOverlay(const RefPtr<UINode> & customNode,const GestureEvent & info,const RefPtr<EventHub> & eventHub)232 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
233     const RefPtr<UINode>& customNode, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
234 {
235     auto frameNode = DynamicCast<FrameNode>(customNode);
236     CHECK_NULL_RETURN(frameNode, nullptr);
237     auto renderContext = frameNode->GetRenderContext();
238     CHECK_NULL_RETURN(renderContext, nullptr);
239     auto geometryNode = frameNode->GetGeometryNode();
240     CHECK_NULL_RETURN(geometryNode, nullptr);
241     auto frameRect = geometryNode->GetFrameSize();
242     renderContext->UpdatePosition(
243         OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - frameRect.Width() / 2), // 2: Average factor.
244             Dimension(info.GetGlobalPoint().GetY() - frameRect.Height() / 2)));             // 2: Average factor.
245     renderContext->OnModifyDone();
246     AddItemDrag(frameNode, eventHub);
247     itemDragOverlayNode_ = frameNode;
248     SetIsDragged(true);
249     isDragCancel_ = false;
250     currentId_ = ++g_proxyId;
251     return MakeRefPtr<DragDropProxy>(currentId_);
252 }
253 
CreateTextDragDropProxy()254 RefPtr<DragDropProxy> DragDropManager::CreateTextDragDropProxy()
255 {
256     SetIsDragged(true);
257     isDragCancel_ = false;
258     currentId_ = ++g_proxyId;
259     return MakeRefPtr<DragDropProxy>(currentId_);
260 }
261 
GetWindowId()262 int32_t DragDropManager::GetWindowId()
263 {
264     auto windowId = -1;
265     auto container = Container::Current();
266     CHECK_NULL_RETURN(container, windowId);
267 
268     if (!container->IsSceneBoardEnabled()) {
269         isDragWindowSubWindow_ = false;
270         return windowId;
271     }
272 
273     if (!container->IsMainWindow()) {
274         // The window manager currently does not support creating child windows within child windows,
275         // so the root main window is used here
276         container = Container::GetContainer(CONTAINER_ID_DIVIDE_SIZE);
277         CHECK_NULL_RETURN(container, windowId);
278         if (!container->IsMainWindow()) {
279             isDragWindowSubWindow_ = false;
280             return windowId;
281         }
282     }
283 
284     windowId = static_cast<int32_t>(container->GetWindowId());
285     isDragWindowSubWindow_ = true;
286 
287     return windowId;
288 }
289 
CreateDragRootNode(const RefPtr<UINode> & customNode)290 RefPtr<FrameNode> DragDropManager::CreateDragRootNode(const RefPtr<UINode>& customNode)
291 {
292     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
293     CHECK_NULL_RETURN(pipeline, nullptr);
294 
295     auto rootNode = FrameNode::CreateFrameNodeWithTree(
296         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
297     rootNode->SetActive(true);
298     rootNode->SetHostRootId(pipeline->GetInstanceId());
299     rootNode->SetHostPageId(-1);
300     rootNode->AddChild(customNode);
301     rootNode->AttachToMainTree(false, AceType::RawPtr(pipeline));
302     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
303     pipeline->FlushUITasks();
304     return rootNode;
305 }
306 
AddItemDrag(const RefPtr<FrameNode> & frameNode,const RefPtr<EventHub> & eventHub)307 void DragDropManager::AddItemDrag(const RefPtr<FrameNode>& frameNode, const RefPtr<EventHub>& eventHub)
308 {
309     auto pipeline = frameNode->GetContext();
310     CHECK_NULL_VOID(pipeline);
311     auto rootNode = pipeline->GetRootElement();
312     auto container = Container::Current();
313     if (container && container->IsSceneBoardWindow()) {
314         auto host = eventHub->GetFrameNode();
315         CHECK_NULL_VOID(host);
316         auto overlayManager = pipeline->GetOverlayManager();
317         CHECK_NULL_VOID(overlayManager);
318         rootNode = DynamicCast<FrameNode>(overlayManager->FindWindowScene(host));
319     }
320     CHECK_NULL_VOID(rootNode);
321     frameNode->MountToParent(rootNode);
322     frameNode->OnMountToParentDone();
323     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
324 }
325 
RemoveItemDrag()326 void DragDropManager::RemoveItemDrag()
327 {
328     CHECK_NULL_VOID(itemDragOverlayNode_);
329     auto rootNode = itemDragOverlayNode_->GetParent();
330     CHECK_NULL_VOID(rootNode);
331     rootNode->RemoveChild(itemDragOverlayNode_);
332     rootNode->RebuildRenderContextTree();
333     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
334 }
335 
UpdateItemDragPosition(int32_t globalX,int32_t globalY)336 void DragDropManager::UpdateItemDragPosition(int32_t globalX, int32_t globalY)
337 {
338     CHECK_NULL_VOID(itemDragOverlayNode_);
339     auto rect = itemDragOverlayNode_->GetTransformRectRelativeToWindow();
340     auto pipeline = itemDragOverlayNode_->GetContext();
341     CHECK_NULL_VOID(pipeline);
342     const Rect windowRect = pipeline->GetDisplayWindowRectInfo();
343     auto maxX = static_cast<float>(windowRect.Width() - rect.Width());
344     auto maxY = static_cast<float>(windowRect.Height() - rect.Height());
345     auto renderContext = itemDragOverlayNode_->GetRenderContext();
346     CHECK_NULL_VOID(renderContext);
347     renderContext->UpdatePosition(
348         OffsetT<Dimension>(Dimension(std::min(std::max(globalX - rect.Width() / 2, 0.0f), maxX)), // 2: Average factor.
349             Dimension(std::min(std::max(globalY - rect.Height() / 2, 0.0f), maxY))));             // 2: Average factor.
350     renderContext->OnModifyDone();
351 }
352 
HideDragPreviewOverlay()353 void DragDropManager::HideDragPreviewOverlay()
354 {
355     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
356     CHECK_NULL_VOID(pipeline);
357     auto manager = pipeline->GetOverlayManager();
358     CHECK_NULL_VOID(manager);
359     manager->RemovePixelMap();
360     manager->RemoveGatherNode();
361     manager->RemoveDragPixelMap();
362     SubwindowManager::GetInstance()->HidePreviewNG();
363 }
364 
HideDragPreviewWindow(int32_t containerId)365 void DragDropManager::HideDragPreviewWindow(int32_t containerId)
366 {
367     auto overlayManager = GetDragAnimationOverlayManager(containerId);
368     CHECK_NULL_VOID(overlayManager);
369     overlayManager->RemovePixelMap();
370     overlayManager->RemoveGatherNode();
371     overlayManager->RemoveDragPixelMap();
372     SubwindowManager::GetInstance()->HidePreviewNG();
373 }
374 
HideSubwindowDragNode()375 void DragDropManager::HideSubwindowDragNode()
376 {
377     auto subwindowOverlayManager = subwindowOverlayManager_.Upgrade();
378     CHECK_NULL_VOID(subwindowOverlayManager);
379     subwindowOverlayManager->RemovePixelMap();
380     subwindowOverlayManager->RemoveGatherNode();
381     subwindowOverlayManager->RemoveDragPixelMap();
382     subwindowOverlayManager_ = nullptr;
383 }
384 
FindTargetInChildNodes(const RefPtr<UINode> parentNode,std::vector<RefPtr<FrameNode>> hitFrameNodes,bool findDrop)385 RefPtr<FrameNode> DragDropManager::FindTargetInChildNodes(
386     const RefPtr<UINode> parentNode, std::vector<RefPtr<FrameNode>> hitFrameNodes, bool findDrop)
387 {
388     CHECK_NULL_RETURN(parentNode, nullptr);
389     auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
390     if (parentFrameNode && (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible())) {
391         return nullptr;
392     }
393     auto children = parentFrameNode->GetFrameChildren();
394 
395     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
396         auto child = iter->Upgrade();
397         if (child == nullptr) {
398             continue;
399         }
400         auto childNode = AceType::DynamicCast<UINode>(child);
401         auto childFindResult = FindTargetInChildNodes(childNode, hitFrameNodes, findDrop);
402         if (childFindResult) {
403             return childFindResult;
404         }
405     }
406 
407     CHECK_NULL_RETURN(parentFrameNode, nullptr);
408     for (auto iter : hitFrameNodes) {
409         if (parentFrameNode == iter) {
410             auto eventHub = parentFrameNode->GetOrCreateEventHub<EventHub>();
411             if (!eventHub) {
412                 continue;
413             }
414             if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop())) {
415                 return parentFrameNode;
416             }
417             if (V2::ISOLATED_COMPONENT_ETS_TAG == parentFrameNode->GetTag() ||
418                 V2::DYNAMIC_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) {
419                 // Extension and Embedded component can potentially show placeholder nodes when not active. Isolated
420                 // and Dynamic component appear not to have this capability. So we dont need to check if its showing
421                 // the placeholder or not...
422                 return parentFrameNode;
423             }
424             if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == parentFrameNode->GetTag() ||
425                 V2::EMBEDDED_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) &&
426                 (!IsUIExtensionShowPlaceholder(parentFrameNode))) {
427                 return parentFrameNode;
428             }
429         }
430     }
431     return nullptr;
432 }
433 
CheckFrameNodeCanDrop(const RefPtr<FrameNode> & node)434 bool DragDropManager::CheckFrameNodeCanDrop(const RefPtr<FrameNode>& node)
435 {
436     CHECK_NULL_RETURN(node, false);
437     auto eventHub = node->GetOrCreateEventHub<EventHub>();
438     CHECK_NULL_RETURN(eventHub, false);
439     if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop()) ||
440         (eventHub->HasCustomerOnDragSpringLoading())) {
441         return true;
442     }
443     if (V2::ISOLATED_COMPONENT_ETS_TAG == node->GetTag() || V2::DYNAMIC_COMPONENT_ETS_TAG == node->GetTag()) {
444         return true;
445     }
446     if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() ||
447         V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
448         (!IsUIExtensionShowPlaceholder(node))) {
449         return true;
450     }
451 
452     return false;
453 }
454 
FindTargetDropNode(const RefPtr<UINode> parentNode,PointF localPoint)455 RefPtr<FrameNode> DragDropManager::FindTargetDropNode(const RefPtr<UINode> parentNode, PointF localPoint)
456 {
457     CHECK_NULL_RETURN(parentNode, nullptr);
458     auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
459     CHECK_NULL_RETURN(parentFrameNode, nullptr);
460     if (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible()) {
461         return nullptr;
462     }
463     auto renderContext = parentFrameNode->GetRenderContext();
464     CHECK_NULL_RETURN(renderContext, nullptr);
465     auto paintRect = renderContext->GetPaintRectWithoutTransform();
466     FrameNode::MapPointTo(localPoint, parentFrameNode->GetOrRefreshMatrixFromCache().revertMatrix);
467     auto subLocalPoint = localPoint - paintRect.GetOffset();
468 
469     auto children = parentFrameNode->GetFrameChildren();
470     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
471         auto child = iter->Upgrade();
472         if (child == nullptr) {
473             continue;
474         }
475         auto childNode = AceType::DynamicCast<UINode>(child);
476         auto childFindResult = FindTargetDropNode(childNode, subLocalPoint);
477         if (childFindResult) {
478             return childFindResult;
479         }
480     }
481 
482     if (paintRect.IsInRegion(localPoint)) {
483         if (parentFrameNode->GetDragHitTestBlock()) {
484             return parentFrameNode;
485         }
486         if (CheckFrameNodeCanDrop(parentFrameNode)) {
487             return parentFrameNode;
488         }
489     }
490     return nullptr;
491 }
492 
FilterSubwindowDragRootNode(const RefPtr<FrameNode> & node)493 RefPtr<FrameNode> DragDropManager::FilterSubwindowDragRootNode(const RefPtr<FrameNode>& node)
494 {
495     auto rootNode = node;
496     auto container = Container::Current();
497     CHECK_NULL_RETURN(container, rootNode);
498     auto containerId = container->GetInstanceId();
499     auto pipeline = PipelineContext::GetMainPipelineContext();
500     CHECK_NULL_RETURN(pipeline, rootNode);
501     if (isReDragStart_ && !DragDropFuncWrapper::IsExpandDisplay(pipeline) && containerId >= MIN_SUBCONTAINER_ID) {
502         rootNode = pipeline->GetRootElement();
503     }
504     return rootNode;
505 }
506 
FindDragFrameNodeByPosition(float globalX,float globalY,const RefPtr<FrameNode> & node)507 RefPtr<FrameNode> DragDropManager::FindDragFrameNodeByPosition(float globalX, float globalY,
508     const RefPtr<FrameNode>& node)
509 {
510     auto rootNode = node;
511     if (!rootNode) {
512         auto container = Container::Current();
513         CHECK_NULL_RETURN(container, nullptr);
514         auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
515         CHECK_NULL_RETURN(pipeline, nullptr);
516         if (container->IsSceneBoardWindow() && draggedFrameNode_) {
517             auto overlayManager = pipeline->GetOverlayManager();
518             CHECK_NULL_RETURN(overlayManager, nullptr);
519             rootNode = AceType::DynamicCast<FrameNode>(overlayManager->FindWindowScene(draggedFrameNode_));
520         }
521         if (!rootNode) {
522             rootNode = pipeline->GetRootElement();
523         }
524     }
525 
526     auto result = FindTargetDropNode(rootNode, {globalX, globalY});
527     if (result) {
528         if (CheckFrameNodeCanDrop(result)) {
529             return result;
530         }
531     }
532     return nullptr;
533 }
534 
CheckDragDropProxy(int64_t id) const535 bool DragDropManager::CheckDragDropProxy(int64_t id) const
536 {
537     return currentId_ == id;
538 }
539 
UpdateDragAllowDrop(const RefPtr<FrameNode> & dragFrameNode,const DragBehavior dragBehavior,const int32_t eventId,bool isCapi)540 void DragDropManager::UpdateDragAllowDrop(
541     const RefPtr<FrameNode>& dragFrameNode, const DragBehavior dragBehavior, const int32_t eventId, bool isCapi)
542 {
543     if (!IsDropAllowed(dragFrameNode)) {
544         // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
545         DragDropGlobalController::GetInstance().GetEnableDropDisallowedBadge()
546             ? UpdateDragStyle(DragCursorStyleCore::FORBIDDEN, eventId)
547             : UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
548         return;
549     }
550 
551     // drop allowed
552     CHECK_NULL_VOID(dragFrameNode);
553     const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
554     // special handling for no drag data present situation, always show as move
555     // For CAPI ,no ENABLE_DROP and DISABLE_DROP state, skip the judgment and consider it allowed to drop into. Continue
556     // to set dragBehavior.
557     if (!isCapi && (dragFrameNodeAllowDrop.empty() || summaryMap_.empty())) {
558         UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
559         return;
560     }
561 
562     //other case, check drag behavior
563     switch (dragBehavior) {
564         case DragBehavior::UNKNOWN: {
565             // the application does not config the drag behavior, use move when moving within
566             // draggedFrameNode or frameNode is disabled, otherwise use copy
567             auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
568             if (draggedFrameNode_ == dragFrameNode || !(eventHub && eventHub->IsEnabled()) ||
569                 CheckExtraSituation(dragFrameNode)) {
570                 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
571             } else {
572                 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
573             }
574             break;
575         }
576         case DragBehavior::MOVE: {
577             UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
578             break;
579         }
580         case DragBehavior::COPY: {
581             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
582             break;
583         }
584         default: {
585             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
586             break;
587         }
588     }
589 }
590 
CheckExtraSituation(const RefPtr<FrameNode> & dragFrameNode) const591 bool DragDropManager::CheckExtraSituation(const RefPtr<FrameNode>& dragFrameNode) const
592 {
593     return CheckInRichEditor(dragFrameNode);
594 }
595 
CheckInRichEditor(const RefPtr<FrameNode> & dragFrameNode) const596 bool DragDropManager::CheckInRichEditor(const RefPtr<FrameNode>& dragFrameNode) const
597 {
598     CHECK_NULL_RETURN(dragFrameNode && draggedFrameNode_, false);
599     auto parent = draggedFrameNode_->GetAncestorNodeOfFrame(false);
600     CHECK_NULL_RETURN(parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG, false);
601     return dragFrameNode == parent;
602 }
603 
UpdateDragStyle(const DragCursorStyleCore & dragStyle,int32_t eventId)604 void DragDropManager::UpdateDragStyle(const DragCursorStyleCore& dragStyle, int32_t eventId)
605 {
606     if (dragStyle != dragCursorStyleCore_) {
607         ACE_SCOPED_TRACE("drag: update drag style %d", dragStyle);
608         TAG_LOGI(
609             AceLogTag::ACE_DRAG, "Update DragStyle to %{public}d, pointerEventId: %{public}d.", dragStyle, eventId);
610         auto ret = InteractionInterface::GetInstance()->UpdateDragStyle(dragStyle, eventId);
611         if (ret != 0) {
612             TAG_LOGI(AceLogTag::ACE_DRAG,
613                 "Update DragStyle to %{public}d failed, keep %{public}d. pointerEventId: %{public}d. ret = %{public}d",
614                 dragStyle, dragCursorStyleCore_, eventId, ret);
615         } else {
616             dragCursorStyleCore_ = dragStyle;
617         }
618     }
619 }
620 
CheckParentVisible(const RefPtr<FrameNode> & frameNode)621 bool CheckParentVisible(const RefPtr<FrameNode>& frameNode)
622 {
623     CHECK_NULL_RETURN(frameNode, false);
624     bool isVisible = frameNode->IsVisible();
625     if (!isVisible) {
626         return false;
627     }
628     auto parent = frameNode->GetParent();
629     while (parent && parent->GetDepth() != 1) {
630         auto parentFrameNode = AceType::DynamicCast<FrameNode>(parent);
631         if (parentFrameNode && !parentFrameNode->IsVisible()) {
632             isVisible = false;
633             break;
634         }
635         parent = parent->GetParent();
636     }
637     return isVisible;
638 }
639 
FindHitFrameNodes(const Point & point)640 std::unordered_set<int32_t> DragDropManager::FindHitFrameNodes(const Point& point)
641 {
642     std::unordered_set<int32_t> frameNodeList;
643     for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
644         auto frameNode = iter->second.Upgrade();
645         if (!frameNode || !frameNode->IsActive() || !frameNode->IsVisible() || !frameNode->IsOnMainTree()) {
646             continue;
647         }
648         auto geometryNode = frameNode->GetGeometryNode();
649         if (!geometryNode) {
650             continue;
651         }
652         auto globalFrameRect = geometryNode->GetFrameRect();
653         globalFrameRect.SetOffset(frameNode->GetTransformRelativeOffset());
654         if (globalFrameRect.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
655             frameNodeList.emplace(frameNode->GetId());
656         }
657     }
658     return frameNodeList;
659 }
660 
UpdateDragListener(const Point & point)661 void DragDropManager::UpdateDragListener(const Point& point)
662 {
663     auto hitNodes = FindHitFrameNodes(point);
664     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragEnterNodes;
665     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragMoveNodes;
666     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragLeaveNodes;
667     for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
668         auto localHitResult = hitNodes.find(iter->first) != hitNodes.end();
669         auto preHitResult = parentHitNodes_.find(iter->first) != parentHitNodes_.end();
670         if (localHitResult && preHitResult) {
671             dragMoveNodes[iter->first] = iter->second;
672         }
673         if (localHitResult && !preHitResult) {
674             dragEnterNodes[iter->first] = iter->second;
675         }
676         if (!localHitResult && preHitResult) {
677             dragLeaveNodes[iter->first] = iter->second;
678         }
679     }
680     RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
681     CHECK_NULL_VOID(notifyEvent);
682     UpdateNotifyDragEvent(notifyEvent, point, DragEventType::MOVE);
683 
684     NotifyDragRegisterFrameNode(dragMoveNodes, DragEventType::MOVE, notifyEvent);
685     NotifyDragRegisterFrameNode(dragEnterNodes, DragEventType::ENTER, notifyEvent);
686     NotifyDragRegisterFrameNode(dragLeaveNodes, DragEventType::LEAVE, notifyEvent);
687     parentHitNodes_ = std::move(hitNodes);
688 }
689 
NotifyDragRegisterFrameNode(std::unordered_map<int32_t,WeakPtr<FrameNode>> nodes,DragEventType dragEventType,RefPtr<NotifyDragEvent> & notifyEvent)690 void DragDropManager::NotifyDragRegisterFrameNode(std::unordered_map<int32_t, WeakPtr<FrameNode>> nodes,
691     DragEventType dragEventType, RefPtr<NotifyDragEvent>& notifyEvent)
692 {
693     for (auto iter = nodes.begin(); iter != nodes.end(); iter++) {
694         auto frameNode = iter->second.Upgrade();
695         if (!frameNode) {
696             continue;
697         }
698         auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
699         if (!CheckParentVisible(frameNode) || (eventHub && !eventHub->IsEnabled())) {
700             continue;
701         }
702         auto pattern = frameNode->GetPattern<Pattern>();
703         if (!pattern) {
704             continue;
705         }
706         pattern->HandleOnDragStatusCallback(dragEventType, notifyEvent);
707     }
708 }
709 
NotifyDragFrameNode(const Point & point,const DragEventType & dragEventType,const DragRet & dragRet)710 void DragDropManager::NotifyDragFrameNode(
711     const Point& point, const DragEventType& dragEventType, const DragRet& dragRet)
712 {
713     RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
714     CHECK_NULL_VOID(notifyEvent);
715     UpdateNotifyDragEvent(notifyEvent, point, dragEventType);
716     notifyEvent->SetResult(dragRet);
717     NotifyDragRegisterFrameNode(nodesForDragNotify_, dragEventType, notifyEvent);
718 }
719 
GetRootNode()720 RefPtr<FrameNode> DragDropManager::GetRootNode()
721 {
722     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
723     CHECK_NULL_RETURN(pipeline, nullptr);
724     return pipeline->GetRootElement();
725 }
726 
OnDragStart(const Point & point,const RefPtr<FrameNode> & frameNode)727 void DragDropManager::OnDragStart(const Point& point, const RefPtr<FrameNode>& frameNode)
728 {
729     dragDropState_ = DragDropMgrState::DRAGGING;
730     NotifyDragFrameNode(point, DragEventType::START);
731     CHECK_NULL_VOID(frameNode);
732     preTargetFrameNode_ = frameNode;
733     draggedFrameNode_ = preTargetFrameNode_;
734     preMovePoint_ = point;
735     parentHitNodes_.emplace(frameNode->GetId());
736     DragDropBehaviorReporter::GetInstance().UpdateFrameNodeStartId(frameNode->GetId());
737     DragDropBehaviorReporter::GetInstance().UpdateStartPoint(point);
738     DragDropBehaviorReporter::GetInstance().UpdateLongPressDurationEnd(GetSysTimestamp());
739     DragDropBehaviorReporter::GetInstance().UpdateDropResult(DropResult::DROP_FAIL);
740 
741     // Reset hover status when drag start.
742     auto pipeline = frameNode->GetContextRefPtr();
743     CHECK_NULL_VOID(pipeline);
744     auto eventManager = pipeline->GetEventManager();
745     CHECK_NULL_VOID(eventManager);
746     eventManager->CleanHoverStatusForDragBegin();
747 
748     auto container = Container::GetContainer(pipeline->GetInstanceId());
749     CHECK_NULL_VOID(container);
750     if (container->IsSceneBoardWindow()) {
751         auto overlayManager = pipeline->GetOverlayManager();
752         CHECK_NULL_VOID(overlayManager);
753         rootNode_ = AceType::DynamicCast<FrameNode>(DragDropFuncWrapper::FindWindowScene(draggedFrameNode_));
754         auto dragDropManager = pipeline->GetDragDropManager();
755         CHECK_NULL_VOID(dragDropManager);
756         dragDropManager->SetRootNode(rootNode_);
757     }
758 }
759 
OnDragStart(const Point & point)760 void DragDropManager::OnDragStart(const Point& point)
761 {
762     dragDropState_ = DragDropMgrState::DRAGGING;
763     NotifyDragFrameNode(point, DragEventType::START);
764 
765     // Reset hover status when drag start.
766     auto pipeline = PipelineContext::GetCurrentContext();
767     CHECK_NULL_VOID(pipeline);
768     auto eventManager = pipeline->GetEventManager();
769     CHECK_NULL_VOID(eventManager);
770     eventManager->CleanHoverStatusForDragBegin();
771 }
772 
PrintDragFrameNode(const OHOS::Ace::DragPointerEvent & pointerEvent,const RefPtr<FrameNode> & dragFrameNode)773 void DragDropManager::PrintDragFrameNode(
774     const OHOS::Ace::DragPointerEvent& pointerEvent, const RefPtr<FrameNode>& dragFrameNode)
775 {
776     CHECK_NULL_VOID(dragFrameNode);
777     auto container = Container::Current();
778     CHECK_NULL_VOID(container);
779     if (preTargetFrameNode_) {
780         TAG_LOGI(AceLogTag::ACE_DRAG,
781             "Current windowId is %{public}d, pointerEventId is %{public}d, "
782             "PreTargetFrameNode is %{public}s, depth is %{public}d, New find "
783             "targetNode is %{public}s, depth is %{public}d.",
784             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
785             preTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
786     } else {
787         TAG_LOGI(AceLogTag::ACE_DRAG,
788             "Current windowId is %{public}d, pointerEventId is %{public}d, "
789             "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d",
790             container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str(),
791             dragFrameNode->GetDepth());
792     }
793 }
794 
PrintGridDragFrameNode(const float globalX,const float globalY,const RefPtr<FrameNode> & dragFrameNode)795 void DragDropManager::PrintGridDragFrameNode(
796     const float globalX, const float globalY, const RefPtr<FrameNode>& dragFrameNode)
797 {
798     CHECK_NULL_VOID(dragFrameNode);
799     auto container = Container::Current();
800     CHECK_NULL_VOID(container);
801     if (preGridTargetFrameNode_) {
802         TAG_LOGI(AceLogTag::ACE_DRAG,
803             "Current windowId is %{public}d"
804             "PreTargetFrameNode is %{public}s, depth is %{public}d,"
805             "New find targetNode is %{public}s, depth is %{public}d.",
806             container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
807             preGridTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
808     } else {
809         TAG_LOGI(AceLogTag::ACE_DRAG,
810             "Current windowId is %{public}d, "
811             "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d.",
812             container->GetWindowId(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
813     }
814 }
815 
TransDragWindowToDragFwk(int32_t windowContainerId)816 void DragDropManager::TransDragWindowToDragFwk(int32_t windowContainerId)
817 {
818     if (isDragFwkShow_) {
819         return;
820     }
821     TAG_LOGI(AceLogTag::ACE_DRAG, "TransDragWindowToDragFwk is %{public}d", isDragFwkShow_);
822     ACE_SCOPED_TRACE("drag: set drag window visible by transfer");
823     if (draggedFrameNode_) {
824         auto gestureHub = draggedFrameNode_->GetOrCreateGestureEventHub();
825         CHECK_NULL_VOID(gestureHub);
826         auto dragEventActuator = gestureHub->GetDragEventActuator();
827         CHECK_NULL_VOID(dragEventActuator);
828         dragEventActuator->NotifyTransDragWindowToFwk();
829     }
830     InteractionInterface::GetInstance()->SetDragWindowVisible(true);
831     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
832     isDragFwkShow_ = true;
833     HideSubwindowDragNode();
834     auto overlayManager = GetDragAnimationOverlayManager(windowContainerId);
835     CHECK_NULL_VOID(overlayManager);
836     overlayManager->RemoveDragPixelMap();
837     overlayManager->RemoveGatherNode();
838     SubwindowManager::GetInstance()->HidePreviewNG();
839     info_.scale = -1.0;
840     dampingOverflowCount_ = 0;
841 }
842 
OnDragMoveOut(const DragPointerEvent & pointerEvent)843 void DragDropManager::OnDragMoveOut(const DragPointerEvent& pointerEvent)
844 {
845     Point point = pointerEvent.GetPoint();
846     auto container = Container::Current();
847     if (container && container->IsSceneBoardWindow()) {
848         if (IsDragged() && IsWindowConsumed()) {
849             SetIsWindowConsumed(false);
850             return;
851         }
852     }
853     isReDragStart_ = false;
854     SetIsWindowConsumed(false);
855     UpdateVelocityTrackerPoint(point, false);
856     UpdateDragListener(Point(-1, -1));
857     NotifyPullEventListener(pointerEvent);
858     if (preTargetFrameNode_) {
859         TAG_LOGI(AceLogTag::ACE_DRAG, "Leave the current window, windowId is %{public}d,"
860             " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
861             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
862             preTargetFrameNode_->GetDepth());
863         FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
864         preTargetFrameNode_ = nullptr;
865     }
866     if (IsNeedDisplayInSubwindow() || isDragWithContextMenu_) {
867         TransDragWindowToDragFwk(Container::CurrentId());
868     }
869     ResetBundleInfo();
870     ClearSummary();
871     ClearExtraInfo();
872     SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
873 }
874 
OnDragThrow(const DragPointerEvent & pointerEvent)875 void DragDropManager::OnDragThrow(const DragPointerEvent& pointerEvent)
876 {
877     auto container = Container::Current();
878     if (container && container->IsSceneBoardWindow()) {
879         if (IsDragged() && IsWindowConsumed()) {
880             SetIsWindowConsumed(false);
881             return;
882         }
883     }
884     SetIsWindowConsumed(false);
885     Point point = pointerEvent.GetPoint();
886     UpdateVelocityTrackerPoint(point, false);
887     UpdateDragListener(Point(-1, -1));
888     if (preTargetFrameNode_) {
889         TAG_LOGI(AceLogTag::ACE_DRAG, "Throw from the current window, windowId is %{public}d,"
890             " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
891             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
892             preTargetFrameNode_->GetDepth());
893         FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
894         preTargetFrameNode_ = nullptr;
895     }
896     TransDragWindowToDragFwk(container->GetInstanceId());
897     ClearSummary();
898     ClearExtraInfo();
899     SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
900     isPullThrow_ = true;
901 }
902 
OnDragPullCancel(const DragPointerEvent & pointerEvent)903 void DragDropManager::OnDragPullCancel(const DragPointerEvent& pointerEvent)
904 {
905     RemoveDeadlineTimer();
906     auto container = Container::Current();
907     auto containerId = container->GetInstanceId();
908     DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
909     DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
910     if (container && container->IsSceneBoardWindow()) {
911         if (IsDragged() && IsWindowConsumed()) {
912             SetIsWindowConsumed(false);
913             return;
914         }
915     }
916     SetIsWindowConsumed(false);
917     Point point = pointerEvent.GetPoint();
918     UpdateVelocityTrackerPoint(point, false);
919     UpdateDragListener(Point(-1, -1));
920     if (preTargetFrameNode_) {
921         TAG_LOGI(AceLogTag::ACE_DRAG, "Cancel from the current window, windowId is %{public}d,"
922             " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
923             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
924             preTargetFrameNode_->GetDepth());
925         FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
926         preTargetFrameNode_ = nullptr;
927     }
928     DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::MOVE };
929     ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
930     ClearSummary();
931     ClearExtraInfo();
932     ClearVelocityInfo();
933     DoDragReset();
934 }
935 
OnDragStartForDragEvent(const DragPointerEvent & pointerEvent,const RefPtr<FrameNode> & frameNode)936 void DragDropManager::OnDragStartForDragEvent(const DragPointerEvent& pointerEvent,
937     const RefPtr<FrameNode>& frameNode)
938 {
939     auto container = Container::Current();
940     CHECK_NULL_VOID(container);
941     ResetPreTargetFrameNode(container->GetInstanceId());
942     RequireSummaryAndDragBundleInfoIfNecessary(pointerEvent);
943     SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
944     OnDragMove(pointerEvent, extraInfo_, frameNode);
945     TAG_LOGI(AceLogTag::ACE_DRAG, "start drag, current windowId is %{public}d", container->GetWindowId());
946 }
947 
HandleDragEvent(const DragPointerEvent & pointerEvent,DragEventAction action,const RefPtr<FrameNode> & node)948 void DragDropManager::HandleDragEvent(const DragPointerEvent& pointerEvent, DragEventAction action,
949     const RefPtr<FrameNode>& node)
950 {
951     switch (action) {
952         case DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER: {
953             RequireSummary();
954             OnDragStart(pointerEvent.GetPoint());
955             break;
956         }
957         // PULL_OUT
958         case DragEventAction::DRAG_EVENT_OUT: {
959             OnDragMoveOut(pointerEvent);
960             break;
961         }
962         case DragEventAction::DRAG_EVENT_PULL_THROW: {
963             OnDragThrow(pointerEvent);
964             break;
965         }
966         case DragEventAction::DRAG_EVENT_PULL_CANCEL: {
967             OnDragPullCancel(pointerEvent);
968             break;
969         }
970         case DragEventAction::DRAG_EVENT_END: {
971             OnDragEnd(pointerEvent, extraInfo_, node);
972             break;
973         }
974         case DragEventAction::DRAG_EVENT_START: {
975             OnDragStartForDragEvent(pointerEvent, node);
976             break;
977         }
978         default:
979             break;
980     }
981 }
982 
OnDragAsyncEnd()983 void DragDropManager::OnDragAsyncEnd()
984 {
985     auto asyncEndCallback = DragDropGlobalController::GetInstance().GetCallAnsyncEnd();
986     DragStartRequestStatus dragStatus = DragDropGlobalController::GetInstance().GetDragStartRequestStatus();
987     if (asyncEndCallback && dragStatus == DragStartRequestStatus::WAITING) {
988         asyncEndCallback(dragStatus);
989     }
990 }
991 
isDistanceLimited(const Point & point)992 bool DragDropManager::isDistanceLimited(const Point& point)
993 {
994     auto distance = sqrt(pow(point.GetX() - preMovePoint_.GetX(), 2) + pow(point.GetY() - preMovePoint_.GetY(), 2));
995     TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance: %{public}f", distance);
996     if (distance < MOVE_DISTANCE_LIMIT) {
997         TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance is less than limit");
998         return true;
999     }
1000     return false;
1001 }
1002 
isTimeLimited(const DragPointerEvent & pointerEvent,const Point & point)1003 bool DragDropManager::isTimeLimited(const DragPointerEvent& pointerEvent, const Point& point)
1004 {
1005     uint64_t currentTimeStamp = static_cast<uint64_t>(
1006         std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
1007     if (currentTimeStamp > preTimeStamp_ && currentTimeStamp - preTimeStamp_ < MOVE_TIME_LIMIT) {
1008         TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, time is less than limit");
1009         return true;
1010     }
1011     return false;
1012 }
1013 
ReachMoveLimit(const DragPointerEvent & pointerEvent,const Point & point)1014 bool DragDropManager::ReachMoveLimit(const DragPointerEvent& pointerEvent, const Point& point)
1015 {
1016     if (pointerEvent.sourceTool == SourceTool::MOUSE) {
1017         if (isTimeLimited(pointerEvent, point) && isDistanceLimited(point)) {
1018             return true;
1019         }
1020     }
1021     return false;
1022 }
1023 
HandleOnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)1024 void DragDropManager::HandleOnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1025     const RefPtr<FrameNode>& dragFrameNode)
1026 {
1027     CHECK_NULL_VOID(dragFrameNode);
1028 
1029     if (dragFrameNode == preTargetFrameNode_) {
1030         FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::MOVE, extraInfo);
1031         return;
1032     }
1033 
1034     FireOnDragLeave(preTargetFrameNode_, pointerEvent, extraInfo);
1035     PrintDragFrameNode(pointerEvent, dragFrameNode);
1036     FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::ENTER, extraInfo);
1037     preTargetFrameNode_ = dragFrameNode;
1038 }
1039 
OnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node)1040 void DragDropManager::OnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1041     const RefPtr<FrameNode>& node)
1042 {
1043     RequireSummaryAndDragBundleInfoIfNecessary(pointerEvent);
1044     Point point = pointerEvent.GetPoint();
1045     auto container = Container::Current();
1046     CHECK_NULL_VOID(container);
1047     if (container && container->IsSceneBoardWindow()) {
1048         if (IsDragged() && IsWindowConsumed()) {
1049             SetIsWindowConsumed(false);
1050             return;
1051         }
1052     }
1053     if (ReachMoveLimit(pointerEvent, point)) {
1054         return;
1055     }
1056     NotifyPullEventListener(pointerEvent);
1057     preMovePoint_ = point;
1058     preDragPointerEvent_ = pointerEvent;
1059     preTimeStamp_ = static_cast<uint64_t>(
1060         std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
1061     SetIsWindowConsumed(false);
1062     if (isDragFwkShow_) {
1063         auto menuWrapper = GetMenuWrapperNodeFromDrag();
1064         if (menuWrapper) {
1065             OffsetF menuPosition(
1066                 static_cast<float>(pointerEvent.GetDisplayX()), static_cast<float>(pointerEvent.GetDisplayY()));
1067             SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(
1068                 menuPosition, 1.0, false, menuWrapper ? menuWrapper->GetId() : -1);
1069         }
1070     }
1071     UpdateVelocityTrackerPoint(point, false);
1072     UpdateDragListener(point);
1073     auto dragFrameNode = FindDragFrameNodeByPosition(
1074         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), node);
1075     if (!dragFrameNode) {
1076         if (preTargetFrameNode_) {
1077             TAG_LOGI(AceLogTag::ACE_DRAG,
1078                 "Not find drag target node, current windowId is %{public}d, pointerEventId is %{public}d, "
1079                 "PreTargetFrameNode is %{public}s, depth is %{public}d.",
1080                 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
1081                 preTargetFrameNode_->GetDepth());
1082             FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
1083             preTargetFrameNode_ = nullptr;
1084         }
1085         UpdateDragStyle(DragCursorStyleCore::MOVE, pointerEvent.pointerEventId);
1086         return;
1087     }
1088     HandleOnDragMove(pointerEvent, extraInfo, dragFrameNode);
1089 }
1090 
ResetDragDropStatus(const Point & point,const DragDropRet & dragDropRet,int32_t windowId)1091 void DragDropManager::ResetDragDropStatus(const Point& point, const DragDropRet& dragDropRet, int32_t windowId)
1092 {
1093     ACE_SCOPED_TRACE("drag: reset drag %d, %d", dragDropRet.result, dragDropRet.hasCustomAnimation);
1094     if (dragDropRet.result != DragRet::DRAG_FAIL || !isMouseDragged_) {
1095         InteractionInterface::GetInstance()->SetDragWindowVisible(!dragDropRet.hasCustomAnimation);
1096     }
1097     InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1098     NotifyDragFrameNode(point, DragEventType::DROP, dragDropRet.result);
1099     ResetPullId();
1100     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1101     isReDragStart_ = false;
1102 }
1103 
ResetPreTargetFrameNode(int32_t instanceId)1104 void DragDropManager::ResetPreTargetFrameNode(int32_t instanceId)
1105 {
1106     auto container = Container::GetContainer(instanceId);
1107     if (container && (container->IsSceneBoardWindow() || container->IsUIExtensionWindow())) {
1108         return;
1109     }
1110     // pull-in subwindow, need to notify showMenu and update menu offset.
1111     if (instanceId > MIN_SUBCONTAINER_ID) {
1112         isDragFwkShow_ = true;
1113     }
1114     preTargetFrameNode_ = nullptr;
1115 }
1116 
ResetDragEndOption(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent,int32_t currentId)1117 void DragDropManager::ResetDragEndOption(
1118     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent, int32_t currentId)
1119 {
1120     ResetBundleInfo();
1121     SetDragResult(notifyMessage, dragEvent);
1122     SetDragBehavior(notifyMessage, dragEvent);
1123     DoDragReset();
1124     SetIsDragged(false);
1125     SetDraggingPointer(-1);
1126     SetDraggingPressedState(false);
1127     ResetDragPreviewInfo();
1128     HideDragPreviewWindow(currentId);
1129     CHECK_NULL_VOID(dragEvent);
1130     dragEvent->SetDragSource(dragBundleInfo_.bundleName);
1131     dragEvent->SetRemoteDev(dragBundleInfo_.isRemoteDev);
1132     dragEvent->SetPressedKeyCodes(GetDragDropPointerEvent().pressedKeyCodes);
1133 }
1134 
DoDragReset()1135 void DragDropManager::DoDragReset()
1136 {
1137     dragDropState_ = DragDropMgrState::IDLE;
1138     preTargetFrameNode_ = nullptr;
1139     draggedFrameNode_ = nullptr;
1140     rootNode_ = nullptr;
1141     menuWrapperNode_ = nullptr;
1142     preMovePoint_ = Point(0, 0);
1143     hasNotifiedTransformation_ = false;
1144     badgeNumber_ = -1;
1145     isDragWithContextMenu_ = false;
1146     dampingOverflowCount_ = 0;
1147     isDragNodeNeedClean_ = false;
1148     isAnyDraggableHit_ = false;
1149     isPullThrow_ = false;
1150     fingerPointInfo_.clear();
1151     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1152     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1153 }
1154 
ResetDraggingStatus(const TouchEvent & touchPoint)1155 void DragDropManager::ResetDraggingStatus(const TouchEvent& touchPoint)
1156 {
1157     if (IsDraggingPressed(touchPoint.id)) {
1158         SetDraggingPressedState(false);
1159     }
1160     if (!IsItemDragging() && IsDragging() && IsSameDraggingPointer(touchPoint.id) && !isPullThrow_) {
1161         TAG_LOGI(AceLogTag::ACE_DRAG, "Reset dragging status, stop drag. pointerId: %{public}d", touchPoint.id);
1162         DragPointerEvent dragPointerEvent;
1163         DragDropFuncWrapper::ConvertPointerEvent(touchPoint, dragPointerEvent);
1164         SetIsDisableDefaultDropAnimation(true);
1165         OnDragEnd(dragPointerEvent, "");
1166     }
1167 }
1168 
HandleOnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)1169 void DragDropManager::HandleOnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1170     const RefPtr<FrameNode>& dragFrameNode)
1171 {
1172     CHECK_NULL_VOID(dragFrameNode);
1173     Point point = pointerEvent.GetPoint();
1174     auto container = Container::Current();
1175     CHECK_NULL_VOID(container);
1176     if (!IsDropAllowed(dragFrameNode)) {
1177         TAG_LOGI(AceLogTag::ACE_DRAG,
1178             "DragDropManager onDragEnd, target data is not allowed to fall into. WindowId is %{public}d, "
1179             "pointerEventId is %{public}d.",
1180             container->GetWindowId(), pointerEvent.pointerEventId);
1181         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_REFUSE_DATA);
1182         ACE_SCOPED_TRACE("drag: stop drag, not allowed to drop");
1183         ResetDragDrop(container->GetWindowId(), point);
1184         return;
1185     }
1186     TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, pointerEventId is %{public}d, "
1187         "TargetNode is %{public}s.",
1188         container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str());
1189     if (IsUIExtensionOrDynamicComponent(dragFrameNode)) {
1190         auto pattern = dragFrameNode->GetPattern<Pattern>();
1191         pattern->HandleDragEvent(pointerEvent);
1192         NotifyDragFrameNode(point, DragEventType::DROP);
1193         return;
1194     }
1195 
1196     RequestDragSummaryInfoAndPrivilege();
1197     std::string udKey;
1198     InteractionInterface::GetInstance()->GetUdKey(udKey);
1199     auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1200     CHECK_NULL_VOID(eventHub);
1201     if (!eventHub->GetDisableDataPrefetch()) {
1202         if (!CheckRemoteData(dragFrameNode, pointerEvent, udKey)) {
1203             auto unifiedData = RequestUDMFDataWithUDKey(udKey);
1204             DoDropAction(dragFrameNode, pointerEvent, unifiedData, udKey);
1205         }
1206     } else {
1207         DoDropAction(dragFrameNode, pointerEvent, nullptr, udKey);
1208     }
1209 }
1210 
OnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node,const bool keyEscape)1211 void DragDropManager::OnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1212     const RefPtr<FrameNode>& node, const bool keyEscape)
1213 {
1214     NotifyDragSpringLoadingIntercept(extraInfo);
1215     RemoveDeadlineTimer();
1216     Point point = pointerEvent.GetPoint();
1217     DragDropBehaviorReporter::GetInstance().UpdateEndPoint(point);
1218     dragDropPointerEvent_ = pointerEvent;
1219     auto preTargetFrameNode = preTargetFrameNode_;
1220     DoDragReset();
1221     auto container = Container::Current();
1222     auto containerId = container->GetInstanceId();
1223     DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
1224     if (container && container->IsSceneBoardWindow() && (IsDragged() && IsWindowConsumed())) {
1225         TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager is dragged or window consumed. WindowId is %{public}d",
1226             container->GetWindowId());
1227         return;
1228     }
1229     UpdateVelocityTrackerPoint(point, true);
1230     auto dragFrameNode = FindDragFrameNodeByPosition(
1231         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), FilterSubwindowDragRootNode(node));
1232     if (HandleUIExtensionComponentDragCancel(preTargetFrameNode, dragFrameNode, keyEscape, pointerEvent, point)) {
1233         return;
1234     }
1235     if (isDragCancel_) {
1236         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1237         TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropManager is dragCancel, finish drag. WindowId is %{public}d, "
1238             "pointerEventId is %{public}d.",
1239             container->GetWindowId(), pointerEvent.pointerEventId);
1240         ACE_SCOPED_TRACE("drag: drag cancelled");
1241         DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::UNKNOWN };
1242         ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
1243         FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
1244         ClearVelocityInfo();
1245         return;
1246     }
1247     if (IsUIExtensionOrDynamicComponent(preTargetFrameNode) && preTargetFrameNode != dragFrameNode) {
1248         HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE);
1249     }
1250     if (!dragFrameNode) {
1251         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_DATA_UNSUPPORT);
1252         TAG_LOGI(AceLogTag::ACE_DRAG,
1253             "DragDropManager onDragEnd, not find drop target, stop drag. WindowId is %{public}d, "
1254             "pointerEventId is %{public}d.",
1255             container->GetWindowId(), pointerEvent.pointerEventId);
1256         ACE_SCOPED_TRACE("drag: drag stop, not find drop target");
1257         ResetDragDrop(container->GetWindowId(), point);
1258         return;
1259     }
1260     HandleOnDragEnd(pointerEvent, extraInfo, dragFrameNode);
1261 }
1262 
HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode> & preTargetFrameNode,const RefPtr<FrameNode> & dragFrameNode,const bool keyEscape,const DragPointerEvent & pointerEvent,const Point & point)1263 bool DragDropManager::HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode>& preTargetFrameNode,
1264     const RefPtr<FrameNode>& dragFrameNode, const bool keyEscape, const DragPointerEvent& pointerEvent,
1265     const Point& point)
1266 {
1267     if (!isDragCancel_) {
1268         return false;
1269     }
1270     if (keyEscape && IsUIExtensionOrDynamicComponent(preTargetFrameNode)) {
1271         HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::PULL_CANCEL);
1272         NotifyDragFrameNode(point, DragEventType::DROP);
1273         return true;
1274     }
1275     if (IsUIExtensionOrDynamicComponent(dragFrameNode)) {
1276         auto pattern = dragFrameNode->GetPattern<Pattern>();
1277         CHECK_NULL_RETURN(pattern, true);
1278         pattern->HandleDragEvent(pointerEvent);
1279         NotifyDragFrameNode(point, DragEventType::DROP);
1280         return true;
1281     }
1282     return false;
1283 }
1284 
IsDropAllowed(const RefPtr<FrameNode> & dragFrameNode)1285 bool DragDropManager::IsDropAllowed(const RefPtr<FrameNode>& dragFrameNode)
1286 {
1287     CHECK_NULL_RETURN(dragFrameNode, false);
1288     // application passed in null to indicate refusing all drag data forcedly
1289     bool isDisallowDropForcedly = dragFrameNode->GetDisallowDropForcedly();
1290     if (isDisallowDropForcedly) {
1291         return false;
1292     }
1293     const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
1294     // if application does not set allow drop or set with empty, treat as all data types is allowed
1295     if (dragFrameNodeAllowDrop.empty() || summaryMap_.empty()) {
1296         return true;
1297     }
1298     DragDropBehaviorReporter::GetInstance().UpdateAllowDropType(dragFrameNodeAllowDrop);
1299     dragSummaryInfo_.summary = summaryMap_;
1300     return UdmfClient::GetInstance()->IsAppropriateType(dragSummaryInfo_, dragFrameNodeAllowDrop);
1301 }
1302 
RequestDragSummaryInfoAndPrivilege()1303 void DragDropManager::RequestDragSummaryInfoAndPrivilege()
1304 {
1305     RequireSummary();
1306     int ret = InteractionInterface::GetInstance()->AddPrivilege();
1307     if (ret != 0 && SystemProperties::GetDebugEnabled()) {
1308         TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction AddPrivilege in DragEnd with code:%{public}d", ret);
1309     }
1310     ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1311     ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1312     if (ret == 0) {
1313         previewRect_ =
1314             Rect(shadowOffsetData.offsetX, shadowOffsetData.offsetY, shadowOffsetData.width, shadowOffsetData.height);
1315     } else {
1316         TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction GetShadowOffset in DragEnd with code:%{public}d", ret);
1317     }
1318 }
1319 
DoDropAction(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<UnifiedData> & unifiedData,const std::string & udKey)1320 void DragDropManager::DoDropAction(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1321     const RefPtr<UnifiedData>& unifiedData, const std::string& udKey)
1322 {
1323     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1324     CHECK_NULL_VOID(event);
1325     if (!udKey.empty()) {
1326         event->SetUdKey(udKey);
1327     }
1328     if (unifiedData == nullptr) {
1329         event->SetIsGetDataSuccess(false);
1330     } else {
1331         DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
1332         event->SetData(unifiedData);
1333         event->SetIsGetDataSuccess(true);
1334     }
1335 
1336     OnDragDrop(event, dragFrameNode, pointerEvent);
1337 }
1338 
RequestUDMFDataWithUDKey(const std::string & udKey)1339 RefPtr<UnifiedData> DragDropManager::RequestUDMFDataWithUDKey(const std::string& udKey)
1340 {
1341     if (udKey.empty()) {
1342         TAG_LOGI(AceLogTag::ACE_DRAG, "udKey is empty");
1343         return nullptr;
1344     }
1345     ACE_SCOPED_TRACE("drag: get drag data from udmf");
1346     RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->CreateUnifiedData();
1347     auto ret = UdmfClient::GetInstance()->GetData(udData, udKey);
1348     if (ret != 0) {
1349         TAG_LOGI(AceLogTag::ACE_DRAG, "Get udmfData failed");
1350         return nullptr;
1351     }
1352     return udData;
1353 }
1354 
TryGetDataBackGround(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey,int32_t count)1355 void DragDropManager::TryGetDataBackGround(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1356     const std::string& udKey, int32_t count)
1357 {
1358     auto pipeline = PipelineContext::GetCurrentContext();
1359     CHECK_NULL_VOID(pipeline);
1360     auto taskScheduler = pipeline->GetTaskExecutor();
1361     CHECK_NULL_VOID(taskScheduler);
1362     taskScheduler->PostTask(
1363         [id = Container::CurrentId(), pipeline, dragFrameNode, pointerEvent, udKey, count,
1364         weakManager = WeakClaim(this)]() {
1365             ContainerScope scope(id);
1366             auto dragDropManager = weakManager.Upgrade();
1367             CHECK_NULL_VOID(dragDropManager);
1368             auto taskScheduler = pipeline->GetTaskExecutor();
1369             CHECK_NULL_VOID(taskScheduler);
1370             auto result = dragDropManager->RequestUDMFDataWithUDKey(udKey);
1371             if (result != nullptr || count >= MAX_RETRY_TIMES) {
1372                 taskScheduler->PostTask(
1373                     [dragFrameNode, pointerEvent, weakManager, result, udKey]() {
1374                         auto dragDropManager = weakManager.Upgrade();
1375                         CHECK_NULL_VOID(dragDropManager);
1376                         dragDropManager->DoDropAction(dragFrameNode, pointerEvent, result, udKey);
1377                     },
1378                     TaskExecutor::TaskType::UI, "ArkUIDragDropAction");
1379             } else {
1380                 // first temp get udmfData failed, prepare to retryGetData.
1381                 taskScheduler->PostDelayedTask(
1382                     [dragFrameNode, pointerEvent, weakManager, count, udKey]() {
1383                         auto dragDropManager = weakManager.Upgrade();
1384                         CHECK_NULL_VOID(dragDropManager);
1385                         dragDropManager->TryGetDataBackGround(dragFrameNode, pointerEvent, udKey, count + 1);
1386                     },
1387                     TaskExecutor::TaskType::UI, MAX_RETRY_DURATION, "ArkUIDragDropRetryGetData");
1388             }
1389         },
1390         TaskExecutor::TaskType::BACKGROUND, "ArkUIDragDropGetDataBackground");
1391 }
1392 
CheckRemoteData(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey)1393 bool DragDropManager::CheckRemoteData(
1394     const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent, const std::string& udKey)
1395 {
1396     if (udKey.empty()) {
1397         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1398         return false;
1399     }
1400     std::string remoteUdKey = udKey;
1401     auto isRemoteData = UdmfClient::GetInstance()->GetRemoteStatus(remoteUdKey);
1402     if (isRemoteData) {
1403         TAG_LOGI(AceLogTag::ACE_DRAG, "Stop drag with motion drag action.");
1404         TryGetDataBackGround(dragFrameNode, pointerEvent, udKey);
1405         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1406         DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::IS_CROSSING);
1407         return isRemoteData;
1408     }
1409     DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::NOT_CROSSING);
1410     return isRemoteData;
1411 }
1412 
OnDragDrop(RefPtr<OHOS::Ace::DragEvent> & event,const RefPtr<FrameNode> & dragFrameNode,const OHOS::Ace::DragPointerEvent & pointerEvent)1413 void DragDropManager::OnDragDrop(RefPtr<OHOS::Ace::DragEvent>& event, const RefPtr<FrameNode>& dragFrameNode,
1414     const OHOS::Ace::DragPointerEvent& pointerEvent)
1415 {
1416     auto point = pointerEvent.GetPoint();
1417     CHECK_NULL_VOID(dragFrameNode);
1418     auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1419     CHECK_NULL_VOID(eventHub);
1420     UpdateDragEvent(event, pointerEvent);
1421     auto extraParams = eventHub->GetDragExtraParams(extraInfo_, point, DragEventType::DROP);
1422     DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(true);
1423     DragDropBehaviorReporter::GetInstance().UpdateFrameNodeDropId(dragFrameNode->GetId());
1424     DragDropBehaviorReporter::GetInstance().UpdateDropResult(DropResult::DROP_SUCCESS);
1425     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1426     if (event->IsDragEndPending() && event->GetRequestIdentify() != -1) {
1427         if (PostStopDrag(dragFrameNode, pointerEvent, event, extraParams)) {
1428             return;
1429         }
1430     }
1431     HandleStopDrag(dragFrameNode, pointerEvent, event, extraParams);
1432     DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1433 }
1434 
HandleStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1435 void DragDropManager::HandleStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1436     const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1437 {
1438     auto point = pointerEvent.GetPoint();
1439     CHECK_NULL_VOID(dragFrameNode);
1440     auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1441     CHECK_NULL_VOID(eventHub);
1442     eventHub->HandleInternalOnDrop(event, extraParams);
1443     ClearVelocityInfo();
1444     SetIsDragged(false);
1445     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1446     CHECK_NULL_VOID(pipeline);
1447     auto dragResult = event->GetResult();
1448     if (dragResult == DragRet::DRAG_FAIL) {
1449         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_RECEIVE_FAIL);
1450     } else if (dragResult == DragRet::DRAG_CANCEL) {
1451         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1452     }
1453     auto useCustomAnimation = event->IsUseCustomAnimation();
1454     if (event->GetNeedDoInternalDropAnimation() && useCustomAnimation) {
1455         TAG_LOGI(AceLogTag::ACE_DRAG, "Need do internal drop animation, set useCustomAnimation to false.");
1456         useCustomAnimation = false;
1457     }
1458     auto dragBehavior = event->GetDragBehavior();
1459     auto container = Container::Current();
1460     CHECK_NULL_VOID(container);
1461     auto windowId = container->GetWindowId();
1462     ExecuteStopDrag(event, dragResult, useCustomAnimation, windowId, dragBehavior, pointerEvent);
1463     NotifyDragFrameNode(point, DragEventType::DROP, event->GetResult());
1464     dragFrameNode->MarkDirtyNode();
1465     ResetPullId();
1466     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1467     pipeline->RequestFrame();
1468 }
1469 
PostStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1470 bool DragDropManager::PostStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1471     const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1472 {
1473     CHECK_NULL_RETURN(dragFrameNode, false);
1474     CHECK_NULL_RETURN(event, false);
1475     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1476     CHECK_NULL_RETURN(pipeline, false);
1477     auto taskScheduler = pipeline->GetTaskExecutor();
1478     CHECK_NULL_RETURN(taskScheduler, false);
1479     taskScheduler->PostDelayedTask(
1480         [pointerEvent, event, extraParams, nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1481             weakManager = WeakClaim(this)]() {
1482             if (!DragDropGlobalController::GetInstance().IsCurrentDrag(event->GetRequestIdentify())) {
1483                 return;
1484             }
1485             if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase() || !event) {
1486                 return;
1487             }
1488             auto dragDropManager = weakManager.Upgrade();
1489             if (dragDropManager) {
1490                 auto frameNode = nodeWeak.Upgrade();
1491                 event->SetResult(DragRet::DRAG_FAIL);
1492                 dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1493             }
1494             DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1495         },
1496         TaskExecutor::TaskType::UI, DROP_DELAY_TIME, "ArkUIStopDragDeadlineTimer");
1497     return DragDropGlobalController::GetInstance().RequestDragEndCallback(event->GetRequestIdentify(),
1498         event->GetResult(), GetStopDragCallBack(dragFrameNode, pointerEvent, event, extraParams));
1499 }
1500 
GetStopDragCallBack(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1501 std::function<void(const DragRet&)> DragDropManager::GetStopDragCallBack(const RefPtr<FrameNode>& dragFrameNode,
1502     const DragPointerEvent& pointerEvent, const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1503 {
1504     auto callback = [id = Container::CurrentId(), pointerEvent, event, extraParams,
1505         nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1506         weakManager = WeakClaim(this)] (const DragRet& dragResult) {
1507         ContainerScope scope(id);
1508         auto dragDropManager = weakManager.Upgrade();
1509         CHECK_NULL_VOID(dragDropManager);
1510         CHECK_NULL_VOID(event);
1511         event->SetResult(dragResult);
1512         auto frameNode = nodeWeak.Upgrade();
1513         dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1514     };
1515     return callback;
1516 }
1517 
ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent> & event,DragRet dragResult,bool useCustomAnimation,int32_t windowId,DragBehavior dragBehavior,const OHOS::Ace::DragPointerEvent & pointerEvent)1518 void DragDropManager::ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent>& event, DragRet dragResult,
1519     bool useCustomAnimation, int32_t windowId, DragBehavior dragBehavior,
1520     const OHOS::Ace::DragPointerEvent& pointerEvent)
1521 {
1522     if (useCustomAnimation && event->HasDropAnimation()) {
1523         ExecuteCustomDropAnimation(event, DragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior });
1524         return;
1525     }
1526     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1527     CHECK_NULL_VOID(pipeline);
1528     HideSubwindowDragNode();
1529     auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1530     if (overlayManager && !isDragFwkShow_) {
1531         overlayManager->RemoveDragPixelMap();
1532         overlayManager->RemoveFilter();
1533         pipeline->FlushMessages();
1534     }
1535     pipeline->AddAfterRenderTask([dragResult, useCustomAnimation, windowId, dragBehavior,
1536                                      pointerEventId = pointerEvent.pointerEventId, weak = WeakClaim(this)]() mutable {
1537         auto manager = weak.Upgrade();
1538         if (manager) {
1539             manager->HideDragPreviewOverlay();
1540             useCustomAnimation = manager->IsDisableDefaultDropAnimation() ? true : useCustomAnimation;
1541         }
1542         TAG_LOGI(AceLogTag::ACE_DRAG,
1543             "Stop drag, start do drop animation. useCustomAnimation is %{public}d,"
1544             "WindowId is %{public}d, pointerEventId is %{public}d.",
1545             useCustomAnimation, windowId, pointerEventId);
1546         InteractionInterface::GetInstance()->SetDragWindowVisible(!useCustomAnimation);
1547         DragDropRet dragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior };
1548         InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1549     });
1550 }
1551 
SetRSSyncTransaction(OHOS::Rosen::RSSyncTransactionController ** transactionController,std::shared_ptr<Rosen::RSSyncTransactionHandler> & transactionHandler,const RefPtr<NG::PipelineContext> & pipeline)1552 void DragDropManager::SetRSSyncTransaction(OHOS::Rosen::RSSyncTransactionController** transactionController,
1553     std::shared_ptr<Rosen::RSSyncTransactionHandler>& transactionHandler, const RefPtr<NG::PipelineContext>& pipeline)
1554 {
1555 #ifdef ENABLE_ROSEN_BACKEND
1556     if (SystemProperties::GetMultiInstanceEnabled()) {
1557         CHECK_NULL_VOID(pipeline);
1558         auto window = pipeline->GetWindow();
1559         CHECK_NULL_VOID(window);
1560         auto rsUIDirector = window->GetRSUIDirector();
1561         CHECK_NULL_VOID(rsUIDirector);
1562         auto rsUIContext = rsUIDirector->GetRSUIContext();
1563         CHECK_NULL_VOID(rsUIContext);
1564         transactionHandler = rsUIContext->GetSyncTransactionHandler();
1565     } else {
1566         auto rsSyncTransactionController = Rosen::RSSyncTransactionController::GetInstance();
1567         *transactionController = rsSyncTransactionController;
1568     }
1569 #endif
1570 }
1571 
ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent> & event,DragDropRet dragDropRet)1572 void DragDropManager::ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent>& event, DragDropRet dragDropRet)
1573 {
1574     CHECK_NULL_VOID(event);
1575     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1576     CHECK_NULL_VOID(pipeline);
1577 
1578 #ifdef ENABLE_ROSEN_BACKEND
1579     OHOS::Rosen::RSSyncTransactionController* transactionController = nullptr;
1580     std::shared_ptr<Rosen::RSSyncTransactionHandler> transactionHandler;
1581     SetRSSyncTransaction(&transactionController, transactionHandler, pipeline);
1582     if (transactionController) {
1583         transactionController->OpenSyncTransaction();
1584     } else if (transactionHandler) {
1585         transactionHandler->OpenSyncTransaction();
1586     } else {
1587         TAG_LOGE(AceLogTag::ACE_DRAG, "transactionController and handler invalid");
1588         return;
1589     }
1590     event->ExecuteDropAnimation();
1591     auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1592     if (overlayManager) {
1593         overlayManager->RemoveDragPixelMap();
1594         overlayManager->RemoveFilter();
1595     }
1596     HideSubwindowDragNode();
1597 
1598     if (transactionController) {
1599         auto transaction = transactionController->GetRSTransaction();
1600         InteractionInterface::GetInstance()->SetDragWindowVisible(false, transaction);
1601         pipeline->FlushUITasks();
1602         transactionController->CloseSyncTransaction();
1603     } else if (transactionHandler) {
1604         auto transaction = transactionHandler->GetRSTransaction();
1605         InteractionInterface::GetInstance()->SetDragWindowVisible(false, transaction);
1606         pipeline->FlushUITasks();
1607         transactionHandler->CloseSyncTransaction();
1608     } else {
1609         InteractionInterface::GetInstance()->SetDragWindowVisible(false);
1610         pipeline->FlushMessages();
1611     }
1612 #else
1613     event->ExecuteDropAnimation();
1614     auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1615     if (overlayManager) {
1616         overlayManager->RemoveDragPixelMap();
1617         overlayManager->RemoveFilter();
1618     }
1619     HideSubwindowDragNode();
1620     InteractionInterface::GetInstance()->SetDragWindowVisible(false);
1621     pipeline->FlushMessages();
1622 #endif
1623     InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1624 }
1625 
RequireSummary()1626 void DragDropManager::RequireSummary()
1627 {
1628     DragSummaryInfo dragSummaryInfo;
1629     int32_t ret =
1630         InteractionInterface::GetInstance()->GetDragSummary(dragSummaryInfo.summary, dragSummaryInfo.detailedSummary,
1631             dragSummaryInfo.summaryFormat, dragSummaryInfo.version, dragSummaryInfo.totalSize);
1632     if (ret != 0) {
1633         TAG_LOGI(AceLogTag::ACE_DRAG, "RequireSummary: Interaction GetSummary failed: %{public}d", ret);
1634     } else {
1635         std::string summarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.summary);
1636         std::string detailedSummarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.detailedSummary);
1637         TAG_LOGI(AceLogTag::ACE_DRAG, "require summary: %{public}s, detailedSummary:%{public}s", summarys.c_str(),
1638             detailedSummarys.c_str());
1639         DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1640     }
1641     std::string extraInfo;
1642     ret = InteractionInterface::GetInstance()->GetDragExtraInfo(extraInfo);
1643     if (ret != 0) {
1644         TAG_LOGI(AceLogTag::ACE_DRAG, "GetExtraInfo: Interaction GetExtraInfo failed: %{public}d", ret);
1645     }
1646     previewRect_ = Rect(-1, -1, -1, -1);
1647     extraInfo_ = extraInfo;
1648     summaryMap_ = dragSummaryInfo.summary;
1649     dragSummaryInfo_ = dragSummaryInfo;
1650 }
1651 
ResetRecordSize(uint32_t recordSize)1652 void DragDropManager::ResetRecordSize(uint32_t recordSize)
1653 {
1654     recordSize_ = recordSize;
1655 }
1656 
GetRecordSize() const1657 uint32_t DragDropManager::GetRecordSize() const
1658 {
1659     return recordSize_;
1660 }
1661 
GetDragWindowRect(const Point & point)1662 Rect DragDropManager::GetDragWindowRect(const Point& point)
1663 {
1664     if (!previewRect_.IsValid()) {
1665         ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1666         int ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1667         if (ret == 0) {
1668             previewRect_ = Rect(
1669                 shadowOffsetData.offsetX,
1670                 shadowOffsetData.offsetY,
1671                 shadowOffsetData.width,
1672                 shadowOffsetData.height);
1673         }
1674     }
1675     return previewRect_ + Offset(point.GetX(), point.GetY());
1676 }
1677 
ClearSummary()1678 void DragDropManager::ClearSummary()
1679 {
1680     previewRect_ = Rect(-1, -1, -1, -1);
1681     ResetPullId();
1682     ResetRecordSize();
1683 }
1684 
OnTextDragEnd(float globalX,float globalY,const std::string & extraInfo)1685 void DragDropManager::OnTextDragEnd(float globalX, float globalY, const std::string& extraInfo)
1686 {
1687     dragDropState_ = DragDropMgrState::IDLE;
1688     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1689     if (dragFrameNode) {
1690         auto textFieldPattern = dragFrameNode->GetPattern<TextFieldPattern>();
1691         if (textFieldPattern) {
1692             textFieldPattern->InsertValue(extraInfo);
1693         }
1694     }
1695     SetIsDragged(false);
1696     currentId_ = -1;
1697 }
1698 
onDragCancel()1699 void DragDropManager::onDragCancel()
1700 {
1701     preTargetFrameNode_ = nullptr;
1702     draggedFrameNode_ = nullptr;
1703 }
1704 
FireOnDragEventWithDragType(const RefPtr<EventHub> & eventHub,DragEventType type,RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1705 void DragDropManager::FireOnDragEventWithDragType(const RefPtr<EventHub>& eventHub, DragEventType type,
1706     RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1707 {
1708     switch (type) {
1709         case DragEventType::ENTER: {
1710             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_ENTER, event, extraParams);
1711             eventHub->FireOnDragEnter(event, extraParams);
1712             break;
1713         }
1714         case DragEventType::MOVE: {
1715             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_MOVE, event, extraParams);
1716             eventHub->FireOnDragMove(event, extraParams);
1717             break;
1718         }
1719         case DragEventType::LEAVE: {
1720             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, event, extraParams);
1721             eventHub->FireOnDragLeave(event, extraParams);
1722             break;
1723         }
1724         case DragEventType::DROP: {
1725             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1726             eventHub->HandleInternalOnDrop(event, extraParams);
1727             break;
1728         }
1729         default:
1730             break;
1731     }
1732 }
1733 
FireOnDragSpringLoadingEventWithDragType(const RefPtr<FrameNode> & frameNode,const RefPtr<EventHub> & eventHub,DragEventType type,const std::string & extraParams)1734 void DragDropManager::FireOnDragSpringLoadingEventWithDragType(const RefPtr<FrameNode>& frameNode,
1735     const RefPtr<EventHub>& eventHub, DragEventType type, const std::string& extraParams)
1736 {
1737     if (!eventHub->HasCustomerOnDragSpringLoading()) {
1738         return;
1739     }
1740     switch (type) {
1741         case DragEventType::ENTER:
1742         case DragEventType::MOVE: {
1743             NotifyDragSpringLoadingMove(frameNode, extraParams);
1744             break;
1745         }
1746         case DragEventType::LEAVE: {
1747             NotifyDragSpringLoadingIntercept(extraParams);
1748             break;
1749         }
1750         default:
1751             break;
1752     }
1753 }
1754 
FireOnDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type,const std::string & extraInfo)1755 void DragDropManager::FireOnDragEvent(
1756     const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent,
1757     DragEventType type, const std::string& extraInfo)
1758 {
1759     CHECK_NULL_VOID(frameNode);
1760     if (IsUIExtensionOrDynamicComponent(frameNode)) {
1761         HandleUIExtensionDragEvent(frameNode, pointerEvent, type);
1762         return;
1763     }
1764     auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
1765     CHECK_NULL_VOID(eventHub);
1766     if (!eventHub->HasOnDrop() && !eventHub->HasOnItemDrop() && !eventHub->HasCustomerOnDrop() &&
1767         !eventHub->HasCustomerOnDragSpringLoading()) {
1768         return;
1769     }
1770     auto point = pointerEvent.GetPoint();
1771     auto extraParams = eventHub->GetDragExtraParams(extraInfo_.empty() ? extraInfo : extraInfo_, point, type);
1772     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1773     CHECK_NULL_VOID(event);
1774     UpdateDragEvent(event, pointerEvent);
1775 
1776     FireOnEditableTextComponent(frameNode, type);
1777     FireOnDragSpringLoadingEventWithDragType(frameNode, eventHub, type, extraParams);
1778     FireOnDragEventWithDragType(eventHub, type, event, extraParams);
1779 
1780     UpdateDragCursorStyle(frameNode, event, pointerEvent.pointerEventId);
1781 }
1782 
UpdateDragCursorStyle(const RefPtr<FrameNode> & frameNode,const RefPtr<OHOS::Ace::DragEvent> & event,const int32_t eventId)1783 void DragDropManager::UpdateDragCursorStyle(const RefPtr<FrameNode>& frameNode,
1784     const RefPtr<OHOS::Ace::DragEvent>& event, const int32_t eventId)
1785 {
1786     if (event->GetResult() == DragRet::ENABLE_DROP) {
1787         if (event->GetDragBehavior() == DragBehavior::MOVE) {
1788             UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1789         } else {
1790             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
1791         }
1792     } else if (event->GetResult() == DragRet::DISABLE_DROP) {
1793         // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
1794         DragDropGlobalController::GetInstance().GetEnableDropDisallowedBadge()
1795             ? UpdateDragStyle(DragCursorStyleCore::FORBIDDEN, eventId)
1796             : UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1797     } else {
1798         UpdateDragAllowDrop(frameNode, event->GetDragBehavior(), eventId, event->IsCapi());
1799     }
1800 }
1801 
OnItemDragStart(float globalX,float globalY,const RefPtr<FrameNode> & frameNode)1802 void DragDropManager::OnItemDragStart(float globalX, float globalY, const RefPtr<FrameNode>& frameNode)
1803 {
1804     dragDropState_ = DragDropMgrState::DRAGGING;
1805     preGridTargetFrameNode_ = frameNode;
1806     draggedGridFrameNode_ = frameNode;
1807 }
1808 
OnItemDragMove(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1809 void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1810 {
1811     auto container = Container::Current();
1812     CHECK_NULL_VOID(container);
1813 
1814     UpdateItemDragPosition(globalX, globalY);
1815 
1816     OHOS::Ace::ItemDragInfo itemDragInfo;
1817     itemDragInfo.SetX(globalX);
1818     itemDragInfo.SetY(globalY);
1819 
1820     // use -1 for grid item not in eventGrid
1821     auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](
1822                                const RefPtr<FrameNode>& eventGrid) {
1823         return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex;
1824     };
1825 
1826     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1827     if (!dragFrameNode) {
1828         if (preGridTargetFrameNode_) {
1829             TAG_LOGI(AceLogTag::ACE_DRAG, "Not find drag target node, current windowId is %{public}d,"
1830                 "PreGridTargetFrameNode is %{public}s, depth is %{public}d.",
1831                 container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
1832                 preGridTargetFrameNode_->GetDepth());
1833             FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1834                 getDraggedIndex(preGridTargetFrameNode_));
1835             preGridTargetFrameNode_ = nullptr;
1836         }
1837         return;
1838     }
1839 
1840     if (dragFrameNode == preGridTargetFrameNode_) {
1841         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1842         FireOnItemDragEvent(
1843             dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex);
1844         return;
1845     }
1846 
1847     if (preGridTargetFrameNode_) {
1848         FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1849             getDraggedIndex(preGridTargetFrameNode_));
1850     }
1851 
1852     PrintGridDragFrameNode(globalX, globalY, dragFrameNode);
1853     FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode));
1854     preGridTargetFrameNode_ = dragFrameNode;
1855 }
1856 
GetWindowScale() const1857 float DragDropManager::GetWindowScale() const
1858 {
1859     float scale = 1.0f;
1860     auto container = Container::Current();
1861     CHECK_NULL_RETURN(container, scale);
1862     scale = container->GetWindowScale();
1863     return scale;
1864 }
1865 
OnItemDragEnd(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1866 void DragDropManager::OnItemDragEnd(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1867 {
1868     dragDropState_ = DragDropMgrState::IDLE;
1869     auto windowScale = isDragWindowSubWindow_ ? 1.0f : GetWindowScale();
1870     auto windowX = globalX * windowScale;
1871     auto windowY = globalY * windowScale;
1872 
1873     OHOS::Ace::ItemDragInfo itemDragInfo;
1874     itemDragInfo.SetX(windowX);
1875     itemDragInfo.SetY(windowY);
1876     auto dropPositionX = PipelineBase::Px2VpWithCurrentDensity(windowX);
1877     auto dropPositionY = PipelineBase::Px2VpWithCurrentDensity(windowY);
1878 
1879     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1880     if (!dragFrameNode) {
1881         // drag on one grid and drop on other area
1882         if (draggedGridFrameNode_) {
1883             if (dragType == DragType::GRID) {
1884                 auto eventHub = draggedGridFrameNode_->GetOrCreateEventHub<GridEventHub>();
1885                 CHECK_NULL_VOID(eventHub);
1886                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1887             } else {
1888                 auto eventHub = draggedGridFrameNode_->GetOrCreateEventHub<ListEventHub>();
1889                 CHECK_NULL_VOID(eventHub);
1890                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1891             }
1892             ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1893         }
1894     } else {
1895         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1896         // drag and drop on the same grid
1897         if (dragFrameNode == draggedGridFrameNode_) {
1898             ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1899             FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, draggedIndex, insertIndex, true);
1900         } else {
1901             // drag and drop on different grid
1902             ReportOnItemDropEvent(dragType, dragFrameNode, dropPositionX, dropPositionY);
1903             bool isSuccess = FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, -1, insertIndex, true);
1904             if (draggedGridFrameNode_) {
1905                 ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1906                 FireOnItemDropEvent(draggedGridFrameNode_, dragType, itemDragInfo, draggedIndex, -1, isSuccess);
1907             }
1908         }
1909     }
1910 
1911     preGridTargetFrameNode_ = nullptr;
1912     draggedGridFrameNode_ = nullptr;
1913 }
1914 
onItemDragCancel()1915 void DragDropManager::onItemDragCancel()
1916 {
1917     dragDropState_ = DragDropMgrState::IDLE;
1918     preGridTargetFrameNode_ = nullptr;
1919     draggedGridFrameNode_ = nullptr;
1920 }
1921 
FireOnItemDragEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,DragEventType type,int32_t draggedIndex,int32_t insertIndex)1922 void DragDropManager::FireOnItemDragEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1923     const OHOS::Ace::ItemDragInfo& itemDragInfo, DragEventType type, int32_t draggedIndex, int32_t insertIndex)
1924 {
1925     CHECK_NULL_VOID(frameNode);
1926     if (dragType == DragType::GRID) {
1927         auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1928         CHECK_NULL_VOID(eventHub);
1929         switch (type) {
1930             case DragEventType::ENTER:
1931                 eventHub->FireOnItemDragEnter(itemDragInfo);
1932                 break;
1933             case DragEventType::MOVE:
1934                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1935                 break;
1936             case DragEventType::LEAVE:
1937                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1938                 break;
1939             default:
1940                 break;
1941         }
1942     } else if (dragType == DragType::LIST) {
1943         auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1944         CHECK_NULL_VOID(eventHub);
1945         switch (type) {
1946             case DragEventType::ENTER:
1947                 eventHub->FireOnItemDragEnter(itemDragInfo);
1948                 break;
1949             case DragEventType::MOVE:
1950                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1951                 break;
1952             case DragEventType::LEAVE:
1953                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1954                 break;
1955             default:
1956                 break;
1957         }
1958     }
1959 }
1960 
FireOnItemDropEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,int32_t draggedIndex,int32_t insertIndex,bool isSuccess)1961 bool DragDropManager::FireOnItemDropEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1962     const OHOS::Ace::ItemDragInfo& itemDragInfo, int32_t draggedIndex, int32_t insertIndex, bool isSuccess)
1963 {
1964     CHECK_NULL_RETURN(frameNode, false);
1965     if (dragType == DragType::GRID) {
1966         auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1967         CHECK_NULL_RETURN(eventHub, false);
1968         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1969     } else if (dragType == DragType::LIST) {
1970         auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1971         CHECK_NULL_RETURN(eventHub, false);
1972         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1973     }
1974     return false;
1975 }
1976 
GetItemIndex(const RefPtr<FrameNode> & frameNode,DragType dragType,float globalX,float globalY)1977 int32_t DragDropManager::GetItemIndex(
1978     const RefPtr<FrameNode>& frameNode, DragType dragType, float globalX, float globalY)
1979 {
1980     CHECK_NULL_RETURN(frameNode, -1);
1981     if (dragType == DragType::GRID) {
1982         auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1983         CHECK_NULL_RETURN(eventHub, -1);
1984         if (frameNode != draggedGridFrameNode_) {
1985             return eventHub->GetInsertPosition(globalX, globalY);
1986         }
1987         auto itemFrameNode = frameNode->FindChildByPositionWithoutChildTransform(globalX, globalY);
1988         if (!itemFrameNode) {
1989             if (eventHub->CheckPostionInGrid(globalX, globalY)) {
1990                 return eventHub->GetFrameNodeChildSize();
1991             }
1992         } else {
1993             return eventHub->GetGridItemIndex(itemFrameNode);
1994         }
1995     } else if (dragType == DragType::LIST) {
1996         auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1997         CHECK_NULL_RETURN(eventHub, -1);
1998         return eventHub->GetListItemIndexByPosition(globalX, globalY);
1999     }
2000     return -1;
2001 }
2002 
AddDataToClipboard(const std::string & extraInfo)2003 void DragDropManager::AddDataToClipboard(const std::string& extraInfo)
2004 {
2005     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2006     CHECK_NULL_VOID(pipeline);
2007     if (!extraInfo.empty()) {
2008         if (!newData_) {
2009             newData_ = JsonUtil::Create(true);
2010             newData_->Put("customDragInfo", extraInfo.c_str());
2011         } else {
2012             newData_->Replace("customDragInfo", extraInfo.c_str());
2013         }
2014     } else {
2015         return;
2016     }
2017     if (!clipboard_) {
2018         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2019     }
2020     if (!addDataCallback_) {
2021         auto callback = [weakManager = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2022             ContainerScope scope(id);
2023             auto dragDropManager = weakManager.Upgrade();
2024             CHECK_NULL_VOID(dragDropManager);
2025             auto addData = dragDropManager->newData_->ToString();
2026             auto clipboardAllData = JsonUtil::Create(true);
2027             clipboardAllData->Put("preData", data.c_str());
2028             clipboardAllData->Put("newData", addData.c_str());
2029             dragDropManager->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
2030         };
2031         addDataCallback_ = callback;
2032     }
2033     if (clipboard_) {
2034         clipboard_->GetData(addDataCallback_, true);
2035     }
2036 }
2037 
GetExtraInfoFromClipboard(std::string & extraInfo)2038 void DragDropManager::GetExtraInfoFromClipboard(std::string& extraInfo)
2039 {
2040     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2041     CHECK_NULL_VOID(pipeline);
2042 
2043     if (!clipboard_) {
2044         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2045     }
2046 
2047     if (!getDataCallback_) {
2048         auto callback = [weak = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2049             ContainerScope scope(id);
2050             auto manager = weak.Upgrade();
2051             CHECK_NULL_VOID(manager);
2052             auto json = JsonUtil::ParseJsonString(data);
2053             auto newData = JsonUtil::ParseJsonString(json->GetString("newData"));
2054             manager->extraInfo_ = newData->GetString("customDragInfo");
2055         };
2056         getDataCallback_ = callback;
2057     }
2058 
2059     if (getDataCallback_ && clipboard_) {
2060         clipboard_->GetData(getDataCallback_, true);
2061     }
2062 
2063     extraInfo = extraInfo_;
2064 }
2065 
RestoreClipboardData()2066 void DragDropManager::RestoreClipboardData()
2067 {
2068     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2069     CHECK_NULL_VOID(pipeline);
2070 
2071     if (!clipboard_) {
2072         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2073     }
2074 
2075     if (!deleteDataCallback_) {
2076         auto callback = [weakManager = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2077             ContainerScope scope(id);
2078             auto dragDropManager = weakManager.Upgrade();
2079             CHECK_NULL_VOID(dragDropManager);
2080             auto json = JsonUtil::ParseJsonString(data);
2081             if (json->Contains("preData")) {
2082                 dragDropManager->clipboard_->SetData(json->GetString("preData"));
2083             }
2084         };
2085         deleteDataCallback_ = callback;
2086     }
2087     if (clipboard_) {
2088         clipboard_->GetData(deleteDataCallback_, true);
2089     }
2090 }
2091 
DestroyDragWindow()2092 void DragDropManager::DestroyDragWindow()
2093 {
2094     ResetRecordSize();
2095     if (itemDragOverlayNode_) {
2096         RemoveItemDrag();
2097         itemDragOverlayNode_ = nullptr;
2098     }
2099     SetIsDragged(false);
2100     SetIsDragWindowShow(false);
2101     previewRect_ = Rect(-1, -1, -1, -1);
2102     isMouseDragged_ = false;
2103     currentId_ = -1;
2104 }
2105 
CancelItemDrag()2106 void DragDropManager::CancelItemDrag()
2107 {
2108     if (draggedGridFrameNode_) {
2109         auto listEventHub = draggedGridFrameNode_->GetOrCreateEventHub<ListEventHub>();
2110         if (listEventHub) {
2111             listEventHub->HandleOnItemDragCancel();
2112             return;
2113         }
2114         auto gridEventHub = draggedGridFrameNode_->GetOrCreateEventHub<GridEventHub>();
2115         if (gridEventHub) {
2116             gridEventHub->HandleOnItemDragCancel();
2117             return;
2118         }
2119     }
2120 }
2121 
CreateFrameworkDragDropProxy()2122 RefPtr<DragDropProxy> DragDropManager::CreateFrameworkDragDropProxy()
2123 {
2124     SetIsDragged(true);
2125     isDragCancel_ = false;
2126     currentId_ = ++g_proxyId;
2127     return MakeRefPtr<DragDropProxy>(currentId_);
2128 }
2129 
UpdateNotifyDragEvent(RefPtr<NotifyDragEvent> & notifyEvent,const Point & point,const DragEventType dragEventType)2130 void DragDropManager::UpdateNotifyDragEvent(
2131     RefPtr<NotifyDragEvent>& notifyEvent, const Point& point, const DragEventType dragEventType)
2132 {
2133     CHECK_NULL_VOID(notifyEvent);
2134     notifyEvent->SetX((double)point.GetX());
2135     notifyEvent->SetY((double)point.GetY());
2136     notifyEvent->SetScreenX((double)point.GetScreenX());
2137     notifyEvent->SetScreenY((double)point.GetScreenY());
2138     notifyEvent->SetGlobalDisplayX(point.GetGlobalDisplayX());
2139     notifyEvent->SetGlobalDisplayY(point.GetGlobalDisplayY());
2140     if (dragEventType != DragEventType::START) {
2141         if (dragEventType != DragEventType::DROP) {
2142             notifyEvent->SetVelocity(velocityTracker_.GetVelocity());
2143         }
2144         notifyEvent->SetSummary(summaryMap_);
2145         notifyEvent->SetPreviewRect(GetDragWindowRect(point));
2146     }
2147 }
2148 
UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent> & event,const OHOS::Ace::DragPointerEvent & pointerEvent)2149 void DragDropManager::UpdateDragEvent(
2150     RefPtr<OHOS::Ace::DragEvent>& event, const OHOS::Ace::DragPointerEvent& pointerEvent)
2151 {
2152     auto point = pointerEvent.GetPoint();
2153     event->SetX(point.GetX());
2154     event->SetY(point.GetY());
2155     event->SetScreenX(point.GetScreenX());
2156     event->SetScreenY(point.GetScreenY());
2157     event->SetDisplayX((double)pointerEvent.GetDisplayX());
2158     event->SetDisplayY((double)pointerEvent.GetDisplayY());
2159     event->SetGlobalDisplayX(pointerEvent.GetGlobalDisplayX());
2160     event->SetGlobalDisplayY(pointerEvent.GetGlobalDisplayY());
2161     event->SetVelocity(velocityTracker_.GetVelocity());
2162     event->SetSummary(summaryMap_);
2163     event->SetPreviewRect(GetDragWindowRect(point));
2164     event->SetPressedKeyCodes(pointerEvent.pressedKeyCodes);
2165     event->SetSourceTool(pointerEvent.sourceTool);
2166     event->SetDragSource(dragBundleInfo_.bundleName);
2167     event->SetRemoteDev(dragBundleInfo_.isRemoteDev);
2168     event->SetDisplayId(pointerEvent.displayId);
2169 }
2170 
GetExtraInfo()2171 std::string DragDropManager::GetExtraInfo()
2172 {
2173     return extraInfo_;
2174 }
2175 
SetExtraInfo(const std::string & extraInfo)2176 void DragDropManager::SetExtraInfo(const std::string& extraInfo)
2177 {
2178     extraInfo_ = extraInfo;
2179 }
2180 
ClearExtraInfo()2181 void DragDropManager::ClearExtraInfo()
2182 {
2183     extraInfo_.clear();
2184 }
2185 
IsMSDPDragging() const2186 bool DragDropManager::IsMSDPDragging() const
2187 {
2188     ACE_SCOPED_TRACE("drag: get drag state from msdp");
2189     return InteractionInterface::GetInstance()->IsDragStart();
2190 }
2191 
ClearVelocityInfo()2192 void DragDropManager::ClearVelocityInfo()
2193 {
2194     velocityTracker_.Reset();
2195 }
2196 
UpdateVelocityTrackerPoint(const Point & point,bool isEnd)2197 void DragDropManager::UpdateVelocityTrackerPoint(const Point& point, bool isEnd)
2198 {
2199     std::chrono::microseconds microseconds(GetMicroTickCount());
2200     TimeStamp curTime(microseconds);
2201     velocityTracker_.UpdateTrackerPoint(point.GetX(), point.GetY(), curTime, isEnd);
2202 }
2203 
GetDragPreviewInfo(const RefPtr<OverlayManager> & overlayManager,DragPreviewInfo & dragPreviewInfo,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)2204 bool DragDropManager::GetDragPreviewInfo(const RefPtr<OverlayManager>& overlayManager, DragPreviewInfo& dragPreviewInfo,
2205     const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
2206 {
2207     CHECK_NULL_RETURN(overlayManager, false);
2208     if (!overlayManager->GetHasDragPixelMap()) {
2209         return false;
2210     }
2211     auto imageNode = overlayManager->GetDragPixelMapContentNode();
2212     CHECK_NULL_RETURN(imageNode, false);
2213     auto badgeNode = overlayManager->GetDragPixelMapBadgeNode();
2214     if (badgeNode) {
2215         dragPreviewInfo.relativeContainerNode = data.relativeContainerNode;
2216         dragPreviewInfo.textNode = badgeNode;
2217     }
2218     CHECK_NULL_RETURN(gestureHub, false);
2219     auto frameNode = gestureHub->GetFrameNode();
2220     CHECK_NULL_RETURN(frameNode, false);
2221     auto previewOption = imageNode->GetDragPreviewOption();
2222     auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
2223     CHECK_NULL_RETURN(gestureEvent, false);
2224     auto width = data.dragPreviewRect.Width();
2225     auto height = data.dragPreviewRect.Height();
2226     auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
2227     CHECK_NULL_RETURN(scaleData, false);
2228     dragPreviewInfo.scale =
2229         (imageNode->GetTag() != V2::WEB_ETS_TAG && width > 0 && height > 0 && previewOption.isScaleEnabled)
2230             ? scaleData->scale : 1.0f;
2231     if (!isMouseDragged_ && dragPreviewInfo.scale == 1.0f) {
2232         dragPreviewInfo.scale = TOUCH_DRAG_PIXELMAP_SCALE;
2233     }
2234     // set menu preview scale only for no scale menu preview.
2235     if (isDragWithContextMenu_ && (!previewOption.isScaleEnabled || !scaleData->isNeedScale)) {
2236         auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
2237         if (imageGestureEventHub) {
2238             auto menuPreviewScale = imageGestureEventHub->GetMenuPreviewScale();
2239             dragPreviewInfo.scale =
2240                 GreatNotEqual(menuPreviewScale, 0.0f) ? menuPreviewScale : TOUCH_DRAG_PIXELMAP_SCALE;
2241         }
2242     }
2243     dragPreviewInfo.height = static_cast<double>(height);
2244     dragPreviewInfo.width = static_cast<double>(width);
2245     dragPreviewInfo.maxWidth = scaleData->shortSide;
2246     dragPreviewInfo.imageNode = imageNode;
2247     dragPreviewInfo.originOffset = imageNode->GetPositionToWindowWithTransform();
2248     dragPreviewInfo.originScale = imageNode->GetTransformScale();
2249     dragPreviewInfo.isDragController = false;
2250     CopyPreparedInfoForDrag(dragPreviewInfo, data);
2251     return true;
2252 }
2253 
CopyPreparedInfoForDrag(DragPreviewInfo & dragPreviewInfo,PreparedInfoForDrag & data)2254 void DragDropManager::CopyPreparedInfoForDrag(DragPreviewInfo& dragPreviewInfo, PreparedInfoForDrag& data)
2255 {
2256     dragPreviewInfo.menuPreviewNode = data.menuPreviewNode;
2257     dragPreviewInfo.menuPreviewImageNode = data.menuPreviewImageNode;
2258     dragPreviewInfo.originPreviewRect = data.originPreviewRect;
2259     dragPreviewInfo.dragPreviewRect = data.dragPreviewRect;
2260     dragPreviewInfo.relativeContainerNode = data.relativeContainerNode;
2261     dragPreviewInfo.stackNode = data.stackNode;
2262     dragPreviewInfo.sizeChangeEffect = data.sizeChangeEffect;
2263     dragPreviewInfo.menuNode = data.menuNode;
2264 }
2265 
IsNeedDoDragMoveAnimate(const DragPointerEvent & pointerEvent)2266 bool DragDropManager::IsNeedDoDragMoveAnimate(const DragPointerEvent& pointerEvent)
2267 {
2268     if (isDragFwkShow_) {
2269         return false;
2270     }
2271     auto x = pointerEvent.GetPoint().GetX();
2272     auto y = pointerEvent.GetPoint().GetY();
2273     curPointerOffset_ = { x, y };
2274     return true;
2275 }
2276 
IsNeedScaleDragPreview()2277 bool DragDropManager::IsNeedScaleDragPreview()
2278 {
2279     return info_.scale > 0 && info_.scale < 1.0f;
2280 }
2281 // calculate the touch position relative to the sub-window which will be used to do animation on,
2282 // the input [x, y] is the position relative to the window which is receiving the touch event,
2283 // and the position is contain the floatTitle offset.
GetTouchOffsetRelativeToSubwindow(int32_t containerId,int32_t x,int32_t y)2284 OffsetF DragDropManager::GetTouchOffsetRelativeToSubwindow(int32_t containerId, int32_t x, int32_t y)
2285 {
2286     auto touchOffset = OffsetF(x, y);
2287     auto pipeline = PipelineContext::GetContextByContainerId(containerId);
2288     CHECK_NULL_RETURN(pipeline, OffsetF(x, y));
2289     auto window = pipeline->GetWindow();
2290     CHECK_NULL_RETURN(window, OffsetF(x, y));
2291     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
2292     touchOffset.SetX(touchOffset.GetX() + windowOffset.GetX());
2293     touchOffset.SetY(touchOffset.GetY() + windowOffset.GetY());
2294     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
2295         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
2296     CHECK_NULL_RETURN(subwindow, OffsetF(x, y));
2297     auto subwindowOffset = subwindow->GetWindowRect().GetOffset();
2298     touchOffset.SetX(touchOffset.GetX() - subwindowOffset.GetX());
2299     touchOffset.SetY(touchOffset.GetY() - subwindowOffset.GetY());
2300     return touchOffset;
2301 }
2302 
CalcDragPreviewDistanceWithPoint(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2303 double DragDropManager::CalcDragPreviewDistanceWithPoint(
2304     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2305 {
2306     CHECK_NULL_RETURN(info.imageNode, 0.0);
2307     auto nodeOffset = info.imageNode->GetTransformRelativeOffset();
2308     auto renderContext = info.imageNode->GetRenderContext();
2309     CHECK_NULL_RETURN(renderContext, 0.0);
2310     nodeOffset -= pixelMapOffset_;
2311     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2312     // calculate distance, so need to pow 2.
2313     return sqrt(pow(nodeOffset.GetX() - touchOffset.GetX(), 2) + pow(nodeOffset.GetY() - touchOffset.GetY(), 2));
2314 }
2315 
CalcDragMoveOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2316 Offset DragDropManager::CalcDragMoveOffset(
2317     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2318 {
2319     auto originPoint = info.originOffset;
2320     originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() +
2321         (info.originScale.x - info.scale) * info.width / 2.0f);
2322     originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY() +
2323         (info.originScale.y - info.scale) * info.height / 2.0f);
2324     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2325     Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2326     return newOffset;
2327 }
2328 
CalcContentTrationOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2329 Offset DragDropManager::CalcContentTrationOffset(
2330     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2331 {
2332     auto originPoint = info.originOffset;
2333     auto scalX = info.dragPreviewRect.Width() / info.originPreviewRect.Width() * info.scale;
2334     originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() + info.originPreviewRect.Width() * (1 - scalX));
2335     originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY());
2336     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2337     Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2338     return newOffset;
2339 }
2340 
CalculateNewOffset(const RefPtr<FrameNode> & frameNode,const GestureEvent & event,bool isDragStartPending)2341 Offset DragDropManager::CalculateNewOffset(
2342     const RefPtr<FrameNode>& frameNode, const GestureEvent& event, bool isDragStartPending)
2343 {
2344     Offset newOffset = { 0, 0 };
2345     CHECK_NULL_RETURN(frameNode, newOffset);
2346     auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2347     if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && !info_.textNode) {
2348         newOffset =
2349             isDragStartPending
2350                 ? CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2351                     static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2352                 : CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2353                     static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2354     } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2355                info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION || info_.textNode) {
2356         newOffset =
2357             isDragStartPending
2358                 ? CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2359                     static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2360                 : CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2361                     static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2362     }
2363     return newOffset;
2364 }
2365 
UpdateDragMovePositionFinished(bool needDoDragMoveAnimate,bool isMenuShow,const Offset & newOffset,int32_t containerId)2366 bool DragDropManager::UpdateDragMovePositionFinished(
2367     bool needDoDragMoveAnimate, bool isMenuShow, const Offset& newOffset, int32_t containerId)
2368 {
2369     if (!isDragWithContextMenu_) {
2370         return false;
2371     }
2372 
2373     CHECK_NULL_RETURN(info_.imageNode, false);
2374     auto renderContext = info_.imageNode->GetRenderContext();
2375     CHECK_NULL_RETURN(renderContext, false);
2376     SubwindowManager::GetInstance()->ContextMenuSwitchDragPreviewAnimation(info_.imageNode,
2377         OffsetF(newOffset.GetX(), newOffset.GetY()));
2378     if (!needDoDragMoveAnimate) {
2379         renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2380         if (!isMenuShow) {
2381             TransDragWindowToDragFwk(containerId);
2382         }
2383         return true;
2384     }
2385     return false;
2386 }
2387 
GetCurrentDistance(float x,float y)2388 float DragDropManager::GetCurrentDistance(float x, float y)
2389 {
2390     auto distance = sqrt(pow(curPointerOffset_.GetX() - x, 2) + pow(curPointerOffset_.GetY() - y, 2));
2391     CHECK_NULL_RETURN(info_.imageNode, distance);
2392     auto containerId = Container::CurrentId();
2393     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
2394     CHECK_NULL_RETURN(subwindow, distance);
2395     auto overlayManager = subwindow->GetOverlayManager();
2396     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(info_.imageNode);
2397     auto gatherDistance = CalcGatherNodeMaxDistanceWithPoint(overlayManager,
2398         gatherNodeCenter.GetX(), gatherNodeCenter.GetY());
2399     return std::max(distance, gatherDistance);
2400 }
2401 
DoDragMoveAnimate(const DragPointerEvent & pointerEvent)2402 void DragDropManager::DoDragMoveAnimate(const DragPointerEvent& pointerEvent)
2403 {
2404     bool needDoDragMoveAnimate = IsNeedDoDragMoveAnimate(pointerEvent);
2405     if (!needDoDragMoveAnimate) {
2406         return;
2407     }
2408     isPullMoveReceivedForCurrentDrag_ = true;
2409     CHECK_NULL_VOID(info_.imageNode);
2410     auto containerId = Container::CurrentId();
2411     auto x = pointerEvent.GetDisplayX();
2412     auto y = pointerEvent.GetDisplayY();
2413     if (CheckIsUIExtensionBoundary(x, y, containerId) || CheckIsFolderSubwindowBoundary(x, y, containerId)) {
2414         SetStartAnimation(false);
2415         TransDragWindowToDragFwk(containerId);
2416         return;
2417     }
2418     auto overlayManager = GetDragAnimationOverlayManager(containerId);
2419     CHECK_NULL_VOID(overlayManager);
2420     auto point = pointerEvent.GetPoint();
2421     Offset newOffset = { 0, 0 };
2422     if ((info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && !info_.textNode) || info_.isDragController) {
2423         newOffset = CalcDragMoveOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2424     } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2425                info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION || info_.textNode) {
2426         newOffset = CalcContentTrationOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2427     }
2428     bool isMenuShow = overlayManager->IsMenuShow();
2429     if (UpdateDragMovePositionFinished(needDoDragMoveAnimate, isMenuShow, newOffset, containerId) ||
2430         !needDoDragMoveAnimate) {
2431         return;
2432     }
2433     DragMoveAnimation(newOffset, overlayManager, point);
2434 }
2435 
DragMoveAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,Point point)2436 void DragDropManager::DragMoveAnimation(
2437     const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager, Point point)
2438 {
2439     auto containerId = Container::CurrentId();
2440     bool isMenuShow = overlayManager->IsMenuShow();
2441     AnimationOption option;
2442     auto springResponse =
2443         std::max(DEFAULT_SPRING_RESPONSE - DEL_SPRING_RESPONSE * allAnimationCnt_, MIN_SPRING_RESPONSE);
2444     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(springResponse, 0.99f, 0.0f);
2445     constexpr int32_t animateDuration = 30;
2446     option.SetCurve(curve);
2447     option.SetDuration(animateDuration);
2448     bool dragWithContextMenu = isDragWithContextMenu_;
2449     AddNewDragAnimation();
2450     option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId, dragWithContextMenu, isMenuShow,
2451                                 x = point.GetX(), y = point.GetY()]() {
2452         auto dragDropManager = weakManager.Upgrade();
2453         CHECK_NULL_VOID(dragDropManager);
2454         if ((dragDropManager->IsAllAnimationFinished() ||
2455                 dragDropManager->GetCurrentDistance(x, y) < MAX_DISTANCE_TO_PRE_POINTER) &&
2456             (!dragWithContextMenu || !isMenuShow) && dragDropManager->IsStartAnimationFInished()) {
2457             dragDropManager->SetStartAnimation(false);
2458             dragDropManager->TransDragWindowToDragFwk(containerId);
2459         }
2460     });
2461 
2462     if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
2463         DragDropManager::DragMoveDefaultAnimation(overlayManager, info_, option, newOffset, point);
2464     } else if ((info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2465                    info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION)) {
2466         DragDropManager::DragMoveTransitionAnimation(overlayManager, info_, option, newOffset, point);
2467     }
2468 }
2469 
DragMoveDefaultAnimation(const RefPtr<OverlayManager> & overlayManager,const DragPreviewInfo & info,AnimationOption option,const Offset & newOffset,Point point)2470 void DragDropManager::DragMoveDefaultAnimation(const RefPtr<OverlayManager>& overlayManager,
2471     const DragPreviewInfo& info, AnimationOption option, const Offset& newOffset, Point point)
2472 {
2473     auto targetNode = info_.textNode && info_.relativeContainerNode ? info_.relativeContainerNode : info_.imageNode;
2474     CHECK_NULL_VOID(targetNode);
2475     auto renderContext = targetNode->GetRenderContext();
2476     CHECK_NULL_VOID(renderContext);
2477     auto context = targetNode->GetContextRefPtr();
2478     CHECK_NULL_VOID(context);
2479     auto offset = OffsetF(point.GetX(), point.GetY());
2480     auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2481     auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2482     auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2483     AnimationUtils::Animate(
2484         option,
2485         [renderContext, localPoint = newOffset, info = info_, overlayManager, menuRenderContext, menuPosition]() {
2486             if (menuRenderContext && !menuPosition.NonOffset()) {
2487                 menuRenderContext->UpdatePosition(
2488                     OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2489             }
2490             renderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2491             if (info.isDragController) {
2492                 UpdateTextNodePosition(info.textNode, localPoint);
2493             }
2494             UpdateGatherNodePosition(overlayManager, info.imageNode);
2495         },
2496         option.GetOnFinishEvent(), nullptr, context);
2497 }
2498 
DragMoveTransitionAnimation(const RefPtr<OverlayManager> & overlayManager,const DragPreviewInfo & info,AnimationOption option,const Offset & newOffset,Point point)2499 void DragDropManager::DragMoveTransitionAnimation(const RefPtr<OverlayManager>& overlayManager,
2500     const DragPreviewInfo& info, AnimationOption option, const Offset& newOffset, Point point)
2501 {
2502     option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2503     auto renderContext = info_.imageNode->GetRenderContext();
2504     CHECK_NULL_VOID(renderContext);
2505     auto offset = OffsetF(point.GetX(), point.GetY());
2506     auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2507     CHECK_NULL_VOID(overlayManager);
2508     auto context = info_.imageNode->GetContextRefPtr();
2509     CHECK_NULL_VOID(context);
2510     auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2511     auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2512     AnimationUtils::Animate(
2513         option,
2514         [overlayManager, info, newOffset, menuRenderContext, menuPosition]() {
2515             if (menuRenderContext && !menuPosition.NonOffset() && !info.menuNode) {
2516                 menuRenderContext->UpdatePosition(
2517                     OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2518             }
2519             CHECK_NULL_VOID(overlayManager);
2520             auto relativeContainerNodeRenderContext = info.relativeContainerNode->GetRenderContext();
2521             CHECK_NULL_VOID(relativeContainerNodeRenderContext);
2522             relativeContainerNodeRenderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2523             UpdateGatherNodePosition(overlayManager, info.imageNode);
2524         },
2525         option.GetOnFinishEvent(), nullptr, context);
2526 }
2527 
UpdateDragPreviewScale()2528 void DragDropManager::UpdateDragPreviewScale()
2529 {
2530     CHECK_NULL_VOID(info_.imageNode);
2531     if (IsNeedDisplayInSubwindow()) {
2532         return;
2533     }
2534     auto renderContext = info_.imageNode->GetRenderContext();
2535     CHECK_NULL_VOID(renderContext);
2536     renderContext->UpdateTransformScale({ info_.scale, info_.scale });
2537 }
2538 
InitDragAnimationPointerEvent(const GestureEvent & event,bool isDragStartPending)2539 void DragDropManager::InitDragAnimationPointerEvent(const GestureEvent& event, bool isDragStartPending)
2540 {
2541     if (isDragStartPending) {
2542         auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2543         dragAnimationPointerEvent_ = DragPointerEvent(dragMoveLastPoint.GetX(),
2544             dragMoveLastPoint.GetY(), dragMoveLastPoint.GetScreenX(), dragMoveLastPoint.GetScreenY(),
2545             dragMoveLastPoint.GetGlobalDisplayX(), dragMoveLastPoint.GetGlobalDisplayY());
2546         return;
2547     }
2548     dragAnimationPointerEvent_ = DragPointerEvent(event.GetGlobalLocation().GetX(),
2549         event.GetGlobalLocation().GetY(), event.GetScreenLocation().GetX(), event.GetScreenLocation().GetY(),
2550         event.GetGlobalDisplayLocation().GetX(), event.GetGlobalDisplayLocation().GetY());
2551 }
2552 
DoDragStartAnimation(const RefPtr<OverlayManager> & overlayManager,const GestureEvent & event,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)2553 void DragDropManager::DoDragStartAnimation(const RefPtr<OverlayManager>& overlayManager, const GestureEvent& event,
2554     const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
2555 {
2556     auto containerId = Container::CurrentId();
2557     auto deviceId = static_cast<int32_t>(event.GetDeviceId());
2558     if (deviceId == RESERVED_DEVICEID_1 || deviceId == RESERVED_DEVICEID_2) {
2559         isDragFwkShow_ = false;
2560         TAG_LOGI(AceLogTag::ACE_DRAG, "Do not need animation.");
2561         TransDragWindowToDragFwk(containerId);
2562         return;
2563     }
2564     CHECK_NULL_VOID(overlayManager);
2565     CHECK_NULL_VOID(gestureHub);
2566     bool isDragStartPending = DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr;
2567     if (!(GetDragPreviewInfo(overlayManager, info_, gestureHub, data)) ||
2568         (!IsNeedDisplayInSubwindow() && !data.isMenuShow && !isDragWithContextMenu_ && !isDragStartPending)) {
2569         if (isDragWithContextMenu_) {
2570             UpdateDragPreviewScale();
2571             isDragFwkShow_ = false;
2572         }
2573         return;
2574     }
2575     CHECK_NULL_VOID(info_.imageNode);
2576     isDragFwkShow_ = false;
2577     subwindowOverlayManager_ = overlayManager;
2578     InitDragAnimationPointerEvent(event, isDragStartPending);
2579     ResetPullMoveReceivedForCurrentDrag();
2580     Point point = { static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2581         static_cast<int32_t>(event.GetGlobalLocation().GetY()) };
2582     auto frameNode = gestureHub->GetFrameNode();
2583     Offset newOffset = CalculateNewOffset(frameNode, event, isDragStartPending);
2584     curPointerOffset_ = { newOffset.GetX(), newOffset.GetY() };
2585     currentAnimationCnt_ = 0;
2586     allAnimationCnt_ = 0;
2587     isStartAnimationFinished_ = false;
2588     DragStartAnimation(newOffset, overlayManager, data, point);
2589 }
2590 
DragStartAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,PreparedInfoForDrag & data,Point point)2591 void DragDropManager::DragStartAnimation(
2592     const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager, PreparedInfoForDrag& data, Point point)
2593 {
2594     CHECK_NULL_VOID(info_.imageNode);
2595     auto containerId = Container::CurrentId();
2596     AnimationOption option;
2597     SetDragStartAnimationOption(option, containerId);
2598     AddNewDragStartAnimation();
2599     auto renderContext = info_.imageNode->GetRenderContext();
2600     CHECK_NULL_VOID(renderContext);
2601     auto callback = [weakManager = WeakClaim(this)](float rate) {
2602         auto dragDropManager = weakManager.Upgrade();
2603         CHECK_NULL_VOID(dragDropManager);
2604         dragDropManager->SetDragStartAnimationRate(rate);
2605     };
2606     auto animateProperty = AceType::MakeRefPtr<NodeAnimatablePropertyFloat>(-1.0, std::move(callback));
2607     CHECK_NULL_VOID(animateProperty);
2608     renderContext->AttachNodeAnimatableProperty(animateProperty);
2609     animateProperty->Set(0.0f);
2610     dragStartAnimationRate_ = 0.0f;
2611     if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
2612         //Default transition
2613         StartDragDefaultAnimation(option, newOffset, overlayManager, animateProperty, point);
2614     } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2615                info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) {
2616         StartDragTransitionAnimation(newOffset, option, overlayManager, animateProperty, point);
2617     }
2618 }
2619 
SetDragStartAnimationOption(AnimationOption & option,int32_t containerId)2620 void DragDropManager::SetDragStartAnimationOption(AnimationOption& option, int32_t containerId)
2621 {
2622     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
2623     constexpr int32_t animateDuration = 300;
2624     option.SetCurve(curve);
2625     option.SetDuration(animateDuration);
2626     option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId]() {
2627         auto dragDropManager = weakManager.Upgrade();
2628         CHECK_NULL_VOID(dragDropManager);
2629         dragDropManager->HandleStartDragAnimationFinish(containerId);
2630     });
2631 }
2632 
HandleStartDragAnimationFinish(int32_t containerId)2633 void DragDropManager::HandleStartDragAnimationFinish(int32_t containerId)
2634 {
2635     if (IsAllStartAnimationFinished()) {
2636         SetStartAnimation(true);
2637     }
2638     if (!IsPullMoveReceivedForCurrentDrag()) {
2639         TransDragWindowToDragFwk(containerId);
2640     }
2641     auto overlayManager = GetDragAnimationOverlayManager(containerId);
2642     CHECK_NULL_VOID(overlayManager);
2643     auto gatherNode = overlayManager->GetGatherNode();
2644     CHECK_NULL_VOID(gatherNode);
2645     auto info = overlayManager->GetGatherNodeChildrenInfo();
2646     int cnt = 0;
2647     for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2648         auto imageNode = (*iter).imageNode.Upgrade();
2649         if (cnt > 1) {
2650             gatherNode->RemoveChild(imageNode);
2651         }
2652         cnt++;
2653     }
2654 }
2655 
StartDragDefaultAnimation(AnimationOption option,const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,const RefPtr<NodeAnimatablePropertyFloat> & animateProperty,Point point)2656 void DragDropManager::StartDragDefaultAnimation(AnimationOption option, const Offset& newOffset,
2657     const RefPtr<OverlayManager>& overlayManager, const RefPtr<NodeAnimatablePropertyFloat>& animateProperty,
2658     Point point)
2659 {
2660     auto renderContext = info_.imageNode->GetRenderContext();
2661     CHECK_NULL_VOID(renderContext);
2662     auto context = info_.imageNode->GetContextRefPtr();
2663     CHECK_NULL_VOID(context);
2664     auto animateCallback = [renderContext, info = info_, newOffset, overlayManager, animateProperty, point]() {
2665         CHECK_NULL_VOID(renderContext);
2666         DragAnimationHelper::UpdateStartAnimation(overlayManager, animateProperty, point, info, newOffset);
2667         if (!info.textNode) {
2668             CHECK_NULL_VOID(renderContext);
2669             renderContext->UpdateTransformScale({ info.scale, info.scale });
2670             renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2671             return;
2672         }
2673         CHECK_NULL_VOID(info.imageNode);
2674         auto imageLayoutProperty = info.imageNode->GetLayoutProperty();
2675         CHECK_NULL_VOID(imageLayoutProperty);
2676         imageLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(info.width * info.scale, DimensionUnit::PX),
2677             CalcLength(info.height * info.scale, DimensionUnit::PX) });
2678         info.relativeContainerNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2679     };
2680     if (info_.textNode) {
2681         option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2682         auto pipeline = info_.relativeContainerNode->GetContext();
2683         CHECK_NULL_VOID(pipeline);
2684         pipeline->Animate(option, option.GetCurve(), animateCallback, option.GetOnFinishEvent());
2685     } else {
2686         AnimationUtils::Animate(option, animateCallback, option.GetOnFinishEvent(), nullptr, context);
2687     }
2688 }
2689 
StartDragTransitionAnimation(const Offset & newOffset,AnimationOption option,const RefPtr<OverlayManager> & overlayManager,const RefPtr<NodeAnimatablePropertyFloat> & animateProperty,Point point)2690 void DragDropManager::StartDragTransitionAnimation(const Offset& newOffset, AnimationOption option,
2691     const RefPtr<OverlayManager>& overlayManager, const RefPtr<NodeAnimatablePropertyFloat>& animateProperty,
2692     Point point)
2693 {
2694     CHECK_NULL_VOID(info_.imageNode);
2695     option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2696     auto callback = [relativeContainerNode = info_.relativeContainerNode, newOffset, info = info_, overlayManager,
2697                         animateProperty, point]() {
2698         DragAnimationHelper::UpdateStartAnimation(overlayManager, animateProperty, point, info, newOffset);
2699         CHECK_NULL_VOID(info.stackNode);
2700         auto stackLayoutProperty = info.stackNode->GetLayoutProperty();
2701         CHECK_NULL_VOID(stackLayoutProperty);
2702         stackLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(info.width * info.scale, DimensionUnit::PX),
2703             CalcLength(info.height * info.scale, DimensionUnit::PX) });
2704         auto stackContext = info.stackNode->GetContext();
2705         CHECK_NULL_VOID(stackContext);
2706         info.stackNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2707     };
2708     auto pipeline = info_.relativeContainerNode->GetContext();
2709     CHECK_NULL_VOID(pipeline);
2710     pipeline->Animate(option, option.GetCurve(), callback, option.GetOnFinishEvent());
2711 }
2712 
NotifyEnterTextEditorArea()2713 void DragDropManager::NotifyEnterTextEditorArea()
2714 {
2715     auto ret = InteractionInterface::GetInstance()->EnterTextEditorArea(true);
2716     if (ret != 0) {
2717         TAG_LOGW(AceLogTag::ACE_DRAG, "Fail to notify entering text editor erea.");
2718         return;
2719     }
2720 
2721     hasNotifiedTransformation_ = true;
2722 }
2723 
FireOnEditableTextComponent(const RefPtr<FrameNode> & frameNode,DragEventType type)2724 void DragDropManager::FireOnEditableTextComponent(const RefPtr<FrameNode>& frameNode,
2725     DragEventType type)
2726 {
2727     CHECK_NULL_VOID(frameNode);
2728     auto frameTag = frameNode->GetTag();
2729     auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
2730     if (!IsEditableTextComponent(frameTag) || !(eventHub && eventHub->IsEnabled()) || !isDragFwkShow_) {
2731         return;
2732     }
2733 
2734     // When moving in an editable text component whithout animation, and has not notified msdp yet, notify msdp.
2735     if (type == DragEventType::MOVE && IsEditableTextComponent(frameTag) && isDragFwkShow_ &&
2736         !hasNotifiedTransformation_) {
2737         NotifyEnterTextEditorArea();
2738         return;
2739     }
2740     if (type != DragEventType::ENTER && type != DragEventType::LEAVE) {
2741         TAG_LOGD(AceLogTag::ACE_DRAG, "It is an invalid drag type %{public}d", type);
2742         return;
2743     }
2744 
2745     if (type == DragEventType::LEAVE) {
2746         TAG_LOGI(AceLogTag::ACE_DRAG, "The current control has been dragged away.");
2747         hasNotifiedTransformation_ = false;
2748         return;
2749     }
2750 
2751     if (hasNotifiedTransformation_) {
2752         TAG_LOGI(AceLogTag::ACE_DRAG, "Coordinates have been transformed.");
2753         return;
2754     }
2755 
2756     NotifyEnterTextEditorArea();
2757 }
2758 
SetDragResult(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2759 void DragDropManager::SetDragResult(
2760     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2761 {
2762     DragRet result = DragRet::DRAG_FAIL;
2763     switch (notifyMessage.result) {
2764         case DragRet::DRAG_SUCCESS:
2765             result = DragRet::DRAG_SUCCESS;
2766             break;
2767         case DragRet::DRAG_FAIL:
2768             result = DragRet::DRAG_FAIL;
2769             break;
2770         case DragRet::DRAG_CANCEL:
2771             result = DragRet::DRAG_CANCEL;
2772             break;
2773         default:
2774             break;
2775     }
2776     CHECK_NULL_VOID(dragEvent);
2777     dragEvent->SetResult(result);
2778 }
2779 
SetDragBehavior(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2780 void DragDropManager::SetDragBehavior(
2781     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2782 {
2783     DragBehavior dragBehavior = DragBehavior::UNKNOWN;
2784     switch (notifyMessage.dragBehavior) {
2785         case DragBehavior::COPY:
2786             dragBehavior = DragBehavior::COPY;
2787             break;
2788         case DragBehavior::MOVE:
2789             dragBehavior = DragBehavior::MOVE;
2790             break;
2791         default:
2792             break;
2793     }
2794     CHECK_NULL_VOID(dragEvent);
2795     dragEvent->SetDragBehavior(dragBehavior);
2796 }
2797 
UpdateGatherNodeAttr(const RefPtr<OverlayManager> & overlayManager,const GatherAnimationInfo & info)2798 void DragDropManager::UpdateGatherNodeAttr(const RefPtr<OverlayManager>& overlayManager,
2799     const GatherAnimationInfo& info)
2800 {
2801     CHECK_NULL_VOID(overlayManager);
2802     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2803     BorderRadiusProperty borderRadius;
2804     if (info.borderRadius.has_value()) {
2805         borderRadius = info.borderRadius.value();
2806     }
2807     borderRadius.multiValued = false;
2808     int32_t cnt = static_cast<int>(gatherNodeChildrenInfo.size());
2809     auto scale = info.scale <= 0.0f ? 1.0f : info.scale;
2810     std::vector<std::pair<float, float>> props(cnt, { 0.0, 0.0 });
2811     if (cnt > 0) {
2812         props[cnt - FIRST_GATHER_PIXEL_MAP] = { FIRST_PIXELMAP_ANGLE, FIRST_PIXELMAP_OPACITY };
2813     }
2814     if (cnt > 1) {
2815         props[cnt - SECOND_GATHER_PIXEL_MAP] = { SECOND_PIXELMAP_ANGLE, SECOND_PIXELMAP_OPACITY };
2816     }
2817     for (int32_t i = 0; i < cnt; ++i) {
2818         auto imageNode = gatherNodeChildrenInfo[i].imageNode.Upgrade();
2819         CHECK_NULL_VOID(imageNode);
2820         auto imageContext = imageNode->GetRenderContext();
2821         CHECK_NULL_VOID(imageContext);
2822         auto& childInfo = gatherNodeChildrenInfo[i];
2823         auto updateScale = scale;
2824         if (((childInfo.width > info.width) || (childInfo.height > info.height)) &&
2825             !NearZero(childInfo.width) && !NearZero(childInfo.height)) {
2826             updateScale *= std::min(info.width / childInfo.width, info.height / childInfo.height);
2827         }
2828         imageContext->UpdateTransformScale({ updateScale, updateScale });
2829         imageContext->UpdateBorderRadius(borderRadius);
2830         imageContext->UpdateOpacity(props[i].second);
2831         Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, props[i].first, 0.0f);
2832         imageContext->UpdateTransformRotate(rotate);
2833     }
2834 }
2835 
UpdateGatherNodePosition(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & imageNode)2836 void DragDropManager::UpdateGatherNodePosition(const RefPtr<OverlayManager>& overlayManager,
2837     const RefPtr<FrameNode>& imageNode)
2838 {
2839     CHECK_NULL_VOID(imageNode);
2840     CHECK_NULL_VOID(overlayManager);
2841     auto gatherNode = overlayManager->GetGatherNode();
2842     CHECK_NULL_VOID(gatherNode);
2843     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenterToScreen(imageNode);
2844     gatherNodeCenter -= DragDropFuncWrapper::GetCurrentWindowOffset(gatherNode->GetContextRefPtr());
2845     OffsetF offset;
2846     auto info = overlayManager->GetGatherNodeChildrenInfo();
2847     for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2848         auto& child = (*iter);
2849         auto imageNode = child.imageNode.Upgrade();
2850         CHECK_NULL_VOID(imageNode);
2851         offset.SetX(gatherNodeCenter.GetX() - child.halfWidth);
2852         offset.SetY(gatherNodeCenter.GetY() - child.halfHeight);
2853         DragDropFuncWrapper::UpdateNodePositionToWindow(imageNode, offset);
2854     }
2855 }
2856 
UpdateTextNodePosition(const RefPtr<FrameNode> & textNode,const Offset & localPoint)2857 void DragDropManager::UpdateTextNodePosition(const RefPtr<FrameNode>& textNode, const Offset& localPoint)
2858 {
2859     CHECK_NULL_VOID(textNode);
2860     auto textRenderContext = textNode->GetRenderContext();
2861     CHECK_NULL_VOID(textRenderContext);
2862     textRenderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2863 }
2864 
CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager> & overlayManager,int32_t x,int32_t y)2865 double DragDropManager::CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager>& overlayManager,
2866     int32_t x, int32_t y)
2867 {
2868     CHECK_NULL_RETURN(overlayManager, 0.0f);
2869     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2870     double maxDistance = 0.0;
2871     for (const auto& child : gatherNodeChildrenInfo) {
2872         auto imageNode = child.imageNode.Upgrade();
2873         CHECK_NULL_RETURN(imageNode, 0.0f);
2874         auto imageContext = imageNode->GetRenderContext();
2875         CHECK_NULL_RETURN(imageContext, 0.0f);
2876         auto renderPosition = imageContext->GetPropertyOfPosition();
2877         double dis = sqrt(pow(renderPosition.GetX() + child.halfWidth - x, SQUARE_NUMBER) +
2878             pow(renderPosition.GetY() + child.halfHeight - y, SQUARE_NUMBER));
2879         maxDistance = std::max(maxDistance, dis);
2880     }
2881     return maxDistance;
2882 }
2883 
IsNeedDisplayInSubwindow()2884 bool DragDropManager::IsNeedDisplayInSubwindow()
2885 {
2886     if (IsNeedScaleDragPreview()) {
2887         return true;
2888     }
2889     auto overlayManager = GetDragAnimationOverlayManager(Container::CurrentId());
2890     CHECK_NULL_RETURN(overlayManager, false);
2891     auto gatherNode = overlayManager->GetGatherNode();
2892     return gatherNode != nullptr;
2893 }
2894 
PushGatherPixelMap(const RefPtr<PixelMap> & pixelMap)2895 void DragDropManager::PushGatherPixelMap(const RefPtr<PixelMap>& pixelMap)
2896 {
2897     gatherPixelMaps_.push_back(pixelMap);
2898 }
2899 
GetGatherPixelMap(DragDataCore & dragData,float scale,float previewWidth,float previewHeight)2900 void DragDropManager::GetGatherPixelMap(
2901     DragDataCore& dragData, float scale, float previewWidth, float previewHeight)
2902 {
2903     for (const auto& gatherPixelMap : gatherPixelMaps_) {
2904         RefPtr<PixelMap> pixelMapDuplicated = gatherPixelMap;
2905 #if defined(PIXEL_MAP_SUPPORTED)
2906         pixelMapDuplicated = PixelMap::CopyPixelMap(gatherPixelMap);
2907         if (!pixelMapDuplicated) {
2908             TAG_LOGW(AceLogTag::ACE_DRAG, "copy pixelMap failed!");
2909             pixelMapDuplicated = gatherPixelMap;
2910         }
2911 #endif
2912         if (!pixelMapDuplicated) {
2913             TAG_LOGW(AceLogTag::ACE_DRAG, "skip null pixelMap.");
2914             continue;
2915         }
2916         auto width = pixelMapDuplicated->GetWidth() * scale;
2917         auto height = pixelMapDuplicated->GetHeight() * scale;
2918         auto updateScale = scale;
2919         if (((width > previewWidth) || (height > previewHeight)) && !NearZero(width) && !NearZero(height)) {
2920             updateScale *= std::min(previewWidth / width, previewHeight / height);
2921         }
2922         pixelMapDuplicated->Scale(updateScale, updateScale, AceAntiAliasingOption::HIGH);
2923         dragData.shadowInfos.push_back({pixelMapDuplicated, 0.0f, 0.0f});
2924     }
2925     gatherPixelMaps_.clear();
2926     return;
2927 }
2928 
ResetDragDrop(int32_t windowId,const Point & point)2929 void DragDropManager::ResetDragDrop(int32_t windowId, const Point& point)
2930 {
2931     DragDropRet dragDropRet { DragRet::DRAG_FAIL, isMouseDragged_, windowId, DragBehavior::UNKNOWN };
2932     HideDragPreviewOverlay();
2933     ClearVelocityInfo();
2934     ResetDragDropStatus(point, dragDropRet, windowId);
2935     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
2936 }
2937 
FireOnDragLeave(const RefPtr<FrameNode> & preTargetFrameNode,const DragPointerEvent & pointerEvent,const std::string & extraInfo)2938 void DragDropManager::FireOnDragLeave(
2939     const RefPtr<FrameNode>& preTargetFrameNode, const DragPointerEvent& pointerEvent, const std::string& extraInfo)
2940 {
2941     auto point = pointerEvent.GetPoint();
2942     if (preTargetFrameNode) {
2943         auto preRect = preTargetFrameNode->GetTransformRectRelativeToWindow();
2944         // If the point is out of the pre node, it means we are totally inside a new node, notify leave anyway
2945         if (!preRect.IsInnerRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
2946             FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
2947             return;
2948         }
2949 
2950         // If reach here, it means we are entering one new node's area, but without leaving the area of the pre
2951         // one, this usually happens when moving from parent into its child.
2952         // Check the configuration to decide the notify to parent node.
2953         if (eventStrictReportingEnabled_) {
2954             FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
2955         }
2956     }
2957 }
2958 
IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode> & node)2959 bool DragDropManager::IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode>& node)
2960 {
2961 #ifdef WINDOW_SCENE_SUPPORTED
2962     CHECK_NULL_RETURN(node, true);
2963     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2964     CHECK_NULL_RETURN(pipeline, true);
2965     auto manager = pipeline->GetUIExtensionManager();
2966     CHECK_NULL_RETURN(manager, true);
2967     return manager->IsShowPlaceholder(node->GetId());
2968 #endif
2969     return true;
2970 }
2971 
UpdateDragMovePosition(const NG::OffsetF & offset,bool isRedragStart)2972 void DragDropManager::UpdateDragMovePosition(const NG::OffsetF& offset, bool isRedragStart)
2973 {
2974     if (isRedragStart) {
2975         ResetContextMenuRedragPosition();
2976     }
2977     lastDragMovePosition_ = dragMovePosition_;
2978     dragMovePosition_ = offset;
2979     if (lastDragMovePosition_.NonOffset()) {
2980         return;
2981     }
2982     dragTotalMovePosition_ += (dragMovePosition_ - lastDragMovePosition_);
2983 }
2984 
IsUIExtensionOrDynamicComponent(const RefPtr<NG::UINode> & node)2985 bool DragDropManager::IsUIExtensionOrDynamicComponent(const RefPtr<NG::UINode>& node)
2986 {
2987     CHECK_NULL_RETURN(node, false);
2988     if (V2::ISOLATED_COMPONENT_ETS_TAG == node->GetTag() || V2::DYNAMIC_COMPONENT_ETS_TAG == node->GetTag()) {
2989         // As before, we presume that Isolated and Dynamic component can never show any placeholder component.
2990         return true;
2991     }
2992     return (V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() || V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
2993            (!IsUIExtensionShowPlaceholder(node));
2994 }
2995 
HandleUIExtensionDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type)2996 void DragDropManager::HandleUIExtensionDragEvent(
2997     const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent, DragEventType type)
2998 {
2999     CHECK_NULL_VOID(frameNode);
3000     auto pattern = frameNode->GetPattern<Pattern>();
3001     CHECK_NULL_VOID(pattern);
3002 
3003     auto dragEvent = pointerEvent;
3004     if (type == DragEventType::ENTER) {
3005         dragEvent.action = PointerAction::PULL_IN_WINDOW;
3006     } else if (type == DragEventType::LEAVE) {
3007         dragEvent.action = PointerAction::PULL_OUT_WINDOW;
3008     } else if (type == DragEventType::PULL_CANCEL) {
3009         dragEvent.action = PointerAction::PULL_CANCEL;
3010     }
3011     pattern->HandleDragEvent(dragEvent);
3012 }
3013 
GetMenuPreviewRect()3014 RectF DragDropManager::GetMenuPreviewRect()
3015 {
3016     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
3017     CHECK_NULL_RETURN(pipelineContext, RectF());
3018     auto dragDropManager = pipelineContext->GetDragDropManager();
3019     CHECK_NULL_RETURN(dragDropManager, RectF());
3020     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
3021     CHECK_NULL_RETURN(menuWrapperNode, RectF());
3022     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
3023     CHECK_NULL_RETURN(menuWrapperPattern, RectF());
3024     auto menuPreview = menuWrapperPattern->GetPreview();
3025     CHECK_NULL_RETURN(menuPreview, RectF());
3026     auto previewPaintRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
3027     previewPaintRect -= DragDropFuncWrapper::GetCurrentWindowOffset(pipelineContext);
3028     return previewPaintRect;
3029 }
3030 
GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase> & pipeline)3031 double DragDropManager::GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase>& pipeline)
3032 {
3033     auto context = DynamicCast<NG::PipelineContext>(pipeline);
3034     CHECK_NULL_RETURN(context, -1.0f);
3035     auto dragDropMgr = context->GetDragDropManager();
3036     CHECK_NULL_RETURN(dragDropMgr, -1.0f);
3037     auto& columnInfo = dragDropMgr->columnInfo_;
3038     if (!columnInfo) {
3039         columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::DRAG_PANEL);
3040         auto gridContainer = columnInfo->GetParent();
3041         if (gridContainer) {
3042             auto rootWidth = context->GetRootWidth();
3043             if (LessOrEqual(rootWidth, 0.0)) {
3044                 auto mainPipeline = PipelineContext::GetMainPipelineContext();
3045                 rootWidth = GridSystemManager::GetInstance().GetScreenWidth(mainPipeline);
3046             }
3047             // cannot handle multi-screen
3048             gridContainer->BuildColumnWidth(rootWidth);
3049         }
3050         dragDropMgr->columnInfo_ = columnInfo;
3051     }
3052 
3053     auto gridSizeType = GridSystemManager::GetInstance().GetCurrentSize();
3054     if (gridSizeType > GridSizeType::LG) {
3055         gridSizeType = GridSizeType::LG;
3056     }
3057     if (gridSizeType < GridSizeType::SM) {
3058         gridSizeType = GridSizeType::SM;
3059     }
3060     auto columns = columnInfo->GetColumns(gridSizeType);
3061     double maxWidth = columnInfo->GetWidth(columns);
3062     return maxWidth;
3063 }
3064 
GetScaleInfo(float width,float height,bool textDraggable)3065 std::shared_ptr<ScaleDataInfo> DragDropManager::GetScaleInfo(float width, float height, bool textDraggable)
3066 {
3067     auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
3068     CHECK_NULL_RETURN(scaleDataInfo, nullptr);
3069     scaleDataInfo->shortSide = fmin(SystemProperties::GetDeviceHeight(), SystemProperties::GetDeviceWidth());
3070     auto shortSide = PipelineBase::Px2VpWithCurrentDensity(scaleDataInfo->shortSide);
3071     if (shortSide <= DEVICE_TYPE_UNKOWN) {
3072         return scaleDataInfo;
3073     } else if (shortSide <= DEVICE_TYPE_SMALL) {
3074         scaleDataInfo = DragDropManager::CalculateScale(width, height,
3075             textDraggable ? scaleDataInfo->shortSide : scaleDataInfo->shortSide / SCALE_TYPE_FIRST,
3076             scaleDataInfo->shortSide / SCALE_TYPE_FIRST);
3077     } else if (shortSide <= DEVICE_TYPE_MEDIUM) {
3078         scaleDataInfo = CalculateScale(width, height,
3079             textDraggable ? scaleDataInfo->shortSide / SCALE_TYPE_FIRST : scaleDataInfo->shortSide / SCALE_TYPE_THIRD,
3080             scaleDataInfo->shortSide / SCALE_TYPE_THIRD);
3081     } else {
3082         scaleDataInfo = CalculateScale(width, height,
3083             textDraggable ? scaleDataInfo->shortSide * SCALE_TYPE_FIRST / SCALE_TYPE_SECOND
3084                           : scaleDataInfo->shortSide / SCALE_TYPE_SECOND,
3085             scaleDataInfo->shortSide / SCALE_TYPE_SECOND);
3086     }
3087     return scaleDataInfo;
3088 }
3089 
CalculateScale(float width,float height,float widthLimit,float heightLimit)3090 std::shared_ptr<ScaleDataInfo> DragDropManager::CalculateScale(
3091     float width, float height, float widthLimit, float heightLimit)
3092 {
3093     auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
3094     CHECK_NULL_RETURN(scaleDataInfo, nullptr);
3095     if ((width > 0 && height > 0) && (width > widthLimit || height > heightLimit)) {
3096         scaleDataInfo->scale = fmin(widthLimit / width, heightLimit / height);
3097         scaleDataInfo->isNeedScale = true;
3098     }
3099     return scaleDataInfo;
3100 }
3101 
GetDragAnimationOverlayManager(int32_t containerId)3102 const RefPtr<NG::OverlayManager> DragDropManager::GetDragAnimationOverlayManager(int32_t containerId)
3103 {
3104     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
3105         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
3106     CHECK_NULL_RETURN(subwindow, nullptr);
3107     return subwindow->GetOverlayManager();
3108 }
3109 
RemoveDragFrameNode(int32_t id)3110 void DragDropManager::RemoveDragFrameNode(int32_t id)
3111 {
3112     gridDragFrameNodes_.erase(id);
3113     listDragFrameNodes_.erase(id);
3114     textFieldDragFrameNodes_.erase(id);
3115 }
3116 
SetIsDragged(bool isDragged)3117 void DragDropManager::SetIsDragged(bool isDragged)
3118 {
3119     if (isDragged && isDragged_ != isDragged && notifyInDraggedCallback_) {
3120         notifyInDraggedCallback_();
3121     }
3122     isDragged_ = isDragged;
3123 }
3124 
RegisterDragStatusListener(int32_t nodeId,const WeakPtr<FrameNode> & node)3125 void DragDropManager::RegisterDragStatusListener(int32_t nodeId, const WeakPtr<FrameNode>& node)
3126 {
3127     auto ret = nodesForDragNotify_.try_emplace(nodeId, node);
3128     if (!ret.second) {
3129         nodesForDragNotify_[nodeId] = node;
3130     }
3131 }
3132 
RegisterPullEventListener(int32_t uniqueIdentify,std::function<void (const DragPointerEvent &)> callback)3133 void DragDropManager::RegisterPullEventListener(
3134     int32_t uniqueIdentify, std::function<void(const DragPointerEvent&)> callback)
3135 {
3136     pullEventListener_[uniqueIdentify] = callback;
3137 }
3138 
UnRegisterPullEventListener(int32_t uniqueIdentify)3139 void DragDropManager::UnRegisterPullEventListener(int32_t uniqueIdentify)
3140 {
3141     auto it = pullEventListener_.find(uniqueIdentify);
3142     if (it != pullEventListener_.end()) {
3143         pullEventListener_.erase(it);
3144     }
3145 }
3146 
NotifyPullEventListener(const DragPointerEvent & pointerEvent)3147 void DragDropManager::NotifyPullEventListener(const DragPointerEvent& pointerEvent)
3148 {
3149     if (pullEventListener_.empty()) {
3150         return;
3151     }
3152     for (const auto& pair : pullEventListener_) {
3153         if (pair.second) {
3154             pair.second(pointerEvent);
3155         }
3156     }
3157 }
3158 
IsDraggingPressed(int32_t currentPointerId) const3159 bool DragDropManager::IsDraggingPressed(int32_t currentPointerId) const
3160 {
3161     if (currentPointerId_ == currentPointerId) {
3162         return draggingPressedState_;
3163     }
3164     return false;
3165 }
3166 
ResetContextMenuDragPosition()3167 void DragDropManager::ResetContextMenuDragPosition()
3168 {
3169     dragMovePosition_.Reset();
3170     lastDragMovePosition_.Reset();
3171     dragTotalMovePosition_.Reset();
3172 }
3173 
ResetContextMenuRedragPosition()3174 void DragDropManager::ResetContextMenuRedragPosition()
3175 {
3176     dragMovePosition_.Reset();
3177     lastDragMovePosition_.Reset();
3178 }
3179 
AddNewDragAnimation()3180 void DragDropManager::AddNewDragAnimation()
3181 {
3182     currentAnimationCnt_++;
3183     allAnimationCnt_++;
3184 }
3185 
AddNewDragStartAnimation()3186 void DragDropManager::AddNewDragStartAnimation()
3187 {
3188     currentStartAnimationCnt_++;
3189     allStartAnimationCnt_++;
3190 }
3191 
IsAllAnimationFinished()3192 bool DragDropManager::IsAllAnimationFinished()
3193 {
3194     currentAnimationCnt_--;
3195     return currentAnimationCnt_ == 0;
3196 }
3197 
IsAllStartAnimationFinished()3198 bool DragDropManager::IsAllStartAnimationFinished()
3199 {
3200     currentStartAnimationCnt_--;
3201     return currentStartAnimationCnt_ == 0;
3202 }
3203 
CheckIsNewDrag(const DragPointerEvent & pointerEvent) const3204 bool DragDropManager::CheckIsNewDrag(const DragPointerEvent& pointerEvent) const
3205 {
3206     return (pointerEvent.pullId != -1) && (pointerEvent.pullId != currentPullId_);
3207 }
3208 
RequireSummaryAndDragBundleInfoIfNecessary(const DragPointerEvent & pointerEvent)3209 void DragDropManager::RequireSummaryAndDragBundleInfoIfNecessary(const DragPointerEvent& pointerEvent)
3210 {
3211     if (CheckIsNewDrag(pointerEvent)) {
3212         currentPullId_ = pointerEvent.pullId;
3213         RequireSummary();
3214         RequireBundleInfo();
3215     }
3216 }
3217 
IsAnyDraggableHit(const RefPtr<PipelineBase> & pipeline,int32_t pointId)3218 bool DragDropManager::IsAnyDraggableHit(const RefPtr<PipelineBase>& pipeline, int32_t pointId)
3219 {
3220     if (isAnyDraggableHit_) {
3221         return true;
3222     }
3223 
3224     auto pipelineContext = AceType::DynamicCast<PipelineContext>(pipeline);
3225     CHECK_NULL_RETURN(pipelineContext, false);
3226     auto eventManager = pipelineContext->GetEventManager();
3227     CHECK_NULL_RETURN(eventManager, false);
3228     auto touchTestResults = eventManager->touchTestResults_;
3229     const auto iter = touchTestResults.find(pointId);
3230     if (iter == touchTestResults.end() || iter->second.empty()) {
3231         TAG_LOGI(AceLogTag::ACE_DRAG, "touch test result is empty.");
3232         return false;
3233     }
3234     for (const auto& touchTestResult : iter->second) {
3235         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(touchTestResult);
3236         if (recognizer) {
3237             continue;
3238         }
3239         auto node = touchTestResult->GetAttachedNode().Upgrade();
3240         CHECK_NULL_RETURN(node, false);
3241         if (IsUIExtensionOrDynamicComponent(node)) {
3242             return true;
3243         }
3244     }
3245     return false;
3246 }
3247 
CancelUDMFDataLoading(const std::string & key)3248 int32_t DragDropManager::CancelUDMFDataLoading(const std::string& key)
3249 {
3250     return UdmfClient::GetInstance()->Cancel(key);
3251 }
3252 
CheckIsFolderSubwindowBoundary(float x,float y,int32_t instanceId)3253 bool DragDropManager::CheckIsFolderSubwindowBoundary(float x, float y, int32_t instanceId)
3254 {
3255     if (!SystemProperties::IsSuperFoldDisplayDevice() || NearZero(info_.scale)) {
3256         return false;
3257     }
3258     auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
3259         SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
3260     auto container = Container::GetContainer(mainContainerId);
3261     CHECK_NULL_RETURN(container, false);
3262     if (container->GetCurrentFoldStatus() == FoldStatus::EXPAND) {
3263         return false;
3264     }
3265     auto isCrossWindow = container->IsCrossAxisWindow();
3266     auto isSceneBoard = container->IsSceneBoardWindow();
3267     if (isCrossWindow || isSceneBoard) {
3268         return false;
3269     }
3270     auto subwindow =
3271         SubwindowManager::GetInstance()->GetSubwindowByType(Container::CurrentId(), SubwindowType::TYPE_MENU);
3272     CHECK_NULL_RETURN(subwindow, false);
3273     auto rect = subwindow->GetWindowRect();
3274     auto scale = dragStartAnimationRate_ * (info_.scale - info_.originScale.y) + info_.originScale.y;
3275     OffsetF pixelMapOffset = pixelMapOffset_ / info_.scale * scale;
3276     float top = y + pixelMapOffset.GetY();
3277     float bottom = y + pixelMapOffset.GetY() + info_.height * scale;
3278     float distance = std::min(top - rect.Top(), rect.Bottom() - bottom);
3279     return distance < MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE;
3280 }
3281 
CheckIsUIExtensionBoundary(float x,float y,int32_t instanceId)3282 bool DragDropManager::CheckIsUIExtensionBoundary(float x, float y, int32_t instanceId)
3283 {
3284     auto container = Container::GetContainer(instanceId);
3285     CHECK_NULL_RETURN(container, false);
3286     if (!container->IsUIExtensionWindow()) {
3287         return false;
3288     }
3289     auto pipeline = container->GetPipelineContext();
3290     CHECK_NULL_RETURN(pipeline, false);
3291     auto rect = pipeline->GetCurrentWindowRect();
3292     auto distance = std::min(std::min(x - rect.Left(), rect.Right() - x),
3293         std::min(y - rect.Top(), rect.Bottom() - y));
3294     return distance < MIN_UI_EXTENSION_BOUNDARY_DISTANCE;
3295 }
3296 
ReportOnItemDropEvent(DragType dragType,const RefPtr<FrameNode> & dragFrameNode,double dropPositionX,double dropPositionY)3297 void DragDropManager::ReportOnItemDropEvent(
3298     DragType dragType, const RefPtr<FrameNode>& dragFrameNode, double dropPositionX, double dropPositionY)
3299 {
3300     CHECK_NULL_VOID(dragFrameNode);
3301     auto windowScale = isDragWindowSubWindow_ ? 1.0f : GetWindowScale();
3302     auto windowX = PipelineBase::Px2VpWithCurrentDensity(dragStartPoint_.GetX() * windowScale);
3303     auto windowY = PipelineBase::Px2VpWithCurrentDensity(dragStartPoint_.GetY() * windowScale);
3304 
3305     auto params = JsonUtil::Create();
3306     CHECK_NULL_VOID(params);
3307     params->Put("StartX", windowX);
3308     params->Put("StartY", windowY);
3309     params->Put("InsertX", dropPositionX);
3310     params->Put("InsertY", dropPositionY);
3311 
3312     std::string eventName;
3313     std::string type;
3314     if (dragType == DragType::GRID) {
3315         eventName = "Grid.onItemDrop";
3316         type = "Grid";
3317     } else {
3318         eventName = "List.onItemDrop";
3319         type = "List";
3320     }
3321     auto event = JsonUtil::Create();
3322     CHECK_NULL_VOID(event);
3323     event->Put("name", eventName.c_str());
3324     event->Put("params", params);
3325 
3326     auto json = JsonUtil::Create();
3327     CHECK_NULL_VOID(json);
3328     json->Put("nodeId", dragFrameNode->GetId());
3329     json->Put("event", event);
3330 
3331     auto result = JsonUtil::Create();
3332     CHECK_NULL_VOID(result);
3333     result->Put("result", json);
3334     UiSessionManager::GetInstance()->ReportComponentChangeEvent("result", result->ToString());
3335     TAG_LOGI(AceLogTag::ACE_DRAG,
3336         "nodeId:[%{public}d] %{public}s reportComponentChangeEvent onItemDrop StartX:%{public}.15f "
3337         "StartY:%{public}.15f "
3338         "InsertX:%{public}.15f InsertY:%{public}.15f",
3339         dragFrameNode->GetId(), type.c_str(), windowX, windowY, dropPositionX, dropPositionY);
3340 }
3341 
SetDragAnimationPointerEvent(const DragPointerEvent & pointerEvent,const RefPtr<NG::FrameNode> & node)3342 void DragDropManager::SetDragAnimationPointerEvent(
3343     const DragPointerEvent& pointerEvent, const RefPtr<NG::FrameNode>& node)
3344 {
3345     auto container = Container::Current();
3346     CHECK_NULL_VOID(container);
3347     if (!container->IsSceneBoardWindow() || node == rootNode_) {
3348         dragAnimationPointerEvent_ = pointerEvent;
3349     }
3350 }
3351 
HandleTouchEvent(const TouchEvent & event,const RefPtr<NG::FrameNode> & node)3352 void DragDropManager::HandleTouchEvent(const TouchEvent& event, const RefPtr<NG::FrameNode>& node)
3353 {
3354     if (event.type == TouchType::MOVE && event.pullType != TouchType::PULL_MOVE) {
3355         if (!IsDragging() || !IsSameDraggingPointer(event.id)) {
3356             return;
3357         }
3358         DragPointerEvent dragPointerEvent;
3359         DragDropFuncWrapper::ConvertPointerEvent(event, dragPointerEvent);
3360         SetDragAnimationPointerEvent(dragPointerEvent);
3361     } else if ((event.type == TouchType::UP) || (event.type == TouchType::CANCEL)) {
3362         ResetDraggingStatus(event);
3363     }
3364 }
3365 
HandleMouseEvent(const MouseEvent & event)3366 void DragDropManager::HandleMouseEvent(const MouseEvent& event)
3367 {
3368     bool cancelDrag = (event.button == MouseButton::RIGHT_BUTTON &&
3369         (event.action == MouseAction::PRESS || event.action == MouseAction::PULL_UP));
3370     SetIsDragCancel(cancelDrag);
3371 }
3372 
HandlePipelineOnHide()3373 void DragDropManager::HandlePipelineOnHide()
3374 {
3375     if (IsItemDragging()) {
3376         CancelItemDrag();
3377     }
3378 }
3379 
ResetBundleInfo()3380 void DragDropManager::ResetBundleInfo()
3381 {
3382     auto container = Container::Current();
3383     CHECK_NULL_VOID(container);
3384     auto dragBundleName = container->GetBundleName();
3385     dragBundleInfo_.bundleName = dragBundleName;
3386     dragBundleInfo_.isRemoteDev = false;
3387 }
3388 
RequireBundleInfo()3389 void DragDropManager::RequireBundleInfo()
3390 {
3391     DragBundleInfo dragBundleInfo;
3392     InteractionInterface::GetInstance()->GetDragBundleInfo(dragBundleInfo);
3393     dragBundleInfo_ = dragBundleInfo;
3394 }
3395 
NotifyDragSpringLoadingMove(const RefPtr<FrameNode> & dragFrameNode,const std::string & extraInfo)3396 void DragDropManager::NotifyDragSpringLoadingMove(const RefPtr<FrameNode>& dragFrameNode, const std::string& extraInfo)
3397 {
3398     if (!dragDropSpringLoadingDetector_) {
3399         dragDropSpringLoadingDetector_ = MakeRefPtr<DragDropSpringLoadingDetector>();
3400     }
3401     dragDropSpringLoadingDetector_->NotifyMove({ preMovePoint_, dragFrameNode, preTimeStamp_, extraInfo });
3402 }
3403 
NotifyDragSpringLoadingIntercept(std::string_view extraParams)3404 void DragDropManager::NotifyDragSpringLoadingIntercept(std::string_view extraParams)
3405 {
3406     if (!dragDropSpringLoadingDetector_) {
3407         dragDropSpringLoadingDetector_ = MakeRefPtr<DragDropSpringLoadingDetector>();
3408     }
3409     dragDropSpringLoadingDetector_->NotifyIntercept(extraParams);
3410 }
3411 } // namespace OHOS::Ace::NG
3412