• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
17 
18 #include "core/common/ace_engine.h"
19 #include "core/components/common/layout/grid_system_manager.h"
20 #include "core/components/select/select_theme.h"
21 #include "core/components/theme/blur_style_theme.h"
22 #include "core/components/theme/shadow_theme.h"
23 #include "core/components_ng/base/inspector.h"
24 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
25 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
26 #include "core/components_ng/pattern/grid/grid_item_pattern.h"
27 #include "core/components_ng/pattern/image/image_pattern.h"
28 #include "core/components_ng/pattern/list/list_item_pattern.h"
29 #include "core/components_ng/pattern/text/text_pattern.h"
30 #include "core/components_ng/render/adapter/component_snapshot.h"
31 #include "base/subwindow/subwindow_manager.h"
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr float DEFAULT_OPACITY = 0.95f;
36 constexpr Dimension PREVIEW_BORDER_RADIUS = 12.0_vp;
37 constexpr float BLUR_SIGMA_SCALE = 0.57735f;
38 constexpr float SCALE_HALF = 0.5f;
39 constexpr float MIN_OPACITY { 0.0f };
40 constexpr float MAX_OPACITY { 1.0f };
41 using DragNotifyMsg = OHOS::Ace::DragNotifyMsg;
42 using OnDragCallback = std::function<void(const DragNotifyMsg&)>;
43 using StopDragCallback = std::function<void()>;
44 constexpr int32_t MOUSE_POINTER_ID = 1001;
45 constexpr int32_t SOURCE_TOOL_PEN = 1;
46 constexpr int32_t SOURCE_TYPE_TOUCH = 2;
47 constexpr int32_t PEN_POINTER_ID = 102;
48 constexpr int32_t SOURCE_TYPE_MOUSE = 1;
49 constexpr size_t SHORT_KEY_LENGTH = 8;
50 constexpr size_t PLAINTEXT_LENGTH = 4;
51 constexpr size_t  CONVERT_TIME_BASE = 1000;
52 #if defined(PIXEL_MAP_SUPPORTED)
53 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
54 #endif
55 }
56 
CheckInternalDragging(const RefPtr<Container> & container)57 static bool CheckInternalDragging(const RefPtr<Container>& container)
58 {
59     CHECK_NULL_RETURN(container, false);
60     auto pipelineContext = container->GetPipelineContext();
61     if (!pipelineContext || !pipelineContext->IsDragging()) {
62         return false;
63     }
64     return true;
65 }
66 
GetShadowInfoArray(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::vector<ShadowInfoCore> & shadowInfos)67 void GetShadowInfoArray(
68     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::vector<ShadowInfoCore>& shadowInfos)
69 {
70     auto minScaleWidth = NG::DragDropFuncWrapper::GetScaleWidth(dragAction->instanceId);
71     for (auto& pixelMap : dragAction->pixelMapList) {
72         double scale = 1.0;
73         if (Referenced::RawPtr(pixelMap)) {
74             if (pixelMap->GetWidth() > minScaleWidth && dragAction->previewOption.isScaleEnabled) {
75                 scale = minScaleWidth / pixelMap->GetWidth();
76             }
77             auto pixelMapScale = dragAction->windowScale * scale;
78             pixelMap->Scale(pixelMapScale, pixelMapScale, AceAntiAliasingOption::HIGH);
79         }
80         int32_t width = pixelMap->GetWidth();
81         int32_t height = pixelMap->GetHeight();
82         double x = dragAction->touchPointX;
83         double y = dragAction->touchPointY;
84         if (!dragAction->hasTouchPoint) {
85             x = -width * PIXELMAP_WIDTH_RATE;
86             y = -height * PIXELMAP_HEIGHT_RATE;
87         }
88         ShadowInfoCore shadowInfo { pixelMap, -x, -y };
89         shadowInfos.push_back(shadowInfo);
90     }
91 }
92 
PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)93 void PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
94 {
95     CHECK_NULL_VOID(container);
96     auto taskExecutor = container->GetTaskExecutor();
97     CHECK_NULL_VOID(taskExecutor);
98     auto windowId = container->GetWindowId();
99     taskExecutor->PostTask(
100         [dragAction, windowId]() {
101             CHECK_NULL_VOID(dragAction);
102             TAG_LOGI(AceLogTag::ACE_DRAG, "drag state is reject, stop drag, windowId is %{public}d.", windowId);
103             OHOS::Ace::DragDropRet dropResult { OHOS::Ace::DragRet::DRAG_CANCEL, false, windowId,
104                 OHOS::Ace::DragBehavior::UNKNOWN };
105             InteractionInterface::GetInstance()->StopDrag(dropResult);
106             InteractionInterface::GetInstance()->SetDragWindowVisible(false);
107         },
108         TaskExecutor::TaskType::UI, "ArkUIDragStop");
109 }
110 
ConfirmCurPointerEventInfo(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)111 bool ConfirmCurPointerEventInfo(
112     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
113 {
114     CHECK_NULL_RETURN(dragAction, false);
115     CHECK_NULL_RETURN(container, false);
116     StopDragCallback stopDragCallback = [dragAction, container]() {
117         CHECK_NULL_VOID(dragAction);
118         CHECK_NULL_VOID(container);
119         bool needPostStopDrag = false;
120         if (dragAction->dragState == DragAdapterState::SENDING) {
121             needPostStopDrag = true;
122         }
123         {
124             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
125             dragAction->dragState = DragAdapterState::REJECT;
126         }
127         if (needPostStopDrag) {
128             PostStopDrag(dragAction, container);
129         }
130     };
131     bool getPointSuccess = container->GetCurPointerEventInfo(dragAction->dragPointerEvent,
132         std::move(stopDragCallback));
133     if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_MOUSE) {
134         dragAction->dragPointerEvent.pointerId = MOUSE_POINTER_ID;
135     } else if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_TOUCH &&
136         static_cast<int32_t>(dragAction->dragPointerEvent.sourceTool) == SOURCE_TOOL_PEN) {
137         dragAction->dragPointerEvent.pointerId = PEN_POINTER_ID;
138     }
139     return getPointSuccess;
140 }
141 
EnvelopedDragData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::optional<DragDataCore> & dragData)142 void EnvelopedDragData(
143     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::optional<DragDataCore>& dragData)
144 {
145     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
146     CHECK_NULL_VOID(container);
147 
148     std::vector<ShadowInfoCore> shadowInfos;
149     GetShadowInfoArray(dragAction, shadowInfos);
150     if (shadowInfos.empty()) {
151         TAG_LOGE(AceLogTag::ACE_DRAG, "shadowInfo array is empty");
152         return;
153     }
154     auto pointerId = dragAction->dragPointerEvent.pointerId;
155     std::string udKey;
156     DragSummaryInfo dragSummaryInfo;
157     int32_t dataSize = 1;
158     DragDropFuncWrapper::EnvelopedData(dragAction, udKey, dragSummaryInfo, dataSize);
159     int32_t recordSize = (dataSize != 0 ? dataSize : static_cast<int32_t>(shadowInfos.size()));
160     if (dragAction->previewOption.isNumber) {
161         recordSize = dragAction->previewOption.badgeNumber > 1 ? dragAction->previewOption.badgeNumber : 1;
162     } else if (!dragAction->previewOption.isShowBadge) {
163         recordSize = 1;
164     }
165     auto windowId = container->GetWindowId();
166     auto arkExtraInfoJson = JsonUtil::Create(true);
167     auto pipeline = container->GetPipelineContext();
168     CHECK_NULL_VOID(pipeline);
169     dragAction->dipScale = pipeline->GetDipScale();
170     arkExtraInfoJson->Put("dip_scale", dragAction->dipScale);
171     arkExtraInfoJson->Put("event_id", dragAction->dragPointerEvent.pointerEventId);
172     NG::DragDropFuncWrapper::UpdateExtraInfo(arkExtraInfoJson, dragAction->previewOption);
173     dragData = { shadowInfos, {}, udKey, dragAction->extraParams, arkExtraInfoJson->ToString(),
174         dragAction->dragPointerEvent.sourceType, recordSize, pointerId, dragAction->dragPointerEvent.displayX,
175         dragAction->dragPointerEvent.displayY, dragAction->dragPointerEvent.displayId, windowId, true, false,
176         dragSummaryInfo.summary, false, dragSummaryInfo.detailedSummary, dragSummaryInfo.summaryFormat,
177         dragSummaryInfo.version, dragSummaryInfo.totalSize };
178 }
179 
EnvelopedData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::string & udKey,DragSummaryInfo & dragSummaryInfo,int32_t & dataSize)180 void DragDropFuncWrapper::EnvelopedData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
181     std::string& udKey, DragSummaryInfo& dragSummaryInfo, int32_t& dataSize)
182 {
183     CHECK_NULL_VOID(dragAction);
184     int32_t ret = 1;
185     if (dragAction->unifiedData) {
186         ret = UdmfClient::GetInstance()->SetData(dragAction->unifiedData, udKey);
187         if (ret != 0) {
188             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set data failed, return value is %{public}d", ret);
189         }
190         dataSize = static_cast<int32_t>(dragAction->unifiedData->GetSize());
191     }
192     if (dragAction->dataLoadParams) {
193         ret = UdmfClient::GetInstance()->SetDelayInfo(dragAction->dataLoadParams, udKey);
194         if (ret != 0) {
195             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set delayInfo failed, return value is %{public}d", ret);
196         }
197         auto recodeCount = dragAction->dataLoadParams->GetRecordCount();
198         dataSize = (recodeCount == 0 || recodeCount > INT32_MAX) ? 1 : static_cast<int32_t>(recodeCount);
199     }
200     if (ret == 0) {
201         ret = UdmfClient::GetInstance()->GetSummary(udKey, dragSummaryInfo);
202         if (ret != 0) {
203             TAG_LOGI(AceLogTag::ACE_DRAG, "get summary failed, return value is %{public}d", ret);
204         }
205     }
206 }
207 
HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const OHOS::Ace::DragNotifyMsg & dragNotifyMsg,const DragAdapterStatus & dragStatus)208 void DragDropFuncWrapper::HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
209     const OHOS::Ace::DragNotifyMsg& dragNotifyMsg, const DragAdapterStatus& dragStatus)
210 {
211     TAG_LOGI(AceLogTag::ACE_DRAG, "drag notify message result is %{public}d.", dragNotifyMsg.result);
212     CHECK_NULL_VOID(dragAction);
213     bool hasHandle = false;
214     {
215         std::lock_guard<std::mutex> lock(dragAction->mutex);
216         hasHandle = dragAction->hasHandle;
217         dragAction->hasHandle = true;
218     }
219     if (hasHandle) {
220         return;
221     }
222     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
223     CHECK_NULL_VOID(container);
224     if (dragStatus == DragAdapterStatus::ENDED) {
225         auto pipelineContext = container->GetPipelineContext();
226         CHECK_NULL_VOID(pipelineContext);
227         pipelineContext->ResetDragging();
228     }
229     int32_t dragState = static_cast<int32_t>(dragStatus);
230     dragAction->callback(dragNotifyMsg, dragState);
231 }
232 
CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container,const RefPtr<DragDropManager> & manager)233 int32_t CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
234     const RefPtr<Container>& container, const RefPtr<DragDropManager>& manager)
235 {
236     if (CheckInternalDragging(container)) {
237         return -1;
238     }
239     {
240         std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
241         if (manager->GetDragAction() != nullptr && (manager->GetDragAction())->dragState == DragAdapterState::SENDING) {
242             return -1;
243         }
244         dragAction->dragState = DragAdapterState::SENDING;
245     }
246     DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(dragAction->previewOption);
247     auto isGetPointSuccess = ConfirmCurPointerEventInfo(dragAction, container);
248     if (!isGetPointSuccess) {
249         return -1;
250     }
251     return 0;
252 }
253 
StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)254 int32_t DragDropFuncWrapper::StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
255 {
256     CHECK_NULL_RETURN(dragAction, -1);
257     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
258     CHECK_NULL_RETURN(pipelineContext, -1);
259     auto manager = pipelineContext->GetDragDropManager();
260     CHECK_NULL_RETURN(manager, -1);
261     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
262     CHECK_NULL_RETURN(container, -1);
263     auto windowScale = container->GetWindowScale();
264     CHECK_NULL_RETURN(windowScale, -1);
265     dragAction->windowScale = windowScale;
266     manager->SetDragAction(dragAction);
267     if (CheckStartAction(dragAction, container, manager) == -1) {
268         manager->GetDragAction()->dragState = DragAdapterState::INIT;
269         return -1;
270     }
271     std::optional<DragDataCore> dragData;
272     EnvelopedDragData(dragAction, dragData);
273     if (!dragData) {
274         {
275             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
276             manager->GetDragAction()->dragState = DragAdapterState::INIT;
277         }
278         return -1;
279     }
280     OnDragCallback callback = [dragAction, manager](const OHOS::Ace::DragNotifyMsg& dragNotifyMsg) {
281         {
282             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
283             dragAction->dragState = DragAdapterState::INIT;
284             manager->SetDragAction(dragAction);
285         }
286         HandleCallback(dragAction, dragNotifyMsg, DragAdapterStatus::ENDED);
287     };
288     NG::DragDropFuncWrapper::SetDraggingPointerAndPressedState(
289         dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
290     int32_t ret = InteractionInterface::GetInstance()->StartDrag(dragData.value(), callback);
291     if (ret != 0) {
292         manager->GetDragAction()->dragState = DragAdapterState::INIT;
293         TAG_LOGE(AceLogTag::ACE_DRAG, "msdp start drag failed.");
294         return -1;
295     }
296     HandleCallback(dragAction, DragNotifyMsg {}, DragAdapterStatus::STARTED);
297     pipelineContext->SetIsDragging(true);
298     TAG_LOGI(AceLogTag::ACE_DRAG, "msdp start drag successfully.");
299     NG::DragDropFuncWrapper::HandleOnDragEvent(dragAction);
300     return 0;
301 }
302 
HandleOnDragEvent(const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)303 void DragDropFuncWrapper::HandleOnDragEvent(
304     const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
305 {
306     CHECK_NULL_VOID(dragAction);
307     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
308     CHECK_NULL_VOID(pipelineContext);
309     std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
310     if (dragAction->dragState == DragAdapterState::SENDING) {
311         dragAction->dragState = DragAdapterState::SUCCESS;
312         InteractionInterface::GetInstance()->SetDragWindowVisible(true);
313         pipelineContext->OnDragEvent(
314             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY },
315             DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER);
316         NG::DragDropFuncWrapper::DecideWhetherToStopDragging(
317             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY }, dragAction->extraParams,
318             dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
319     }
320 }
321 
SetDraggingPointerAndPressedState(int32_t currentPointerId,int32_t containerId)322 void DragDropFuncWrapper::SetDraggingPointerAndPressedState(int32_t currentPointerId, int32_t containerId)
323 {
324     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
325     CHECK_NULL_VOID(pipelineContext);
326     auto manager = pipelineContext->GetDragDropManager();
327     CHECK_NULL_VOID(manager);
328     manager->SetDraggingPointer(currentPointerId);
329     manager->SetDraggingPressedState(true);
330 }
331 
RequestDragEndPending()332 int32_t DragDropFuncWrapper::RequestDragEndPending()
333 {
334     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
335         return -1;
336     }
337     static std::atomic<int32_t> gDragDropDelayEndRequestId;
338     int32_t id = gDragDropDelayEndRequestId.fetch_add(1);
339     return id;
340 }
341 
NotifyDragResult(int32_t requestId,int32_t result)342 int32_t DragDropFuncWrapper::NotifyDragResult(int32_t requestId, int32_t result)
343 {
344     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
345         return -1;
346     }
347     return DragDropGlobalController::GetInstance().NotifyDragResult(requestId, result);
348 }
349 
NotifyDragEndPendingDone(int32_t requestId)350 int32_t DragDropFuncWrapper::NotifyDragEndPendingDone(int32_t requestId)
351 {
352     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
353         return -1;
354     }
355     return DragDropGlobalController::GetInstance().NotifyDragEndPendingDone(requestId);
356 }
357 
DecideWhetherToStopDragging(const DragPointerEvent & pointerEvent,const std::string & extraParams,int32_t currentPointerId,int32_t containerId)358 void DragDropFuncWrapper::DecideWhetherToStopDragging(
359     const DragPointerEvent& pointerEvent, const std::string& extraParams, int32_t currentPointerId, int32_t containerId)
360 {
361     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
362     CHECK_NULL_VOID(pipelineContext);
363     auto manager = pipelineContext->GetDragDropManager();
364     CHECK_NULL_VOID(manager);
365     if (!manager->IsDraggingPressed(currentPointerId)) {
366         manager->OnDragEnd(pointerEvent, extraParams);
367     }
368 }
369 
UpdateDragPreviewOptionsFromModifier(std::function<void (WeakPtr<FrameNode>)> applyOnNodeSync,DragPreviewOption & option)370 void DragDropFuncWrapper::UpdateDragPreviewOptionsFromModifier(
371     std::function<void(WeakPtr<FrameNode>)> applyOnNodeSync, DragPreviewOption& option)
372 {
373     // create one temporary frame node for receiving the value from the modifier
374     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
375         []() { return AceType::MakeRefPtr<ImagePattern>(); });
376     CHECK_NULL_VOID(imageNode);
377 
378     // execute the modifier
379     CHECK_NULL_VOID(applyOnNodeSync);
380     applyOnNodeSync(AceType::WeakClaim(AceType::RawPtr(imageNode)));
381 
382     // get values from the temporary frame node
383     auto imageContext = imageNode->GetRenderContext();
384     CHECK_NULL_VOID(imageContext);
385     auto opacity = imageContext->GetOpacity();
386     if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) > MIN_OPACITY) {
387         option.options.opacity = opacity.value();
388     } else {
389         option.options.opacity = DEFAULT_OPACITY;
390     }
391 
392     auto shadow = imageContext->GetBackShadow();
393     if (shadow.has_value()) {
394         option.options.shadow = shadow.value();
395     }
396 
397     auto borderRadius = imageContext->GetBorderRadius();
398     if (borderRadius.has_value()) {
399         option.options.borderRadius = borderRadius;
400     }
401 
402     auto bgEffect = imageContext->GetBackgroundEffect();
403     if (bgEffect.has_value()) {
404         option.options.blurbgEffect.backGroundEffect = bgEffect.value();
405     } else {
406         auto blurstyletmp = imageContext->GetBackBlurStyle();
407         if (blurstyletmp.has_value()) {
408             bgEffect = BlurStyleToEffection(blurstyletmp);
409             if (bgEffect.has_value()) {
410                 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
411             }
412         }
413     }
414 }
415 
UpdatePreviewOptionDefaultAttr(DragPreviewOption & option,bool isMultiSelectionEnabled)416 void DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(DragPreviewOption& option, bool isMultiSelectionEnabled)
417 {
418     option.options.opacity = DEFAULT_OPACITY;
419     if (option.isDefaultShadowEnabled) {
420         option.options.shadow = GetDefaultShadow();
421     } else {
422         option.options.shadow = std::nullopt;
423     }
424     if (option.isDefaultRadiusEnabled || isMultiSelectionEnabled) {
425         option.options.borderRadius = GetDefaultBorderRadius();
426     } else {
427         option.options.borderRadius = std::nullopt;
428     }
429 }
430 
UpdateExtraInfo(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)431 void DragDropFuncWrapper::UpdateExtraInfo(std::unique_ptr<JsonValue>& arkExtraInfoJson,
432     DragPreviewOption& option)
433 {
434     CHECK_NULL_VOID(arkExtraInfoJson);
435     double opacity = option.options.opacity;
436     arkExtraInfoJson->Put("dip_opacity", opacity);
437     if (option.options.blurbgEffect.backGroundEffect.radius.IsValid()) {
438         option.options.blurbgEffect.ToJsonValue(arkExtraInfoJson);
439     }
440     PrepareShadowParametersForDragData(arkExtraInfoJson, option);
441     PrepareRadiusParametersForDragData(arkExtraInfoJson, option);
442 }
443 
PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)444 void DragDropFuncWrapper::PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
445     DragPreviewOption& option)
446 {
447     CHECK_NULL_VOID(arkExtraInfoJson);
448     auto borderRadius = option.options.borderRadius;
449     if (borderRadius.has_value()) {
450         if (borderRadius.value().radiusTopLeft.has_value()) {
451             arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
452         }
453         if (borderRadius.value().radiusTopRight.has_value()) {
454             arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
455         }
456         if (borderRadius.value().radiusBottomRight.has_value()) {
457             arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
458         }
459         if (borderRadius.value().radiusBottomLeft.has_value()) {
460             arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
461         }
462     }
463 }
464 
PrepareShadowParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)465 void DragDropFuncWrapper::PrepareShadowParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
466     DragPreviewOption& option)
467 {
468     CHECK_NULL_VOID(arkExtraInfoJson);
469     auto shadow = option.options.shadow;
470     if (!shadow.has_value() || !shadow->IsValid()) {
471         arkExtraInfoJson->Put("shadow_enable", false);
472         return;
473     }
474     arkExtraInfoJson->Put("drag_type", "non-text");
475     arkExtraInfoJson->Put("shadow_enable", true);
476     ParseShadowInfo(shadow.value(), arkExtraInfoJson);
477 }
478 
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)479 void DragDropFuncWrapper::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
480 {
481     CHECK_NULL_VOID(arkExtraInfoJson);
482     arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
483     arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
484     arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
485     arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
486     int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
487     arkExtraInfoJson->Put("drag_shadow_argb", argb);
488     int32_t strategy = static_cast<int32_t>(shadow.GetShadowColorStrategy());
489     arkExtraInfoJson->Put("shadow_color_strategy", strategy);
490     arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
491     arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
492     arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
493 }
494 
GetDefaultShadow()495 std::optional<Shadow> DragDropFuncWrapper::GetDefaultShadow()
496 {
497     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
498     CHECK_NULL_RETURN(pipelineContext, std::nullopt);
499     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
500     CHECK_NULL_RETURN(shadowTheme, std::nullopt);
501     auto colorMode = pipelineContext->GetColorMode();
502     auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
503     shadow.SetIsFilled(true);
504     return shadow;
505 }
506 
GetDefaultBorderRadius()507 std::optional<BorderRadiusProperty> DragDropFuncWrapper::GetDefaultBorderRadius()
508 {
509     BorderRadiusProperty borderRadius;
510     borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
511     return borderRadius;
512 }
513 
RadiusToSigma(float radius)514 float DragDropFuncWrapper::RadiusToSigma(float radius)
515 {
516     return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
517 }
518 
BlurStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)519 std::optional<EffectOption> DragDropFuncWrapper::BlurStyleToEffection(
520     const std::optional<BlurStyleOption>& blurStyleOp)
521 {
522     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
523     CHECK_NULL_RETURN(pipeline, std::nullopt);
524     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
525     if (!blurStyleTheme) {
526         TAG_LOGW(AceLogTag::ACE_DRAG, "cannot find theme of blurStyle, create blurStyle failed");
527         return std::nullopt;
528     }
529     CHECK_NULL_RETURN(blurStyleOp, std::nullopt);
530     ThemeColorMode colorMode = blurStyleOp->colorMode;
531     if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
532         colorMode = pipeline->GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
533     }
534     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
535     CHECK_NULL_RETURN(blurParam, std::nullopt);
536     auto ratio = blurStyleOp->scale;
537     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
538     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
539     auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
540     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
541     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
542     Dimension dimen(radiusBlur);
543     EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
544         blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
545     return std::optional<EffectOption>(bgEffection);
546 }
547 
GetScaleWidth(int32_t containerId)548 [[maybe_unused]] double DragDropFuncWrapper::GetScaleWidth(int32_t containerId)
549 {
550     auto container = Container::GetContainer(containerId);
551     CHECK_NULL_RETURN(container, -1.0f);
552     auto pipeline = container->GetPipelineContext();
553     CHECK_NULL_RETURN(pipeline, -1.0f);
554     return DragDropManager::GetMaxWidthBaseOnGridSystem(pipeline);
555 }
556 
SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus)557 void DragDropFuncWrapper::SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus) noexcept
558 {
559     auto pipelineContext = PipelineContext::GetCurrentContext();
560     CHECK_NULL_VOID(pipelineContext);
561     auto dragDropManager = pipelineContext->GetDragDropManager();
562     CHECK_NULL_VOID(dragDropManager);
563     dragDropManager->HandleSyncOnDragStart(dragStartRequestStatus);
564 }
565 
SetExtraInfo(int32_t containerId,std::string extraInfo)566 void DragDropFuncWrapper::SetExtraInfo(int32_t containerId, std::string extraInfo)
567 {
568     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
569     CHECK_NULL_VOID(pipelineContext);
570     auto manager = pipelineContext->GetDragDropManager();
571     CHECK_NULL_VOID(manager);
572     manager->SetExtraInfo(extraInfo);
573 }
574 
GetSummaryString(const std::map<std::string,int64_t> & summary)575 std::string DragDropFuncWrapper::GetSummaryString(const std::map<std::string, int64_t>& summary)
576 {
577     std::string summarys;
578     for (const auto& [udkey, recordSize] : summary) {
579         std::string str = udkey + "-" + std::to_string(recordSize) + ";";
580         summarys += str;
581     }
582 
583     return summarys;
584 }
585 
GetAnonyString(const std::string & fullString)586 std::string DragDropFuncWrapper::GetAnonyString(const std::string &fullString)
587 {
588     if (fullString.empty() || fullString.length() == 0) {
589         return "";
590     }
591     std::string middleStr = "******";
592     std::string anonyStr;
593     size_t strLen = fullString.length();
594     if (strLen <= SHORT_KEY_LENGTH) {
595         anonyStr += fullString[0];
596         anonyStr.append(middleStr);
597         anonyStr += fullString[strLen - 1];
598     } else {
599         anonyStr.append(fullString, 0, PLAINTEXT_LENGTH).append(middleStr)
600             .append(fullString, strLen - PLAINTEXT_LENGTH, PLAINTEXT_LENGTH);
601     }
602     return anonyStr;
603 }
604 
605 // returns a node's offset relative to window plus half of self rect size(w, h)
606 // and accumulate every ancestor node's graphic properties such as rotate and transform
607 // ancestor will NOT check boundary of window scene
GetPaintRectCenter(const RefPtr<FrameNode> & frameNode,bool checkWindowBoundary)608 OffsetF DragDropFuncWrapper::GetPaintRectCenter(const RefPtr<FrameNode>& frameNode, bool checkWindowBoundary)
609 {
610     CHECK_NULL_RETURN(frameNode, OffsetF());
611     auto context = frameNode->GetRenderContext();
612     CHECK_NULL_RETURN(context, OffsetF());
613     auto paintRect = context->GetPaintRectWithoutTransform();
614     auto offset = paintRect.GetOffset();
615     PointF pointNode(offset.GetX() + paintRect.Width() / 2.0f, offset.GetY() + paintRect.Height() / 2.0f);
616     context->GetPointTransformRotate(pointNode);
617     auto parent = frameNode->GetAncestorNodeOfFrame(false);
618     while (parent) {
619         if (checkWindowBoundary && parent->IsWindowBoundary()) {
620             break;
621         }
622         auto renderContext = parent->GetRenderContext();
623         CHECK_NULL_RETURN(renderContext, OffsetF());
624         offset = renderContext->GetPaintRectWithoutTransform().GetOffset();
625         pointNode.SetX(offset.GetX() + pointNode.GetX());
626         pointNode.SetY(offset.GetY() + pointNode.GetY());
627         renderContext->GetPointTransformRotate(pointNode);
628         parent = parent->GetAncestorNodeOfFrame(false);
629     }
630     return OffsetF(pointNode.GetX(), pointNode.GetY());
631 }
632 
633 // check if expand subwindow
IsExpandDisplay(const RefPtr<PipelineBase> & context)634 bool DragDropFuncWrapper::IsExpandDisplay(const RefPtr<PipelineBase>& context)
635 {
636     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
637     CHECK_NULL_RETURN(pipeline, false);
638     auto theme = pipeline->GetTheme<SelectTheme>();
639     CHECK_NULL_RETURN(theme, false);
640     if (theme->GetExpandDisplay()) {
641         return true;
642     }
643     auto containerId = pipeline->GetInstanceId();
644     containerId = containerId >= MIN_SUBCONTAINER_ID ?
645         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId;
646     auto container = AceEngine::Get().GetContainer(containerId);
647     CHECK_NULL_RETURN(container, false);
648     return container->IsFreeMultiWindow() || container->IsUIExtensionWindow();
649 }
650 
GetCurrentWindowOffset(const RefPtr<PipelineBase> & context)651 OffsetF DragDropFuncWrapper::GetCurrentWindowOffset(const RefPtr<PipelineBase>& context)
652 {
653     if (!IsExpandDisplay(context)) {
654         return OffsetF();
655     }
656     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
657     CHECK_NULL_RETURN(pipeline, OffsetF());
658     auto window = pipeline->GetWindow();
659     CHECK_NULL_RETURN(window, OffsetF());
660     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
661     return OffsetF(windowOffset.GetX(), windowOffset.GetY());
662 }
663 
GetPaintRectCenterToScreen(const RefPtr<FrameNode> & frameNode)664 OffsetF DragDropFuncWrapper::GetPaintRectCenterToScreen(const RefPtr<FrameNode>& frameNode)
665 {
666     auto offset = GetPaintRectCenter(frameNode);
667     CHECK_NULL_RETURN(frameNode, offset);
668     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
669     return offset;
670 }
671 
GetFrameNodeOffsetToScreen(const RefPtr<FrameNode> & frameNode)672 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToScreen(const RefPtr<FrameNode>& frameNode)
673 {
674     CHECK_NULL_RETURN(frameNode, OffsetF());
675     auto offset = frameNode->GetPositionToWindowWithTransform();
676     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
677     return offset;
678 }
679 
GetPaintRectToScreen(const RefPtr<FrameNode> & frameNode)680 RectF DragDropFuncWrapper::GetPaintRectToScreen(const RefPtr<FrameNode>& frameNode)
681 {
682     CHECK_NULL_RETURN(frameNode, RectF());
683     RectF rect = frameNode->GetTransformRectRelativeToWindow();
684     rect += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
685     return rect;
686 }
687 
UpdateNodePositionToScreen(const RefPtr<FrameNode> & frameNode,OffsetF offset)688 void DragDropFuncWrapper::UpdateNodePositionToScreen(const RefPtr<FrameNode>& frameNode, OffsetF offset)
689 {
690     CHECK_NULL_VOID(frameNode);
691     offset -= GetCurrentWindowOffset(frameNode->GetContextRefPtr());
692     UpdateNodePositionToWindow(frameNode, offset);
693 }
694 
UpdateNodePositionToWindow(const RefPtr<FrameNode> & frameNode,OffsetF offset)695 void DragDropFuncWrapper::UpdateNodePositionToWindow(const RefPtr<FrameNode>& frameNode, OffsetF offset)
696 {
697     CHECK_NULL_VOID(frameNode);
698     auto renderContext = frameNode->GetRenderContext();
699     CHECK_NULL_VOID(renderContext);
700     RefPtr<FrameNode> parentNode = frameNode->GetAncestorNodeOfFrame(true);
701     if (parentNode) {
702         offset -= parentNode->GetPositionToWindowWithTransform();
703     }
704     renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
705 }
706 
UpdatePositionFromFrameNode(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)707 void DragDropFuncWrapper::UpdatePositionFromFrameNode(const RefPtr<FrameNode>& targetNode,
708     const RefPtr<FrameNode>& frameNode, float width, float height)
709 {
710     CHECK_NULL_VOID(targetNode);
711     CHECK_NULL_VOID(frameNode);
712     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
713     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
714     UpdateNodePositionToScreen(targetNode, offset);
715 }
716 
GetFrameNodeOffsetToWindow(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)717 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToWindow(const RefPtr<FrameNode>& targetNode,
718     const RefPtr<FrameNode>& frameNode, float width, float height)
719 {
720     CHECK_NULL_RETURN(targetNode, OffsetF());
721     CHECK_NULL_RETURN(frameNode, OffsetF());
722     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
723     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
724     offset -= GetCurrentWindowOffset(targetNode->GetContextRefPtr());
725     auto renderContext = targetNode->GetRenderContext();
726     CHECK_NULL_RETURN(renderContext, OffsetF());
727     RefPtr<FrameNode> parentNode = targetNode->GetAncestorNodeOfFrame(true);
728     if (parentNode) {
729         offset -= parentNode->GetPositionToWindowWithTransform();
730     }
731     return offset;
732 }
733 
ConvertPointerEvent(const TouchEvent & touchPoint,DragPointerEvent & event)734 void DragDropFuncWrapper::ConvertPointerEvent(const TouchEvent& touchPoint, DragPointerEvent& event)
735 {
736     event.rawPointerEvent = touchPoint.GetTouchEventPointerEvent();
737     event.pointerEventId = touchPoint.touchEventId;
738     event.pointerId = touchPoint.id;
739     event.windowX = touchPoint.x;
740     event.windowY = touchPoint.y;
741     event.displayX = touchPoint.screenX;
742     event.displayY = touchPoint.screenY;
743     event.globalDisplayX = touchPoint.globalDisplayX;
744     event.globalDisplayY = touchPoint.globalDisplayY;
745     event.deviceId = touchPoint.deviceId;
746     event.displayId = touchPoint.targetDisplayId;
747     event.x = event.windowX;
748     event.y = event.windowY;
749     event.pressedKeyCodes.clear();
750     for (const auto& curCode : touchPoint.pressedKeyCodes_) {
751         event.pressedKeyCodes.emplace_back(static_cast<KeyCode>(curCode));
752     }
753     GetPointerEventAction(touchPoint, event);
754 }
755 
GetPointerEventAction(const TouchEvent & touchPoint,DragPointerEvent & event)756 void DragDropFuncWrapper::GetPointerEventAction(const TouchEvent& touchPoint, DragPointerEvent& event)
757 {
758     auto orgAction = touchPoint.type;
759     switch (orgAction) {
760         case TouchType::CANCEL:
761             event.action = PointerAction::CANCEL;
762             break;
763         case TouchType::DOWN:
764             event.action = PointerAction::DOWN;
765             break;
766         case TouchType::MOVE:
767             event.action = PointerAction::MOVE;
768             break;
769         case TouchType::UP:
770             event.action = PointerAction::UP;
771             break;
772         case TouchType::PULL_MOVE:
773             event.action = PointerAction::PULL_MOVE;
774             break;
775         case TouchType::PULL_UP:
776             event.action = PointerAction::PULL_UP;
777             break;
778         case TouchType::PULL_IN_WINDOW:
779             event.action = PointerAction::PULL_IN_WINDOW;
780             break;
781         case TouchType::PULL_OUT_WINDOW:
782             event.action = PointerAction::PULL_OUT_WINDOW;
783             break;
784         default:
785             event.action = PointerAction::UNKNOWN;
786             break;
787     }
788 }
789 
GetFrameNodeByKey(const RefPtr<FrameNode> & root,const std::string & key)790 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByKey(const RefPtr<FrameNode>& root, const std::string& key)
791 {
792     std::queue<RefPtr<UINode>> elements;
793     elements.push(root);
794     RefPtr<UINode> inspectorElement;
795     while (!elements.empty()) {
796         auto current = elements.front();
797         elements.pop();
798         if (key == current->GetInspectorId().value_or("")) {
799             return AceType::DynamicCast<FrameNode>(current);
800         }
801 
802         const auto& children = current->GetChildren();
803         for (const auto& child : children) {
804             elements.push(child);
805         }
806     }
807     return nullptr;
808 }
809 
GetPointRelativeToMainWindow(const Point & point)810 OffsetF DragDropFuncWrapper::GetPointRelativeToMainWindow(const Point& point)
811 {
812     OffsetF position (static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
813     auto currentPipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
814     CHECK_NULL_RETURN(currentPipeline, position);
815     auto mainPipeline = PipelineContext::GetMainPipelineContext();
816     CHECK_NULL_RETURN(mainPipeline, position);
817     if (mainPipeline != currentPipeline) {
818         position -= (GetCurrentWindowOffset(mainPipeline) -
819                      GetCurrentWindowOffset(currentPipeline));
820     }
821     return position;
822 }
823 
IsSelectedItemNode(const RefPtr<UINode> & uiNode)824 bool DragDropFuncWrapper::IsSelectedItemNode(const RefPtr<UINode>& uiNode)
825 {
826     auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
827     CHECK_NULL_RETURN(frameNode, false);
828     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
829     CHECK_NULL_RETURN(gestureHub, false);
830     auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
831     CHECK_NULL_RETURN(eventHub, false);
832     auto dragPreview = frameNode->GetDragPreviewOption();
833     if (!dragPreview.isMultiSelectionEnabled) {
834         return false;
835     }
836     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
837     if (!isAllowedDrag) {
838         return false;
839     }
840     if (frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG) {
841         auto itemPattern = frameNode->GetPattern<GridItemPattern>();
842         CHECK_NULL_RETURN(itemPattern, false);
843         if (itemPattern->IsSelected()) {
844             return true;
845         }
846     }
847     if (frameNode->GetTag() == V2::LIST_ITEM_ETS_TAG) {
848         auto itemPattern = frameNode->GetPattern<ListItemPattern>();
849         CHECK_NULL_RETURN(itemPattern, false);
850         if (itemPattern->IsSelected()) {
851             return true;
852         }
853     }
854     return false;
855 }
856 
857 /**
858  * Do some nessessary check before returning the gesture recognizer collection result
859  * to parent during the hittest process. For example, if there is one drag operation
860  * already in our system, it is not allowed to start new interation for drag operation.
861  */
IsGlobalStatusSuitableForDragging()862 bool DragDropFuncWrapper::IsGlobalStatusSuitableForDragging()
863 {
864     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
865     CHECK_NULL_RETURN(pipeline, false);
866     auto dragDropManager = pipeline->GetDragDropManager();
867     CHECK_NULL_RETURN(dragDropManager, false);
868     if (dragDropManager->IsDragging()) {
869         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is dragging status");
870         return false;
871     }
872 
873     if (dragDropManager->IsMSDPDragging()) {
874         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is msdp dragging status");
875         return false;
876     }
877 
878     return true;
879 }
880 
IsSelfAndParentDragForbidden(const RefPtr<FrameNode> & frameNode)881 bool DragDropFuncWrapper::IsSelfAndParentDragForbidden(const RefPtr<FrameNode>& frameNode)
882 {
883     auto parent = frameNode;
884     while (parent) {
885         auto eventHub = parent->GetOrCreateEventHub<EventHub>();
886         parent = parent->GetAncestorNodeOfFrame(true);
887         if (!eventHub) {
888             continue;
889         }
890         auto gestureEventHub = eventHub->GetGestureEventHub();
891         if (!gestureEventHub) {
892             continue;
893         }
894         if (gestureEventHub->IsDragForbidden()) {
895             return true;
896         }
897     }
898     return false;
899 }
900 
IsBelongToMultiItemNode(const RefPtr<FrameNode> & frameNode)901 bool DragDropFuncWrapper::IsBelongToMultiItemNode(const RefPtr<FrameNode>& frameNode)
902 {
903     CHECK_NULL_RETURN(frameNode, false);
904     auto uiNode = frameNode->GetParent();
905     CHECK_NULL_RETURN(uiNode, false);
906     while (!IsSelectedItemNode(uiNode)) {
907         uiNode = uiNode->GetParent();
908         CHECK_NULL_RETURN(uiNode, false);
909     }
910     return true;
911 }
912 
CheckIsNeedGather(const RefPtr<FrameNode> & frameNode)913 bool DragDropFuncWrapper::CheckIsNeedGather(const RefPtr<FrameNode>& frameNode)
914 {
915     CHECK_NULL_RETURN(frameNode, false);
916     auto dragPreview = frameNode->GetDragPreviewOption();
917     if (!dragPreview.isMultiSelectionEnabled) {
918         return false;
919     }
920     return IsSelectedItemNode(frameNode);
921 }
922 
FindItemParentNode(const RefPtr<FrameNode> & frameNode)923 RefPtr<FrameNode> DragDropFuncWrapper::FindItemParentNode(const RefPtr<FrameNode>& frameNode)
924 {
925     CHECK_NULL_RETURN(frameNode, nullptr);
926     if (frameNode->GetTag() != V2::GRID_ITEM_ETS_TAG && frameNode->GetTag() != V2::LIST_ITEM_ETS_TAG) {
927         return nullptr;
928     }
929     auto parentType = frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG ? V2::GRID_ETS_TAG : V2::LIST_ETS_TAG;
930     auto uiNode = frameNode->GetParent();
931     CHECK_NULL_RETURN(uiNode, nullptr);
932     while (uiNode->GetTag() != parentType) {
933         uiNode = uiNode->GetParent();
934         CHECK_NULL_RETURN(uiNode, nullptr);
935     }
936     return AceType::DynamicCast<FrameNode>(uiNode);
937 }
938 
GetGatherNodePreviewPixelMap(const RefPtr<FrameNode> & frameNode)939 RefPtr<PixelMap> DragDropFuncWrapper::GetGatherNodePreviewPixelMap(const RefPtr<FrameNode>& frameNode)
940 {
941     CHECK_NULL_RETURN(frameNode, nullptr);
942     auto dragPreviewInfo = frameNode->GetDragPreview();
943     if (dragPreviewInfo.inspectorId != "") {
944         auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
945         return previewPixelMap;
946     }
947     if (dragPreviewInfo.pixelMap != nullptr) {
948         return dragPreviewInfo.pixelMap;
949     }
950     auto context = frameNode->GetRenderContext();
951     CHECK_NULL_RETURN(context, nullptr);
952     auto pixelMap = context->GetThumbnailPixelMap(true);
953     return pixelMap;
954 }
955 
TrySetDraggableStateAsync(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)956 void DragDropFuncWrapper::TrySetDraggableStateAsync(
957     const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
958 {
959     CHECK_NULL_VOID(frameNode);
960     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
961     CHECK_NULL_VOID(gestureHub);
962     if (frameNode->GetTag() == V2::TEXT_ETS_TAG && !gestureHub->GetIsTextDraggable()) {
963         return;
964     }
965     int64_t downTime = static_cast<int64_t>(touchRestrict.touchEvent.time.time_since_epoch().count());
966     if (DragDropGlobalController::GetInstance().IsAppGlobalDragEnabled()) {
967         InteractionInterface::GetInstance()->SetDraggableStateAsync(true, downTime / CONVERT_TIME_BASE);
968     }
969 }
970 
971 /**
972  * check the current node's status to decide if it can initiate one drag operation
973  */
IsCurrentNodeStatusSuitableForDragging(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)974 bool DragDropFuncWrapper::IsCurrentNodeStatusSuitableForDragging(
975     const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
976 {
977     CHECK_NULL_RETURN(frameNode, false);
978     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
979     CHECK_NULL_RETURN(gestureHub, false);
980 
981     if (gestureHub->IsDragForbidden() || (!frameNode->IsDraggable() && frameNode->IsCustomerSet()) ||
982         touchRestrict.inputEventType == InputEventType::AXIS ||
983         touchRestrict.touchEvent.convertInfo.first == UIInputEventType::AXIS) {
984         TAG_LOGI(AceLogTag::ACE_DRAG,
985             "No need to collect drag gestures result, drag forbidden set is %{public}d,"
986             "frameNode draggable is %{public}d, custom set is %{public}d",
987             gestureHub->IsDragForbidden(), frameNode->IsDraggable(), frameNode->IsCustomerSet());
988         return false;
989     }
990 
991     if (gestureHub->GetTextDraggable()) {
992         auto pattern = frameNode->GetPattern<TextBase>();
993         if (pattern && !pattern->IsSelected() && !pattern->CanAIEntityDrag()) {
994             TrySetDraggableStateAsync(frameNode, touchRestrict);
995             TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, text is not selected.");
996             return false;
997         }
998     }
999 
1000     if (IsSelfAndParentDragForbidden(frameNode)) {
1001         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, parent is drag forbidden.");
1002         return false;
1003     }
1004 
1005     return true;
1006 }
RecordMenuWrapperNodeForDrag(int32_t targetId)1007 void DragDropFuncWrapper::RecordMenuWrapperNodeForDrag(int32_t targetId)
1008 {
1009     auto subWindow =
1010         SubwindowManager::GetInstance()->GetSubwindowByType(Container::CurrentId(), SubwindowType::TYPE_MENU);
1011     CHECK_NULL_VOID(subWindow);
1012     auto overlayManager = subWindow->GetOverlayManager();
1013     CHECK_NULL_VOID(overlayManager);
1014     auto menuWrapperNode = overlayManager->GetMenuNode(targetId);
1015     if (!menuWrapperNode) {
1016         auto rootNode = overlayManager->GetRootNode().Upgrade();
1017         CHECK_NULL_VOID(rootNode);
1018         for (const auto& child : rootNode->GetChildren()) {
1019             auto node = AceType::DynamicCast<FrameNode>(child);
1020             if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
1021                 menuWrapperNode = node;
1022                 break;
1023             }
1024         }
1025     }
1026     CHECK_NULL_VOID(menuWrapperNode);
1027 
1028     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1029     CHECK_NULL_VOID(pipeline);
1030     auto dragDropManager = pipeline->GetDragDropManager();
1031     CHECK_NULL_VOID(dragDropManager);
1032     dragDropManager->SetMenuWrapperNode(menuWrapperNode);
1033 
1034     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1035     CHECK_NULL_VOID(mainPipeline);
1036     auto dragMainDropManager = mainPipeline->GetDragDropManager();
1037     CHECK_NULL_VOID(dragMainDropManager);
1038     dragMainDropManager->SetMenuWrapperNode(menuWrapperNode);
1039 }
1040 
GetFrameNodeByInspectorId(const std::string & inspectorId)1041 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByInspectorId(const std::string& inspectorId)
1042 {
1043     if (inspectorId.empty()) {
1044         return nullptr;
1045     }
1046 
1047     auto frameNode = Inspector::GetFrameNodeByKey(inspectorId);
1048     CHECK_NULL_RETURN(frameNode, nullptr);
1049     auto layoutProperty = frameNode->GetLayoutProperty();
1050     CHECK_NULL_RETURN(layoutProperty, nullptr);
1051 
1052     auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1053     if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1054         return nullptr;
1055     }
1056 
1057     return frameNode;
1058 }
1059 
ApplyNewestOptionExecutedFromModifierToNode(const RefPtr<FrameNode> & optionHolderNode,const RefPtr<FrameNode> & targetNode)1060 void DragDropFuncWrapper::ApplyNewestOptionExecutedFromModifierToNode(
1061     const RefPtr<FrameNode>& optionHolderNode, const RefPtr<FrameNode>& targetNode)
1062 {
1063     auto optionsFromModifier = targetNode->GetDragPreviewOption().options;
1064     ACE_UPDATE_NODE_RENDER_CONTEXT(Opacity, optionsFromModifier.opacity, targetNode);
1065     if (optionsFromModifier.blurbgEffect.backGroundEffect.radius.IsValid()) {
1066         ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundEffect, optionsFromModifier.blurbgEffect.backGroundEffect, targetNode);
1067     }
1068     if (optionsFromModifier.shadow.has_value()) {
1069         // if shadow is unfilled, set shadow after animation
1070         if (optionsFromModifier.shadow->GetIsFilled()) {
1071             ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, optionsFromModifier.shadow.value(), targetNode);
1072         }
1073     }
1074 
1075     const auto& target = targetNode->GetRenderContext();
1076     if (optionsFromModifier.borderRadius.has_value()) {
1077         target->UpdateBorderRadius(optionsFromModifier.borderRadius.value());
1078         target->UpdateClipEdge(true);
1079     }
1080 }
1081 
ResetNode(const RefPtr<FrameNode> & frameNode)1082 void DragDropFuncWrapper::ResetNode(const RefPtr<FrameNode>& frameNode)
1083 {
1084     CHECK_NULL_VOID(frameNode);
1085     bool defaultAnimationBeforeLifting = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
1086     if (!defaultAnimationBeforeLifting) {
1087         return;
1088     }
1089     auto frameContext = frameNode->GetRenderContext();
1090     CHECK_NULL_VOID(frameContext);
1091     frameContext->UpdateTransformScale({ 1.0f, 1.0f });
1092     auto layoutProperty = frameNode->GetLayoutProperty();
1093     if (layoutProperty) {
1094         layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
1095     }
1096 }
1097 
GetDragFrameNodeBorderRadius(const RefPtr<FrameNode> & frameNode)1098 BorderRadiusProperty DragDropFuncWrapper::GetDragFrameNodeBorderRadius(const RefPtr<FrameNode>& frameNode)
1099 {
1100     Dimension defaultDimension(0);
1101     BorderRadiusProperty borderRadius = { defaultDimension, defaultDimension, defaultDimension, defaultDimension };
1102     auto dragPreviewInfo = frameNode->GetDragPreview();
1103     if (dragPreviewInfo.pixelMap != nullptr) {
1104         return borderRadius;
1105     }
1106     RefPtr<FrameNode> targetNode = frameNode;
1107     if (!dragPreviewInfo.inspectorId.empty()) {
1108         targetNode = DragDropFuncWrapper::GetFrameNodeByInspectorId(dragPreviewInfo.inspectorId);
1109         CHECK_NULL_RETURN(targetNode, borderRadius);
1110     } else if (dragPreviewInfo.customNode != nullptr) {
1111         targetNode = AceType::DynamicCast<FrameNode>(dragPreviewInfo.customNode);
1112         CHECK_NULL_RETURN(targetNode, borderRadius);
1113     }
1114     auto targetNodeContext = targetNode->GetRenderContext();
1115     CHECK_NULL_RETURN(targetNodeContext, borderRadius);
1116     if (targetNodeContext->GetBorderRadius().has_value()) {
1117         borderRadius.UpdateWithCheck(targetNodeContext->GetBorderRadius().value());
1118     }
1119     return borderRadius;
1120 }
1121 
1122 /* Retrieves a preview PixelMap for a given drag event action.
1123  * This function attempts to obtain a screenshot of a frameNode associated with an inspector ID.
1124  * If the frameNode with the given ID does not exist or hasn't been rendered,
1125  * it falls back to taking a screenshot of the provided frame node.
1126  *
1127  * @param inspectorId A string representing the unique identifier for the frameNode's ID.
1128  * @param selfFrameNode A RefPtr to the frame node associated with the drag event.
1129  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found.
1130  */
GetPreviewPixelMap(const std::string & inspectorId,const RefPtr<FrameNode> & selfFrameNode)1131 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMap(
1132     const std::string& inspectorId, const RefPtr<FrameNode>& selfFrameNode)
1133 {
1134     // Attempt to retrieve the PixelMap using the inspector ID.
1135     auto previewPixelMap = GetPreviewPixelMapByInspectorId(inspectorId, selfFrameNode);
1136     // If a preview PixelMap was found, return it.
1137     if (previewPixelMap != nullptr) {
1138         return previewPixelMap;
1139     }
1140     // If not found by inspector ID, attempt to get a screenshot of the frame node.
1141     return GetScreenShotPixelMap(selfFrameNode);
1142 }
1143 
1144 /* Retrieves a preview PixelMap based on an inspector ID.
1145  * This function attempts to find a frame node associated with the given inspector ID and then takes a screenshot of it.
1146  *
1147  * @param inspectorId The unique identifier for a frameNode.
1148  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found or the ID is empty.
1149  */
GetPreviewPixelMapByInspectorId(const std::string & inspectorId,const RefPtr<FrameNode> & frameNode)1150 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMapByInspectorId(
1151     const std::string& inspectorId, const RefPtr<FrameNode>& frameNode)
1152 {
1153     // Check for an empty inspector ID and return nullptr if it is empty.
1154     if (inspectorId == "") {
1155         return nullptr;
1156     }
1157 
1158     CHECK_NULL_RETURN(frameNode, nullptr);
1159     auto pipeLine = frameNode->GetContextRefPtr();
1160     CHECK_NULL_RETURN(pipeLine, nullptr);
1161     auto rootNode = pipeLine->GetRootElement();
1162     CHECK_NULL_RETURN(rootNode, nullptr);
1163     // Retrieve the frame node using the inspector's ID.
1164     auto dragPreviewFrameNode = DragDropFuncWrapper::GetFrameNodeByKey(rootNode, inspectorId);
1165     CHECK_NULL_RETURN(dragPreviewFrameNode, nullptr);
1166 
1167     auto layoutProperty = dragPreviewFrameNode->GetLayoutProperty();
1168     CHECK_NULL_RETURN(layoutProperty, nullptr);
1169 
1170     auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1171     if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1172         return nullptr;
1173     }
1174 
1175     // Take a screenshot of the frame node and return it as a PixelMap.
1176     return GetScreenShotPixelMap(dragPreviewFrameNode);
1177 }
1178 
1179 /* Captures a screenshot of the specified frame node and encapsulates it in a PixelMap.
1180  *
1181  * @param frameNode A RefPtr reference to the frame node from which to capture the screenshot.
1182  * @return A RefPtr to a PixelMap containing the screenshot.
1183  */
GetScreenShotPixelMap(const RefPtr<FrameNode> & frameNode)1184 RefPtr<PixelMap> DragDropFuncWrapper::GetScreenShotPixelMap(const RefPtr<FrameNode>& frameNode)
1185 {
1186     // Ensure the frame node is not nulls before proceeding.
1187     CHECK_NULL_RETURN(frameNode, nullptr);
1188 
1189     // Obtain the rendering context from the frame node.
1190     auto context = frameNode->GetRenderContext();
1191 
1192     // If the rendering context is not available, return nullptr.
1193     CHECK_NULL_RETURN(context, nullptr);
1194 
1195     // Capture and return the thumbnail PixelMap from the rendering context.
1196     return context->GetThumbnailPixelMap(true);
1197 }
1198 
CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode> & frameNode,int32_t fingerId)1199 bool DragDropFuncWrapper::CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode>& frameNode, int32_t fingerId)
1200 {
1201     CHECK_NULL_RETURN(frameNode, false);
1202     auto pipeline = frameNode->GetContextRefPtr();
1203     CHECK_NULL_RETURN(pipeline, false);
1204     auto eventManager = pipeline->GetEventManager();
1205     CHECK_NULL_RETURN(eventManager, false);
1206     RefPtr<LongPressRecognizer> recognizer;
1207     auto gestureReferee = eventManager->GetGestureRefereeNG(recognizer);
1208     CHECK_NULL_RETURN(gestureReferee, false);
1209     if (gestureReferee->IsAnySucceedRecognizerExist(fingerId)) {
1210         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to get thumbnail pixelmap with success recognizer.");
1211         return true;
1212     }
1213     return false;
1214 }
1215 
CreateTiledPixelMap(const RefPtr<FrameNode> & frameNode)1216 RefPtr<PixelMap> DragDropFuncWrapper::CreateTiledPixelMap(const RefPtr<FrameNode>& frameNode)
1217 {
1218     CHECK_NULL_RETURN(frameNode, nullptr);
1219     auto pipelineContext = frameNode->GetContextRefPtr();
1220     CHECK_NULL_RETURN(pipelineContext, nullptr);
1221     auto manager = pipelineContext->GetOverlayManager();
1222     CHECK_NULL_RETURN(manager, nullptr);
1223     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1224     CHECK_NULL_RETURN(fatherNode, nullptr);
1225     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1226     CHECK_NULL_RETURN(scrollPattern, nullptr);
1227     auto children = scrollPattern->GetVisibleSelectedItems();
1228     auto pixelMapinfo = GetTiledPixelMapInfo(children);
1229     RefPtr<PixelMap> tiledPixelMap = nullptr;
1230 #if defined(PIXEL_MAP_SUPPORTED)
1231     CHECK_NULL_RETURN(pixelMapinfo, nullptr);
1232     InitializationOptions opts;
1233     opts.size.SetWidth(pixelMapinfo->pixelMapRect.GetSize().Width());
1234     opts.size.SetHeight(pixelMapinfo->pixelMapRect.GetSize().Height());
1235     opts.srcPixelFormat = pixelMapinfo->srcPixelFormat;
1236     opts.pixelFormat = pixelMapinfo->pixelFormat;
1237     opts.editable = true;
1238     opts.alphaType = pixelMapinfo->alphaType;
1239     tiledPixelMap = PixelMap::Create(opts);
1240 #endif
1241     DrawTiledPixelMap(tiledPixelMap, children, pixelMapinfo->pixelMapRect);
1242     CHECK_NULL_RETURN(tiledPixelMap, nullptr);
1243     return tiledPixelMap;
1244 }
1245 
GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>> & children)1246 std::shared_ptr<PixelMapInfo> DragDropFuncWrapper::GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>>& children)
1247 {
1248     CHECK_NULL_RETURN(children.size(), nullptr);
1249     auto minX = std::numeric_limits<float>::max();
1250     auto minY = std::numeric_limits<float>::max();
1251     auto maxX = std::numeric_limits<float>::lowest();
1252     auto maxY = std::numeric_limits<float>::lowest();
1253 
1254     for (auto& node : children) {
1255         auto context = node->GetRenderContext();
1256         CHECK_NULL_RETURN(context, nullptr);
1257         auto pixelMap = context->GetThumbnailPixelMap();
1258         auto gestureHub = node->GetOrCreateGestureEventHub();
1259         gestureHub->SetDragPreviewPixelMap(pixelMap);
1260         CHECK_NULL_RETURN(pixelMap, nullptr);
1261         auto offset = node->GetPositionToWindowWithTransform();
1262         minX = std::min(minX, offset.GetX());
1263         minY = std::min(minY, offset.GetY());
1264         maxX = std::max(maxX, offset.GetX() + pixelMap->GetWidth());
1265         maxY = std::max(maxY, offset.GetY() + pixelMap->GetHeight());
1266     }
1267     auto gestureHub = children.front()->GetOrCreateGestureEventHub();
1268     CHECK_NULL_RETURN(gestureHub, nullptr);
1269     auto dragPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1270     CHECK_NULL_RETURN(dragPreviewPixelMap, nullptr);
1271     std::shared_ptr<PixelMapInfo> pixelMapInfo = std::make_shared<PixelMapInfo>();
1272     pixelMapInfo->srcPixelFormat = dragPreviewPixelMap->GetPixelFormat();
1273     pixelMapInfo->pixelFormat = dragPreviewPixelMap->GetPixelFormat();
1274     pixelMapInfo->alphaType = dragPreviewPixelMap->GetAlphaType();
1275     pixelMapInfo->pixelMapRect.SetLeft(minX);
1276     pixelMapInfo->pixelMapRect.SetTop(minY);
1277     pixelMapInfo->pixelMapRect.SetHeight(maxY - minY);
1278     pixelMapInfo->pixelMapRect.SetWidth(maxX - minX);
1279     return pixelMapInfo;
1280 }
1281 
DrawTiledPixelMap(const RefPtr<PixelMap> & tiledPixelMap,const std::vector<RefPtr<FrameNode>> & children,const Rect & pixelMapRect)1282 void DragDropFuncWrapper::DrawTiledPixelMap(
1283     const RefPtr<PixelMap>& tiledPixelMap, const std::vector<RefPtr<FrameNode>>& children, const Rect& pixelMapRect)
1284 {
1285     CHECK_NULL_VOID(tiledPixelMap);
1286     for (auto& node : children) {
1287         auto gestureHub = node->GetOrCreateGestureEventHub();
1288         CHECK_NULL_VOID(gestureHub);
1289         auto pixelMap = gestureHub->GetDragPreviewPixelMap();
1290         CHECK_NULL_VOID(pixelMap);
1291         auto offset = node->GetPositionToWindowWithTransform();
1292         auto offsetX = offset.GetX();
1293         auto offsetY = offset.GetY();
1294         auto result =
1295             tiledPixelMap->WritePixels({ pixelMap->GetPixels(), pixelMap->GetByteCount(), 0, pixelMap->GetRowStride(),
1296                 { offsetX - pixelMapRect.GetOffset().GetX(), offsetY - pixelMapRect.GetOffset().GetY(),
1297                     pixelMap->GetWidth(), pixelMap->GetHeight() },
1298                 pixelMap->GetPixelFormat() });
1299         if (result != 0) {
1300             TAG_LOGW(AceLogTag::ACE_DRAG, "Tiled pixelmap Write is failed, the result is %{public}d", result);
1301             return;
1302         }
1303     }
1304     return;
1305 }
1306 
IsNeedCreateTiledPixelMap(const RefPtr<FrameNode> & frameNode,const RefPtr<DragEventActuator> dragEventActuator,SourceType type)1307 bool DragDropFuncWrapper::IsNeedCreateTiledPixelMap(
1308     const RefPtr<FrameNode>& frameNode, const RefPtr<DragEventActuator> dragEventActuator, SourceType type)
1309 {
1310     CHECK_NULL_RETURN(frameNode, false);
1311     CHECK_NULL_RETURN(dragEventActuator, false);
1312     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1313     CHECK_NULL_RETURN(fatherNode, false);
1314     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1315     CHECK_NULL_RETURN(scrollPattern, false);
1316     if (frameNode->GetDragPreviewOption().isMultiTiled && scrollPattern->GetVisibleSelectedItems().size() > 1 &&
1317         DragDropFuncWrapper::IsSelectedItemNode(frameNode) && !dragEventActuator->GetRestartDrag() &&
1318         type == SourceType::MOUSE) {
1319         return true;
1320     }
1321     return false;
1322 }
1323 
GetThumbnailPixelMapForCustomNodeSync(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1324 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNodeSync(
1325     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1326 {
1327 #if defined(PIXEL_MAP_SUPPORTED)
1328     CHECK_NULL_VOID(gestureHub);
1329     auto frameNode = gestureHub->GetFrameNode();
1330     CHECK_NULL_VOID(frameNode);
1331     auto dragPreviewInfo = frameNode->GetDragPreview();
1332     SnapshotParam param;
1333     auto pixelMap = ComponentSnapshot::CreateSync(dragPreviewInfo.customNode, param);
1334     CHECK_NULL_VOID(pixelMap);
1335     auto previewPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1336     gestureHub->SetPixelMap(previewPixelMap);
1337     gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1338     pixelMapCallback(previewPixelMap, false);
1339 #endif
1340 }
1341 
GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub> & gestureHub)1342 void DragDropFuncWrapper::GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub>& gestureHub)
1343 {
1344     CHECK_NULL_VOID(gestureHub);
1345     auto callback = [id = Container::CurrentId(), weakGestureHub = AceType::WeakClaim(AceType::RawPtr(gestureHub))](
1346                         const RefPtr<PixelMap>& pixelMap) {
1347         ContainerScope scope(id);
1348         if (pixelMap != nullptr) {
1349             auto taskScheduler = Container::CurrentTaskExecutor();
1350             CHECK_NULL_VOID(taskScheduler);
1351             auto gestureHub = weakGestureHub.Upgrade();
1352             CHECK_NULL_VOID(gestureHub);
1353             taskScheduler->PostTask(
1354                 [gestureHub, pixelMap]() {
1355                     CHECK_NULL_VOID(gestureHub);
1356                     gestureHub->SetPixelMap(pixelMap);
1357                     TAG_LOGI(AceLogTag::ACE_DRAG, "Set thumbnail pixelMap async success.");
1358                 },
1359                 TaskExecutor::TaskType::UI, "ArkUIDragSetPixelMap");
1360         }
1361     };
1362     auto frameNode = gestureHub->GetFrameNode();
1363     CHECK_NULL_VOID(frameNode);
1364     auto context = frameNode->GetRenderContext();
1365     CHECK_NULL_VOID(context);
1366     if (!context->CreateThumbnailPixelMapAsyncTask(true, std::move(callback))) {
1367         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1368         TAG_LOGW(AceLogTag::ACE_DRAG, "Create thumbnail pixelMap async task failed!");
1369     }
1370 }
1371 
GetThumbnailPixelMapForCustomNode(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1372 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNode(
1373     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1374 {
1375 #if defined(PIXEL_MAP_SUPPORTED)
1376     CHECK_NULL_VOID(gestureHub);
1377     auto frameNode = gestureHub->GetFrameNode();
1378     CHECK_NULL_VOID(frameNode);
1379     auto dragPreviewInfo = frameNode->GetDragPreview();
1380     auto pipeline = PipelineContext::GetCurrentContext();
1381     CHECK_NULL_VOID(pipeline);
1382     auto callback = [id = Container::CurrentId(), pipeline, gestureHub, pixelMapCallback](
1383                         std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()> finishCallback) {
1384         ContainerScope scope(id);
1385         CHECK_NULL_VOID(pipeline);
1386         auto taskScheduler = pipeline->GetTaskExecutor();
1387         CHECK_NULL_VOID(taskScheduler);
1388         taskScheduler->PostTask(
1389             [finishCallback]() {
1390                 if (finishCallback) {
1391                     finishCallback();
1392                 }
1393             },
1394             TaskExecutor::TaskType::UI, "ArkUIDragRemoveCustomNode");
1395         if (pixelMap != nullptr) {
1396             auto customPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1397             taskScheduler->PostTask(
1398                 [gestureHub, customPixelMap, pixelMapCallback]() {
1399                     CHECK_NULL_VOID(gestureHub);
1400                     gestureHub->SetPixelMap(customPixelMap);
1401                     gestureHub->SetDragPreviewPixelMap(customPixelMap);
1402                     pixelMapCallback(customPixelMap, true);
1403                 },
1404                 TaskExecutor::TaskType::UI, "ArkUIDragSetCustomPixelMap");
1405         } else {
1406             TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap is null.");
1407             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1408         }
1409     };
1410     SnapshotParam param;
1411     param.delay = CREATE_PIXELMAP_TIME;
1412     param.checkImageStatus = true;
1413     param.options.waitUntilRenderFinished = true;
1414     OHOS::Ace::NG::ComponentSnapshot::Create(dragPreviewInfo.customNode, std::move(callback), true, param);
1415     gestureHub->PrintBuilderNode(dragPreviewInfo.customNode);
1416 #endif
1417 }
1418 
GetThumbnailPixelMap(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback,bool isSync)1419 void DragDropFuncWrapper::GetThumbnailPixelMap(
1420     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback, bool isSync)
1421 {
1422     CHECK_NULL_VOID(gestureHub);
1423     auto frameNode = gestureHub->GetFrameNode();
1424     CHECK_NULL_VOID(frameNode);
1425     auto dragPreviewInfo = frameNode->GetDragPreview();
1426     if (dragPreviewInfo.inspectorId != "") {
1427         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through inspectorId.");
1428         auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
1429         gestureHub->SetPixelMap(previewPixelMap);
1430         gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1431         pixelMapCallback(previewPixelMap, false);
1432     } else if (dragPreviewInfo.pixelMap != nullptr) {
1433         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through pixelMap.");
1434         gestureHub->SetPixelMap(dragPreviewInfo.pixelMap);
1435         gestureHub->SetDragPreviewPixelMap(dragPreviewInfo.pixelMap);
1436         pixelMapCallback(dragPreviewInfo.pixelMap, false);
1437     } else if (dragPreviewInfo.customNode || (dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc)) {
1438         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through customNode.");
1439         if (!dragPreviewInfo.customNode && dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc) {
1440             dragPreviewInfo.customNode = dragPreviewInfo.buildFunc();
1441         }
1442         frameNode->SetDragPreview(dragPreviewInfo);
1443         if (isSync) {
1444             GetThumbnailPixelMapForCustomNodeSync(gestureHub, pixelMapCallback);
1445         } else {
1446             GetThumbnailPixelMapForCustomNode(gestureHub, pixelMapCallback);
1447         }
1448     } else {
1449         GetThumbnailPixelMapAsync(gestureHub);
1450     }
1451 }
1452 
GetPixelMapScale(const RefPtr<FrameNode> & frameNode)1453 float DragDropFuncWrapper::GetPixelMapScale(const RefPtr<FrameNode>& frameNode)
1454 {
1455     float scale = 1.0f;
1456     CHECK_NULL_RETURN(frameNode, scale);
1457     auto pixelMap = frameNode->GetDragPixelMap();
1458     CHECK_NULL_RETURN(pixelMap, scale);
1459     auto width = pixelMap->GetWidth();
1460     auto height = pixelMap->GetHeight();
1461     auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
1462     CHECK_NULL_RETURN(gestureEvent, scale);
1463     if (frameNode->GetDragPreviewOption().isScaleEnabled && width > 0 && height > 0) {
1464         auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
1465         CHECK_NULL_RETURN(scaleData, scale);
1466         scale = scaleData->scale;
1467     }
1468     return scale;
1469 }
1470 
IsTextCategoryComponent(const std::string & frameTag)1471 bool DragDropFuncWrapper::IsTextCategoryComponent(const std::string& frameTag)
1472 {
1473     return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1474            frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1475            frameTag == V2::RICH_EDITOR_ETS_TAG;
1476 }
1477 
GetDragDropManagerForDragAnimation(const RefPtr<PipelineBase> & context,const RefPtr<PipelineBase> & nodeContext,const RefPtr<Subwindow> & subWindow,bool isExpandDisplay,int32_t instanceId)1478 RefPtr<DragDropManager> DragDropFuncWrapper::GetDragDropManagerForDragAnimation(
1479     const RefPtr<PipelineBase>& context, const RefPtr<PipelineBase>& nodeContext,
1480     const RefPtr<Subwindow>& subWindow, bool isExpandDisplay, int32_t instanceId)
1481 {
1482     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1483     CHECK_NULL_RETURN(pipeline, nullptr);
1484     auto dragDropManager = pipeline->GetDragDropManager();
1485     auto nodePipeline = AceType::DynamicCast<PipelineContext>(nodeContext);
1486     CHECK_NULL_RETURN(nodePipeline, dragDropManager);
1487     if (nodePipeline == pipeline || isExpandDisplay) {
1488         return dragDropManager;
1489     }
1490     auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
1491         SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
1492     auto container = Container::GetContainer(mainContainerId);
1493     CHECK_NULL_RETURN(container, dragDropManager);
1494     if (!container->IsSceneBoardWindow()) {
1495         return dragDropManager;
1496     }
1497     CHECK_NULL_RETURN(subWindow, dragDropManager);
1498     subWindow->SetWindowTouchable(false);
1499     auto pixelMapOffset = dragDropManager->GetPixelMapOffset();
1500     dragDropManager = nodePipeline->GetDragDropManager();
1501     dragDropManager->SetPixelMapOffset(pixelMapOffset);
1502     return dragDropManager;
1503 }
1504 
SetMenuSubWindowTouchable(bool touchable)1505 void DragDropFuncWrapper::SetMenuSubWindowTouchable(bool touchable)
1506 {
1507     auto containerId = Container::CurrentId();
1508     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
1509     CHECK_NULL_VOID(subwindow);
1510     subwindow->SetWindowTouchable(touchable);
1511 }
1512 
HandleBackPressHideMenu()1513 void DragDropFuncWrapper::HandleBackPressHideMenu()
1514 {
1515     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1516     CHECK_NULL_VOID(mainPipeline);
1517     auto dragDropManager = mainPipeline->GetDragDropManager();
1518     CHECK_NULL_VOID(dragDropManager);
1519     dragDropManager->SetIsDragNodeNeedClean(true);
1520     auto container = AceEngine::Get().GetContainer(mainPipeline->GetInstanceId());
1521     CHECK_NULL_VOID(container);
1522     if (container->IsUIExtensionWindow()) {
1523         auto overlayManager = mainPipeline->GetOverlayManager();
1524         CHECK_NULL_VOID(overlayManager);
1525         overlayManager->RemoveGatherNode();
1526     }
1527 }
1528 
ProcessDragDropData(const RefPtr<OHOS::Ace::DragEvent> & dragEvent,std::string & udKey,DragSummaryInfo & dragSummaryInfo,int32_t & ret)1529 void DragDropFuncWrapper::ProcessDragDropData(const RefPtr<OHOS::Ace::DragEvent>& dragEvent, std::string& udKey,
1530     DragSummaryInfo& dragSummaryInfo, int32_t& ret)
1531 {
1532     CHECK_NULL_VOID(dragEvent);
1533     auto unifiedData = dragEvent->GetData();
1534     if (unifiedData) {
1535         DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
1536     }
1537     auto dataLoadParams = dragEvent->GetDataLoadParams();
1538     auto isUseDataLoadParams = dragEvent->IsUseDataLoadParams();
1539     if (dataLoadParams && isUseDataLoadParams) {
1540         ACE_SCOPED_TRACE("drag: set delayInfo to udmf");
1541         if (UdmfClient::GetInstance()->SetDelayInfo(dataLoadParams, udKey) != 0) {
1542             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set delayInfo failed, return value is %{public}d", ret);
1543             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
1544         }
1545     }
1546     if (unifiedData && !isUseDataLoadParams) {
1547         ACE_SCOPED_TRACE("drag: set drag data to udmf");
1548         if (UdmfClient::GetInstance()->SetData(unifiedData, udKey) != 0) {
1549             TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
1550             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
1551         }
1552     }
1553     ret = UdmfClient::GetInstance()->GetSummary(udKey, dragSummaryInfo);
1554     if (ret != 0) {
1555         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
1556     }
1557     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1558     CHECK_NULL_VOID(pipeline);
1559     auto dragDropManager = pipeline->GetDragDropManager();
1560     CHECK_NULL_VOID(dragDropManager);
1561     dragDropManager->SetSummaryMap(dragSummaryInfo.summary);
1562 }
1563 
FindWindowScene(RefPtr<FrameNode> & targetNode)1564 RefPtr<UINode> DragDropFuncWrapper::FindWindowScene(RefPtr<FrameNode>& targetNode)
1565 {
1566     CHECK_NULL_RETURN(targetNode, nullptr);
1567     auto pipeline = targetNode->GetContextRefPtr();
1568     CHECK_NULL_RETURN(pipeline, nullptr);
1569     auto container = Container::GetContainer(pipeline->GetInstanceId());
1570     CHECK_NULL_RETURN(container, nullptr);
1571     if (!container->IsSceneBoardWindow()) {
1572         return nullptr;
1573     }
1574     auto parent = targetNode->GetParent();
1575     while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
1576         parent = parent->GetParent();
1577     }
1578     return parent;
1579 }
1580 } // namespace OHOS::Ace::NG
1581