• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "drag_drawing.h"
17 
18 #include <atomic>
19 #include <cstdint>
20 #include <fstream>
21 #include <limits>
22 #include <shared_mutex>
23 #include <string>
24 #include <unistd.h>
25 
26 #include <dlfcn.h>
27 #include "display_info.h"
28 
29 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
30 #include "hitrace_meter.h"
31 #endif // OHOS_BUILD_ENABLE_ARKUI_X
32 #include "include/core/SkTextBlob.h"
33 #include "image_source.h"
34 #include "image_type.h"
35 #include "image_utils.h"
36 #include "input_manager.h"
37 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
38 #include "parameters.h"
39 #endif // OHOS_BUILD_ENABLE_ARKUI_X
40 #include "pointer_event.h"
41 #include "pointer_style.h"
42 #include "render/rs_filter.h"
43 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
44 #include "screen_manager.h"
45 #endif // OHOS_BUILD_ENABLE_ARKUI_X
46 #include "string_ex.h"
47 #include "transaction/rs_interfaces.h"
48 #include "ui/rs_surface_extractor.h"
49 #include "ui/rs_surface_node.h"
50 #include "ui/rs_ui_director.h"
51 
52 #include "animation_curve.h"
53 #include "devicestatus_define.h"
54 #include "drag_data_manager.h"
55 #ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
56 #include "drag_hisysevent.h"
57 #endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
58 #include "include/util.h"
59 
60 #undef LOG_TAG
61 #define LOG_TAG "DragDrawing"
62 
63 namespace OHOS {
64 namespace Msdp {
65 namespace DeviceStatus {
66 namespace {
67 constexpr int32_t BASELINE_DENSITY { 160 };
68 constexpr int32_t DEVICE_INDEPENDENT_PIXEL { 40 };
69 constexpr int32_t MAGIC_INDEPENDENT_PIXEL { 25 };
70 constexpr int32_t MAGIC_STYLE_OPT { 1 };
71 constexpr int32_t DRAG_NUM_ONE { 1 };
72 constexpr int32_t STRING_PX_LENGTH { 2 };
73 constexpr int32_t EIGHT_SIZE { 8 };
74 constexpr int32_t TWELVE_SIZE { 12 };
75 constexpr int64_t START_TIME { 181154000809 };
76 constexpr int64_t INTERVAL_TIME { 16666667 };
77 constexpr int32_t SVG_WIDTH { 40 };
78 constexpr float SCALE_THRESHOLD_EIGHT { 1.0F * INT32_MAX / (SVG_WIDTH + EIGHT_SIZE) };
79 constexpr float SCALE_THRESHOLD_TWELVE { 1.0F * INT32_MAX / (SVG_WIDTH + TWELVE_SIZE) };
80 constexpr int32_t SUCCESS_ANIMATION_DURATION { 300 };
81 constexpr int32_t ANIMATION_DURATION { 400 };
82 constexpr int32_t VIEW_BOX_POS { 2 };
83 constexpr int32_t BACKGROUND_FILTER_INDEX { 0 };
84 constexpr int32_t ASYNC_ROTATE_TIME { 150 };
85 constexpr int32_t PIXEL_MAP_INDEX { 1 };
86 constexpr int32_t DRAG_STYLE_INDEX { 2 };
87 constexpr int32_t MOUSE_ICON_INDEX { 3 };
88 constexpr int32_t SHORT_DURATION { 55 };
89 constexpr int32_t LONG_DURATION { 90 };
90 constexpr int32_t FIRST_PIXELMAP_INDEX { 0 };
91 constexpr int32_t SECOND_PIXELMAP_INDEX { 1 };
92 constexpr int32_t LAST_SECOND_PIXELMAP { 2 };
93 constexpr int32_t LAST_THIRD_PIXELMAP { 3 };
94 constexpr size_t TOUCH_NODE_MIN_COUNT { 3 };
95 constexpr size_t MOUSE_NODE_MIN_COUNT { 4 };
96 constexpr float DEFAULT_SCALING { 1.0f };
97 constexpr float BEGIN_ALPHA { 1.0f };
98 constexpr float END_ALPHA { 0.0f };
99 constexpr float START_STYLE_ALPHA { 1.0f };
100 constexpr float END_STYLE_ALPHA { 0.0f };
101 constexpr float BEGIN_SCALE { 1.0f };
102 constexpr float END_SCALE_FAIL { 1.2f };
103 constexpr float END_SCALE_SUCCESS { 0.0f };
104 #ifndef OHOS_BUILD_PC_PRODUCT
105 constexpr float DEFAULT_PIVOT { 0.0f };
106 #else
107 constexpr int32_t DOT_PER_INCH { 160 };
108 #endif // OHOS_BUILD_PC_PRODUCT
109 constexpr float HALF_PIVOT { 0.5f };
110 constexpr float START_STYLE_SCALE { 1.0f };
111 constexpr float STYLE_CHANGE_SCALE { 1.1f };
112 constexpr float STYLE_MAX_SCALE { 1.2f };
113 constexpr float STYLE_END_SCALE { 1.0f };
114 constexpr float SVG_ORIGINAL_SIZE { 40.0f };
115 constexpr float DEFAULT_POSITION_X { 0.0f };
116 constexpr float BLUR_SIGMA_SCALE { 0.57735f };
117 constexpr float RADIUS_VP { 23.0f };
118 constexpr float DEFAULT_SATURATION { 1.05f };
119 constexpr float DEFAULT_BRIGHTNESS { 1.05f };
120 constexpr float INCREASE_RATIO { 1.22f };
121 constexpr float DRAG_WINDOW_POSITION_Z { 6999.0f };
122 constexpr float DEFAULT_ANGLE { 0.0f };
123 constexpr float POSITIVE_ANGLE { 8.0f };
124 constexpr float NEGATIVE_ANGLE { -8.0f };
125 constexpr float DEFAULT_ALPHA { 1.0f };
126 constexpr float FIRST_PIXELMAP_ALPHA { 0.6f };
127 constexpr float SECOND_PIXELMAP_ALPHA { 0.3f };
128 constexpr float HALF_RATIO { 0.5f };
129 constexpr float ROTATION_0 { 0.0f };
130 constexpr float ROTATION_90 { 90.0f };
131 constexpr float ROTATION_360 { 360.0f };
132 constexpr float ROTATION_270 { 270.0f };
133 constexpr float ZOOM_IN_SCALE { 1.03f };
134 constexpr float ZOOM_OUT_SCALE { 0.9f };
135 constexpr float ZOOM_END_SCALE { 1.0f };
136 constexpr uint32_t TRANSPARENT_COLOR_ARGB { 0x00000000 };
137 constexpr int32_t DEFAULT_MOUSE_SIZE { 1 };
138 constexpr int32_t DEFAULT_COLOR_VALUE { 0 };
139 constexpr int32_t INVALID_COLOR_VALUE { -1 };
140 constexpr int32_t GLOBAL_WINDOW_ID { -1 };
141 constexpr int32_t MOUSE_DRAG_CURSOR_CIRCLE_STYLE { 41 };
142 constexpr int32_t CURSOR_CIRCLE_MIDDLE { 2 };
143 constexpr int32_t TWICE_SIZE { 2 };
144 constexpr int32_t NUM_ONE { 1 };
145 constexpr int32_t NUM_TWO { 2 };
146 constexpr int32_t NUM_FOUR { 4 };
147 constexpr int32_t ALPHA_DURATION { 350 };
148 constexpr int32_t DRAG_END_DURATION { 200 };
149 constexpr int32_t ZOOM_DURATION { 300 };
150 constexpr int32_t ZOOM_IN_DURATION { 350 };
151 constexpr int32_t ZOOM_OUT_DURATION { 250 };
152 const Rosen::RSAnimationTimingCurve CURVE =
153     Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f);
154 const Rosen::RSAnimationTimingCurve SPRING = Rosen::RSAnimationTimingCurve::CreateSpring(0.347f, 0.99f, 0.0f);
155 constexpr int32_t HEX_FF { 0xFF };
156 const std::string RENDER_THREAD_NAME { "os_dargRenderRunner" };
157 constexpr float BEZIER_000 { 0.00f };
158 constexpr float BEZIER_020 { 0.20f };
159 constexpr float BEZIER_030 { 0.30f };
160 constexpr float BEZIER_033 { 0.33f };
161 constexpr float BEZIER_040 { 0.40f };
162 constexpr float BEZIER_060 { 0.60f };
163 constexpr float BEZIER_067 { 0.67f };
164 constexpr float BEZIER_100 { 1.00f };
165 constexpr float MIN_OPACITY { 0.0f };
166 constexpr float MAX_OPACITY { 1.0f };
167 constexpr int32_t TIME_DRAG_CHANGE_STYLE { 50 };
168 constexpr int32_t TIME_DRAG_STYLE { 100 };
169 constexpr int32_t TIME_STOP_FAIL_WINDOW { 125 };
170 constexpr int32_t TIME_STOP_SUCCESS_WINDOW { 250 };
171 constexpr int32_t TIME_STOP_SUCCESS_STYLE { 150 };
172 constexpr int32_t TIME_STOP { 0 };
173 constexpr int64_t TIME_SLEEP { 30000 };
174 constexpr int32_t INTERRUPT_SCALE { 15 };
175 constexpr int32_t TIMEOUT_MS { 500 };
176 constexpr float MAX_SCREEN_WIDTH_SM { 600.0f };
177 constexpr float MAX_SCREEN_WIDTH_MD { 840.0f };
178 constexpr float MAX_SCREEN_WIDTH_LG { 1440.0f };
179 constexpr int32_t SCALE_TYPE_FIRST = 2;
180 constexpr int32_t SCALE_TYPE_SECOND = 3;
181 constexpr int32_t SCALE_TYPE_THIRD = 4;
182 const std::string THREAD_NAME { "os_AnimationEventRunner" };
183 const std::string SUPER_HUB_THREAD_NAME { "os_SuperHubEventRunner" };
184 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
185 const std::string COPY_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
186 const std::string COPY_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_One_Drag.svg" };
187 const std::string FORBID_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_Drag.svg" };
188 const std::string FORBID_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_One_Drag.svg" };
189 const std::string MOVE_DRAG_PATH { "/system/etc/device_status/drag_icon/Move_Drag.svg" };
190 #else
191 const std::string COPY_DRAG_NAME { "/base/media/Copy_Drag.svg" };
192 const std::string COPY_ONE_DRAG_NAME { "/base/media/Copy_One_Drag.svg" };
193 const std::string FORBID_DRAG_NAME { "/base/media/Forbid_Drag.svg" };
194 const std::string FORBID_ONE_DRAG_NAME { "/base/media/Forbid_One_Drag.svg" };
195 const std::string MOVE_DRAG_NAME { "/base/media/Move_Drag.svg" };
196 #endif // OHOS_BUILD_ENABLE_ARKUI_X
197 const std::string MOUSE_DRAG_DEFAULT_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Default.svg" };
198 const std::string MOUSE_DRAG_MAGIC_DEFAULT_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Magic_Default.svg" };
199 const std::string MOUSE_DRAG_CURSOR_CIRCLE_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Cursor_Circle.png" };
200 const std::string DRAG_DROP_EXTENSION_SO_PATH { "/system/lib64/drag_drop_ext/libdrag_drop_ext.z.so" };
201 const std::string BIG_FOLDER_LABEL { "scb_folder" };
202 struct DrawingInfo g_drawingInfo;
203 static std::shared_mutex g_pixelMapLock;
204 struct DragData g_dragDataForSuperHub;
205 
CheckNodesValid()206 bool CheckNodesValid()
207 {
208     FI_HILOGD("enter");
209     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
210         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
211         return false;
212     } else if (g_drawingInfo.nodes.empty() || g_drawingInfo.nodes[DRAG_STYLE_INDEX] == nullptr) {
213         FI_HILOGE("Nodes invalid");
214         return false;
215     }
216 
217 #ifndef OHOS_BUILD_PC_PRODUCT
218     if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
219         (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT)) {
220         FI_HILOGE("Nodes size invalid when mouse type, node size:%{public}zu", g_drawingInfo.nodes.size());
221         return false;
222     }
223 #endif // OHOS_BUILD_PC_PRODUCT
224 
225     if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
226         (g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
227         FI_HILOGE("Nodes size invalid when touchscreen type, node size:%{public}zu", g_drawingInfo.nodes.size());
228         return false;
229     }
230     return true;
231 }
232 
GetScaling()233 float GetScaling()
234 {
235     if (g_drawingInfo.isExistScalingValue) {
236         return g_drawingInfo.scalingValue;
237     }
238 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
239 #ifndef OHOS_BUILD_PC_PRODUCT
240     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
241     if (display == nullptr) {
242         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
243         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
244         if (display == nullptr) {
245             FI_HILOGE("Get display info failed, display is nullptr");
246             return DEFAULT_SCALING;
247         }
248     }
249     int32_t deviceDpi = display->GetDpi();
250 #else
251     sptr<Rosen::DisplayInfo> displayInfo =
252         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
253     if (displayInfo == nullptr) {
254         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
255         displayInfo = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
256         if (displayInfo == nullptr) {
257             FI_HILOGE("Get display info failed, display is nullptr");
258             return DEFAULT_SCALING;
259         }
260     }
261     int32_t deviceDpi = displayInfo->GetVirtualPixelRatio() * DOT_PER_INCH;
262 #endif // OHOS_BUILD_PC_PRODUCT
263 #else
264     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
265     if (display == nullptr) {
266         FI_HILOGE("Get display info failed, display is nullptr");
267         return DEFAULT_SCALING;
268     }
269     sptr<Rosen::DisplayInfo> info = display->GetDisplayInfo();
270     if (info == nullptr) {
271         FI_HILOGE("Get info failed, info is nullptr");
272         return DEFAULT_SCALING;
273     }
274     int32_t deviceDpi = info->GetDensityDpi();
275 #endif // OHOS_BUILD_ENABLE_ARKUI_X
276     FI_HILOGD("displayId:%{public}d, deviceDpi:%{public}d", g_drawingInfo.displayId, deviceDpi);
277     if (deviceDpi < -std::numeric_limits<float>::epsilon()) {
278         FI_HILOGE("Invalid deviceDpi:%{public}d", deviceDpi);
279         return DEFAULT_SCALING;
280     }
281     g_drawingInfo.scalingValue = (1.0 * deviceDpi * DEVICE_INDEPENDENT_PIXEL / BASELINE_DENSITY) / SVG_ORIGINAL_SIZE;
282     g_drawingInfo.isExistScalingValue = true;
283     return g_drawingInfo.scalingValue;
284 }
285 } // namespace
286 
287 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
Init(const DragData & dragData,IContext * context,bool isLongPressDrag)288 int32_t DragDrawing::Init(const DragData &dragData, IContext* context, bool isLongPressDrag)
289 #else
290 int32_t DragDrawing::Init(const DragData &dragData, bool isLongPressDrag)
291 #endif // OHOS_BUILD_ENABLE_ARKUI_X
292 {
293     FI_HILOGI("enter");
294     int32_t checkDragDataResult = CheckDragData(dragData);
295     if (INIT_SUCCESS != checkDragDataResult) {
296         return checkDragDataResult;
297     }
298     InitDrawingInfo(dragData, isLongPressDrag);
299     UpdateDragDataForSuperHub(dragData);
300     CreateWindow();
301     CHKPR(g_drawingInfo.surfaceNode, INIT_FAIL);
302     if (InitLayer() != RET_OK) {
303         FI_HILOGE("Init layer failed");
304         return INIT_FAIL;
305     }
306     DragAnimationData dragAnimationData;
307     if (!CheckNodesValid() || InitDragAnimationData(dragAnimationData) != RET_OK) {
308         FI_HILOGE("Init drag animation data or check nodes valid failed");
309         return INIT_FAIL;
310     }
311 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
312     LoadDragDropLib();
313 #endif // OHOS_BUILD_ENABLE_ARKUI_X
314     OnStartDrag(dragAnimationData);
315     if (!g_drawingInfo.multiSelectedNodes.empty()) {
316         g_drawingInfo.isCurrentDefaultStyle = true;
317         UpdateDragStyle(DragCursorStyle::MOVE);
318     }
319 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
320     context_ = context;
321 #endif // OHOS_BUILD_ENABLE_ARKUI_X
322     CHKPR(rsUiDirector_, INIT_FAIL);
323     if (g_drawingInfo.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
324         rsUiDirector_->SendMessages();
325         return INIT_SUCCESS;
326     }
327 
328 #ifndef OHOS_BUILD_PC_PRODUCT
329     if (DrawMouseIcon() != RET_OK) {
330         FI_HILOGE("Draw mouse icon failed");
331         return INIT_FAIL;
332     }
333 #endif // OHOS_BUILD_PC_PRODUCT
334 
335     rsUiDirector_->SendMessages();
336     FI_HILOGI("leave");
337     return INIT_SUCCESS;
338 }
339 
CheckDragData(const DragData & dragData)340 int32_t DragDrawing::CheckDragData(const DragData &dragData)
341 {
342     if (g_drawingInfo.isRunning) {
343         FI_HILOGE("Drag drawing is running, can not init again");
344         return INIT_CANCEL;
345     }
346     if (dragData.shadowInfos.empty()) {
347         FI_HILOGE("ShadowInfos is empty");
348         return INIT_FAIL;
349     }
350     for (const auto &shadowInfo : dragData.shadowInfos) {
351         CHKPR(shadowInfo.pixelMap, INIT_FAIL);
352     }
353     if ((dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
354         (dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN)) {
355         FI_HILOGE("Invalid sourceType:%{public}d", dragData.sourceType);
356         return INIT_FAIL;
357     }
358     if (dragData.dragNum < 0) {
359         FI_HILOGE("Invalid dragNum:%{public}d", dragData.dragNum);
360         return INIT_FAIL;
361     }
362     return INIT_SUCCESS;
363 }
364 
Draw(int32_t displayId,int32_t displayX,int32_t displayY,bool isNeedAdjustDisplayXY,bool isMultiSelectedAnimation)365 void DragDrawing::Draw(int32_t displayId, int32_t displayX, int32_t displayY, bool isNeedAdjustDisplayXY,
366     bool isMultiSelectedAnimation)
367 {
368     if (screenRotateState_) {
369         FI_HILOGD("Doing screen rotation, ignore draw drag window");
370         return;
371     }
372     if (isRunningRotateAnimation_) {
373         FI_HILOGD("Doing rotate drag window animate, ignore draw drag window");
374         return;
375     }
376     if (displayId < 0) {
377         FI_HILOGE("Invalid displayId:%{public}d", displayId);
378         return;
379     }
380     int32_t mousePositionX = displayX;
381     int32_t mousePositionY = displayY;
382     if (isNeedAdjustDisplayXY) {
383         RotateDisplayXY(displayX, displayY);
384         mousePositionX = displayX;
385         mousePositionY = displayY;
386         g_drawingInfo.currentPositionX = static_cast<float>(displayX);
387         g_drawingInfo.currentPositionY = static_cast<float>(displayY);
388         AdjustRotateDisplayXY(displayX, displayY);
389     }
390     g_drawingInfo.displayId = displayId;
391     g_drawingInfo.displayX = displayX;
392     g_drawingInfo.displayY = displayY;
393     if (displayX < 0) {
394         g_drawingInfo.displayX = 0;
395     }
396     if (displayY < 0) {
397         g_drawingInfo.displayY = 0;
398     }
399     int32_t adjustSize = TWELVE_SIZE * GetScaling();
400     int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
401     int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
402     CHKPV(g_drawingInfo.parentNode);
403     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
404     CHKPV(currentPixelMap);
405     g_drawingInfo.parentNode->SetBounds(positionX, positionY, currentPixelMap->GetWidth(),
406         currentPixelMap->GetHeight() + adjustSize);
407     g_drawingInfo.parentNode->SetFrame(positionX, positionY, currentPixelMap->GetWidth(),
408         currentPixelMap->GetHeight() + adjustSize);
409 #ifndef OHOS_BUILD_PC_PRODUCT
410     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
411         DoDrawMouse(mousePositionX, mousePositionY);
412     }
413 #endif // OHOS_BUILD_PC_PRODUCT
414     if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
415         MultiSelectedAnimation(positionX, positionY, adjustSize, isMultiSelectedAnimation);
416     }
417     Rosen::RSTransaction::FlushImplicitTransaction();
418 }
419 
UpdateDragPosition(int32_t displayId,float displayX,float displayY)420 void DragDrawing::UpdateDragPosition(int32_t displayId, float displayX, float displayY)
421 {
422     if (screenRotateState_) {
423         FI_HILOGD("Doing screen rotation, ignore update drag position");
424         return;
425     }
426     if (displayId < 0) {
427         FI_HILOGE("Invalid displayId:%{public}d", displayId);
428         return;
429     }
430     RotatePosition(displayX, displayY);
431     g_drawingInfo.currentPositionX = displayX;
432     g_drawingInfo.currentPositionY = displayY;
433     g_drawingInfo.displayId = displayId;
434     g_drawingInfo.displayX = static_cast<int32_t>(displayX);
435     g_drawingInfo.displayY = static_cast<int32_t>(displayY);
436 #ifndef OHOS_BUILD_PC_PRODUCT
437     float mousePositionX = displayX;
438     float mousePositionY = displayY;
439 #endif // OHOS_BUILD_PC_PRODUCT
440     AdjustRotateDisplayXY(displayX, displayY);
441     g_drawingInfo.x = displayX;
442     g_drawingInfo.y = displayY;
443     if (displayX < 0) {
444         g_drawingInfo.displayX = 0;
445     }
446     if (displayY < 0) {
447         g_drawingInfo.displayY = 0;
448     }
449     float adjustSize = TWELVE_SIZE * GetScaling();
450     float positionX = g_drawingInfo.x + g_drawingInfo.pixelMapX;
451     float positionY = g_drawingInfo.y + g_drawingInfo.pixelMapY - adjustSize;
452     auto parentNode = g_drawingInfo.parentNode;
453     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
454     CHKPV(parentNode);
455     CHKPV(currentPixelMap);
456     parentNode->SetBounds(positionX, positionY, currentPixelMap->GetWidth(),
457         currentPixelMap->GetHeight() + adjustSize);
458     parentNode->SetFrame(positionX, positionY, currentPixelMap->GetWidth(),
459         currentPixelMap->GetHeight() + adjustSize);
460 #ifndef OHOS_BUILD_PC_PRODUCT
461     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
462         UpdateMousePosition(mousePositionX, mousePositionY);
463     }
464 #endif // OHOS_BUILD_PC_PRODUCT
465     if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
466         DoMultiSelectedAnimation(positionX, positionY, adjustSize);
467     }
468     if (rsUiDirector_ != nullptr) {
469         rsUiDirector_->SendMessages();
470     } else {
471         FI_HILOGE("rsUiDirector_ is nullptr");
472     }
473 }
474 
DoMultiSelectedAnimation(float positionX,float positionY,float adjustSize,bool isMultiSelectedAnimation)475 void DragDrawing::DoMultiSelectedAnimation(float positionX, float positionY, float adjustSize,
476     bool isMultiSelectedAnimation)
477 {
478     if (isMultiSelectedAnimation) {
479         isMultiSelectedAnimation = needMultiSelectedAnimation_;
480     }
481     size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
482     size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
483     for (size_t i = 0; (i < multiSelectedNodesSize) && (i < multiSelectedPixelMapsSize); ++i) {
484         std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
485         std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
486         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
487         CHKPV(currentPixelMap);
488         CHKPV(multiSelectedNode);
489         CHKPV(multiSelectedPixelMap);
490         float multiSelectedPositionX = positionX + (static_cast<float>(currentPixelMap->GetWidth()) / TWICE_SIZE) -
491             (static_cast<float>(multiSelectedPixelMap->GetWidth()) / TWICE_SIZE);
492         float multiSelectedPositionY = positionY + (static_cast<float>(currentPixelMap->GetHeight()) / TWICE_SIZE) -
493             (static_cast<float>(multiSelectedPixelMap->GetHeight()) / TWICE_SIZE - adjustSize);
494         if (isMultiSelectedAnimation) {
495             Rosen::RSAnimationTimingProtocol protocol;
496             if (i == FIRST_PIXELMAP_INDEX) {
497                 protocol.SetDuration(SHORT_DURATION);
498             } else {
499                 protocol.SetDuration(LONG_DURATION);
500             }
501             Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
502                 multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
503                     multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
504                 multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
505                     multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
506             }, []() { FI_HILOGD("DoMultiSelectedAnimation end"); });
507         } else {
508             multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
509                 multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
510             multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
511                 multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
512         }
513     }
514 }
515 
UpdateDragStyle(DragCursorStyle style)516 int32_t DragDrawing::UpdateDragStyle(DragCursorStyle style)
517 {
518     FI_HILOGD("style:%{public}d", style);
519     if ((style < DragCursorStyle::DEFAULT) || (style > DragCursorStyle::MOVE)) {
520 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
521 #ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
522         DragDFX::WriteUpdateDragStyle(style, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
523 #endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
524 #endif // OHOS_BUILD_ENABLE_ARKUI_X
525         FI_HILOGE("Invalid style:%{public}d", style);
526         return RET_ERR;
527     }
528     if ((style == DragCursorStyle::DEFAULT) ||
529         ((style == DragCursorStyle::MOVE) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE))) {
530         return UpdateDefaultDragStyle(style);
531     }
532     return UpdateValidDragStyle(style);
533 }
534 
UpdateShadowPic(const ShadowInfo & shadowInfo)535 int32_t DragDrawing::UpdateShadowPic(const ShadowInfo &shadowInfo)
536 {
537     FI_HILOGD("enter");
538     CHKPR(shadowInfo.pixelMap, RET_ERR);
539     DragDrawing::UpdataGlobalPixelMapLocked(shadowInfo.pixelMap);
540     g_drawingInfo.pixelMapX = shadowInfo.x;
541     g_drawingInfo.pixelMapY = shadowInfo.y;
542     if (!CheckNodesValid()) {
543         FI_HILOGE("Check nodes valid failed");
544         return RET_ERR;
545     }
546     if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
547         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
548         return RET_ERR;
549     }
550     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
551     CHKPR(shadowNode, RET_ERR);
552     DrawShadow(shadowNode);
553     float scalingValue = GetScaling();
554     if (SCALE_THRESHOLD_TWELVE < scalingValue || fabsf(SCALE_THRESHOLD_TWELVE - scalingValue) < EPSILON) {
555         FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
556         return RET_ERR;
557     }
558 #ifndef OHOS_BUILD_PC_PRODUCT
559     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
560         DrawMouseIcon();
561     }
562 #endif // OHOS_BUILD_PC_PRODUCT
563     ProcessFilter();
564     Draw(g_drawingInfo.displayId, g_drawingInfo.displayX, g_drawingInfo.displayY, false);
565     RotateDragWindow(rotation_);
566     Rosen::RSTransaction::FlushImplicitTransaction();
567     CHKPR(rsUiDirector_, RET_ERR);
568     rsUiDirector_->SendMessages();
569     FI_HILOGD("leave");
570     return RET_OK;
571 }
572 
UpdatePixelMapsAngleAndAlpha()573 int32_t DragDrawing::UpdatePixelMapsAngleAndAlpha()
574 {
575     FI_HILOGD("enter");
576     size_t mulNodesSize = g_drawingInfo.multiSelectedNodes.size();
577     if (mulNodesSize <= 0) {
578         FI_HILOGE("No pixelmap add");
579         return RET_ERR;
580     }
581     if (mulNodesSize == 1) {
582         g_drawingInfo.multiSelectedNodes.front()->SetRotation(POSITIVE_ANGLE);
583         g_drawingInfo.multiSelectedNodes.front()->SetAlpha(FIRST_PIXELMAP_ALPHA);
584     } else if (mulNodesSize == LAST_SECOND_PIXELMAP) {
585         g_drawingInfo.multiSelectedNodes.back()->SetRotation(NEGATIVE_ANGLE);
586         g_drawingInfo.multiSelectedNodes.back()->SetAlpha(SECOND_PIXELMAP_ALPHA);
587     } else {
588         g_drawingInfo.rootNode->RemoveChild(g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_THIRD_PIXELMAP]);
589         g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_SECOND_PIXELMAP ]->SetRotation(POSITIVE_ANGLE);
590         g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_SECOND_PIXELMAP ]->SetAlpha(FIRST_PIXELMAP_ALPHA);
591         g_drawingInfo.multiSelectedNodes.back()->SetRotation(NEGATIVE_ANGLE);
592         g_drawingInfo.multiSelectedNodes.back()->SetAlpha(SECOND_PIXELMAP_ALPHA);
593     }
594     FI_HILOGD("leave");
595     return RET_OK;
596 }
597 
UpdatePixeMapDrawingOrder()598 int32_t DragDrawing::UpdatePixeMapDrawingOrder()
599 {
600     FI_HILOGD("enter");
601     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
602     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
603     CHKPR(pixelMapNode, RET_ERR);
604     CHKPR(dragStyleNode, RET_ERR);
605     CHKPR(g_drawingInfo.parentNode, RET_ERR);
606     CHKPR(g_drawingInfo.rootNode, RET_ERR);
607     g_drawingInfo.multiSelectedNodes.emplace_back(pixelMapNode);
608     g_drawingInfo.parentNode->RemoveChild(dragStyleNode);
609     g_drawingInfo.parentNode->RemoveChild(pixelMapNode);
610 
611     int32_t adjustSize = TWELVE_SIZE * GetScaling();
612     int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
613     int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
614     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
615     int32_t pixelMapWidth = currentPixelMap->GetWidth();
616     int32_t pixelMapHeight = currentPixelMap->GetHeight();
617     pixelMapNode->SetBounds(positionX, positionY + adjustSize, pixelMapWidth, pixelMapHeight);
618     pixelMapNode->SetFrame(positionX, positionY + adjustSize, pixelMapWidth, pixelMapHeight);
619 
620     std::shared_ptr<Rosen::RSCanvasNode> addSelectedNode = Rosen::RSCanvasNode::Create();
621     CHKPR(addSelectedNode, RET_ERR);
622     g_drawingInfo.nodes[PIXEL_MAP_INDEX] = addSelectedNode;
623     g_drawingInfo.parentNode->AddChild(addSelectedNode);
624     g_drawingInfo.parentNode->AddChild(dragStyleNode);
625     g_drawingInfo.rootNode->AddChild(g_drawingInfo.multiSelectedNodes.back());
626     g_drawingInfo.rootNode->RemoveChild(g_drawingInfo.parentNode);
627     g_drawingInfo.rootNode->AddChild(g_drawingInfo.parentNode);
628 #ifndef OHOS_BUILD_PC_PRODUCT
629     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
630         std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
631         CHKPR(mouseIconNode, RET_ERR);
632         g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
633         g_drawingInfo.rootNode->AddChild(mouseIconNode);
634     }
635 #endif // OHOS_BUILD_PC_PRODUCT
636     if (UpdatePixelMapsAngleAndAlpha() != RET_OK) {
637         FI_HILOGE("setPixelMapsAngleAndAlpha failed");
638         return RET_ERR;
639     }
640     DrawShadow(pixelMapNode);
641     FI_HILOGD("leave");
642     return RET_OK;
643 }
644 
AddSelectedPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)645 int32_t DragDrawing::AddSelectedPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
646 {
647     FI_HILOGD("enter");
648     CHKPR(pixelMap, RET_ERR);
649     if (!CheckNodesValid()) {
650         FI_HILOGE("Check nodes valid failed");
651         return RET_ERR;
652     }
653 
654     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
655     g_drawingInfo.multiSelectedPixelMaps.emplace_back(currentPixelMap);
656     DragDrawing::UpdataGlobalPixelMapLocked(pixelMap);
657     if (UpdatePixeMapDrawingOrder() != RET_OK) {
658         FI_HILOGE("Update pixeMap drawing order failed");
659         return RET_ERR;
660     }
661     Draw(g_drawingInfo.displayId, g_drawingInfo.displayX, g_drawingInfo.displayY, false);
662     g_drawingInfo.currentDragNum = g_drawingInfo.multiSelectedPixelMaps.size() + 1;
663     if (UpdateDragStyle(g_drawingInfo.currentStyle) != RET_OK) {
664         FI_HILOGE("Update drag style failed");
665         return RET_ERR;
666     }
667     Rosen::RSTransaction::FlushImplicitTransaction();
668     FI_HILOGD("leave");
669     return RET_OK;
670 }
671 
672 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
OnDragSuccess(IContext * context)673 void DragDrawing::OnDragSuccess(IContext* context)
674 #else
675 void DragDrawing::OnDragSuccess()
676 #endif // OHOS_BUILD_ENABLE_ARKUI_X
677 {
678     FI_HILOGI("enter");
679     if (!CheckNodesValid()) {
680         FI_HILOGE("Check nodes valid failed");
681         return;
682     }
683     if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX || g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
684         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
685         return;
686     }
687     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
688     CHKPV(shadowNode);
689     std::shared_ptr<Rosen::RSCanvasNode> styleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
690     CHKPV(styleNode);
691 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
692     g_drawingInfo.context = context;
693 #endif // OHOS_BUILD_ENABLE_ARKUI_X
694     OnStopDragSuccess(shadowNode, styleNode);
695     FI_HILOGI("leave");
696 }
697 
LongPressDragFail()698 void DragDrawing::LongPressDragFail()
699 {
700     FI_HILOGD("enter");
701     if (!CheckNodesValid()) {
702         FI_HILOGE("Check nodes valid failed");
703         return;
704     }
705     ResetAnimationParameter();
706     Rosen::RSAnimationTimingProtocol protocolAlphaChanged;
707     protocolAlphaChanged.SetDuration(DRAG_END_DURATION);
708     Rosen::RSNode::Animate(protocolAlphaChanged, CURVE, [&]() {
709         CHKPV(g_drawingInfo.parentNode);
710         g_drawingInfo.parentNode->SetAlpha(END_ALPHA);
711         if (!g_drawingInfo.multiSelectedNodes.empty()) {
712             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
713             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
714                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
715                 CHKPV(multiSelectedNode);
716                 multiSelectedNode->SetAlpha(END_ALPHA);
717             }
718         }
719         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
720         CHKPV(dragStyleNode);
721         dragStyleNode->SetAlpha(END_ALPHA);
722     },  []() { FI_HILOGD("AlphaChanged end"); });
723 
724     Rosen::RSAnimationTimingProtocol protocolZoomIn;
725     protocolZoomIn.SetDuration(DRAG_END_DURATION);
726     Rosen::RSNode::Animate(protocolZoomIn, CURVE, [&]() {
727         CHKPV(g_drawingInfo.parentNode);
728         g_drawingInfo.parentNode->SetScale(ZOOM_END_SCALE);
729         if (!g_drawingInfo.multiSelectedNodes.empty()) {
730             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
731             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
732                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
733                 CHKPV(multiSelectedNode);
734                 multiSelectedNode->SetScale(ZOOM_END_SCALE);
735             }
736         }
737         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
738         CHKPV(dragStyleNode);
739         dragStyleNode->SetScale(ZOOM_END_SCALE);
740     },  [&]() {
741         FI_HILOGD("ZoomIn end");
742         ResetAnimationFlag();
743     });
744     g_drawingInfo.startNum = START_TIME;
745     g_drawingInfo.needDestroyDragWindow = false;
746     StartVsync();
747     FI_HILOGD("leave");
748 }
749 
750 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
OnDragFail(IContext * context,bool isLongPressDrag)751 void DragDrawing::OnDragFail(IContext* context, bool isLongPressDrag)
752 #else
753 void DragDrawing::OnDragFail()
754 #endif // OHOS_BUILD_ENABLE_ARKUI_X
755 {
756     FI_HILOGI("enter");
757 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
758     if (isLongPressDrag) {
759         LongPressDragFail();
760         return;
761     }
762 #endif // OHOS_BUILD_ENABLE_ARKUI_X
763     std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode = g_drawingInfo.surfaceNode;
764     CHKPV(surfaceNode);
765     std::shared_ptr<Rosen::RSNode> rootNode = g_drawingInfo.rootNode;
766     CHKPV(rootNode);
767 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
768     g_drawingInfo.context = context;
769 #endif // OHOS_BUILD_ENABLE_ARKUI_X
770     OnStopDragFail(surfaceNode, rootNode);
771     FI_HILOGI("leave");
772 }
773 
EraseMouseIcon()774 void DragDrawing::EraseMouseIcon()
775 {
776     FI_HILOGI("enter");
777     if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
778         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
779         return;
780     }
781     if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
782         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
783         return;
784     }
785     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
786     CHKPV(mouseIconNode);
787     if (drawMouseIconModifier_ != nullptr) {
788         mouseIconNode->RemoveModifier(drawMouseIconModifier_);
789         drawMouseIconModifier_ = nullptr;
790     }
791     CHKPV(g_drawingInfo.rootNode);
792     g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
793     CHKPV(rsUiDirector_);
794     rsUiDirector_->SendMessages();
795     FI_HILOGI("leave");
796 }
797 
DestroyDragWindow()798 void DragDrawing::DestroyDragWindow()
799 {
800     FI_HILOGI("enter");
801     ResetParameter();
802     RemoveModifier();
803     ClearMultiSelectedData();
804     if (!g_drawingInfo.nodes.empty()) {
805         g_drawingInfo.nodes.clear();
806         g_drawingInfo.nodes.shrink_to_fit();
807     }
808     if (g_drawingInfo.parentNode != nullptr) {
809         g_drawingInfo.parentNode->ClearChildren();
810         g_drawingInfo.parentNode.reset();
811         g_drawingInfo.parentNode = nullptr;
812     }
813     if (g_drawingInfo.rootNode != nullptr) {
814         g_drawingInfo.rootNode->ClearChildren();
815         g_drawingInfo.rootNode.reset();
816         g_drawingInfo.rootNode = nullptr;
817     }
818     if (g_drawingInfo.surfaceNode != nullptr) {
819         g_drawingInfo.surfaceNode->DetachFromWindowContainer(screenId_);
820         screenId_ = 0;
821         g_drawingInfo.displayId = -1;
822         g_drawingInfo.surfaceNode = nullptr;
823         Rosen::RSTransaction::FlushImplicitTransaction();
824     }
825 #ifdef OHOS_BUILD_ENABLE_ARKUI_X
826     CHKPV(callback_);
827     callback_();
828     window_ = nullptr;
829     g_dragDataForSuperHub = {};
830 #endif // OHOS_BUILD_ENABLE_ARKUI_X
831     CHKPV(rsUiDirector_);
832     rsUiDirector_->SetRoot(-1);
833     rsUiDirector_->SendMessages();
834     FI_HILOGI("leave");
835 }
836 
UpdateDrawingState()837 void DragDrawing::UpdateDrawingState()
838 {
839     FI_HILOGD("enter");
840     g_drawingInfo.isRunning = false;
841     FI_HILOGD("leave");
842 }
843 
UpdateDragWindowState(bool visible,bool isZoomInAndAlphaChanged)844 void DragDrawing::UpdateDragWindowState(bool visible, bool isZoomInAndAlphaChanged)
845 {
846     CHKPV(g_drawingInfo.surfaceNode);
847     if (visible && isZoomInAndAlphaChanged) {
848         FI_HILOGI("UpdateDragWindowState in animation");
849         if (!CheckNodesValid()) {
850             FI_HILOGE("Check nodes valid failed");
851             return;
852         }
853         CHKPV(g_drawingInfo.parentNode);
854         g_drawingInfo.parentNode->SetAlpha(0.0f);
855         if (!g_drawingInfo.multiSelectedNodes.empty()) {
856             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
857             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
858                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
859                 CHKPV(multiSelectedNode);
860                 multiSelectedNode->SetAlpha(0.0f);
861             }
862         }
863         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
864         CHKPV(dragStyleNode);
865         dragStyleNode->SetAlpha(0.0f);
866         g_drawingInfo.surfaceNode->SetVisible(true);
867         LongPressDragAnimation();
868     } else {
869         g_drawingInfo.surfaceNode->SetVisible(visible);
870     }
871     FI_HILOGI("Drag surfaceNode %{public}s success", visible ? "show" : "hide");
872     Rosen::RSTransaction::FlushImplicitTransaction();
873 }
874 
LongPressDragAlphaAnimation()875 void DragDrawing::LongPressDragAlphaAnimation()
876 {
877     FI_HILOGD("enter");
878     if (!CheckNodesValid()) {
879         FI_HILOGE("Check nodes valid failed");
880         return;
881     }
882     Rosen::RSAnimationTimingProtocol protocolAlphaChanged;
883     protocolAlphaChanged.SetDuration(ALPHA_DURATION);
884     Rosen::RSNode::Animate(protocolAlphaChanged, CURVE, [&]() {
885         CHKPV(g_drawingInfo.parentNode);
886         g_drawingInfo.parentNode->SetAlpha(1.0f);
887         if (!g_drawingInfo.multiSelectedNodes.empty()) {
888             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
889             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
890                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
891                 CHKPV(multiSelectedNode);
892                 multiSelectedNode->SetAlpha(1.0f);
893             }
894         }
895         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
896         CHKPV(dragStyleNode);
897         dragStyleNode->SetAlpha(1.0f);
898     },  []() { FI_HILOGD("AlphaChanged end"); });
899 }
900 
LongPressDragZoomInAnimation()901 void DragDrawing::LongPressDragZoomInAnimation()
902 {
903     FI_HILOGD("enter");
904     if (!CheckNodesValid()) {
905         FI_HILOGE("Check nodes valid failed");
906         return;
907     }
908     CHKPV(g_drawingInfo.parentNode);
909     g_drawingInfo.parentNode->SetScale(1.0f);
910     if (!g_drawingInfo.multiSelectedNodes.empty()) {
911         size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
912         for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
913             std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
914             CHKPV(multiSelectedNode);
915             multiSelectedNode->SetScale(1.0f);
916         }
917     }
918     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
919     CHKPV(dragStyleNode);
920     dragStyleNode->SetScale(1.0f);
921 
922     Rosen::RSAnimationTimingProtocol protocolZoomIn;
923     protocolZoomIn.SetDuration(ZOOM_IN_DURATION);
924     Rosen::RSNode::Animate(protocolZoomIn, CURVE, [&]() {
925         CHKPV(g_drawingInfo.parentNode);
926         g_drawingInfo.parentNode->SetScale(ZOOM_IN_SCALE);
927         if (!g_drawingInfo.multiSelectedNodes.empty()) {
928             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
929             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
930                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
931                 CHKPV(multiSelectedNode);
932                 multiSelectedNode->SetScale(ZOOM_IN_SCALE);
933             }
934         }
935         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
936         CHKPV(dragStyleNode);
937         dragStyleNode->SetScale(ZOOM_IN_SCALE);
938     },  []() { FI_HILOGD("ZoomIn end"); });
939 
940     FI_HILOGD("leave");
941     return;
942 }
943 
SetMultiSelectedAnimationFlag(bool needMultiSelectedAnimation)944 void DragDrawing::SetMultiSelectedAnimationFlag(bool needMultiSelectedAnimation)
945 {
946     FI_HILOGI("needMultiSelectedAnimation:%{public}d", needMultiSelectedAnimation);
947     needMultiSelectedAnimation_ = needMultiSelectedAnimation;
948 }
949 
LongPressDragZoomOutAnimation()950 void DragDrawing::LongPressDragZoomOutAnimation()
951 {
952     FI_HILOGD("enter");
953     if (!CheckNodesValid()) {
954         FI_HILOGE("Check nodes valid failed");
955         return;
956     }
957     Rosen::RSAnimationTimingProtocol protocolZoomOut;
958     protocolZoomOut.SetDuration(ZOOM_OUT_DURATION);
959     Rosen::RSNode::Animate(protocolZoomOut, CURVE, [&]() {
960         CHKPV(g_drawingInfo.parentNode);
961         g_drawingInfo.parentNode->SetScale(ZOOM_OUT_SCALE);
962         if (!g_drawingInfo.multiSelectedNodes.empty()) {
963             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
964             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
965                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
966                 CHKPV(multiSelectedNode);
967                 multiSelectedNode->SetScale(ZOOM_OUT_SCALE);
968             }
969         }
970         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
971         CHKPV(dragStyleNode);
972         dragStyleNode->SetScale(ZOOM_OUT_SCALE);
973     },  []() { FI_HILOGD("ZoomOut end"); });
974 
975     g_drawingInfo.startNum = START_TIME;
976     g_drawingInfo.needDestroyDragWindow = false;
977     StartVsync();
978     FI_HILOGD("leave");
979     return;
980 }
981 
LongPressDragAnimation()982 void DragDrawing::LongPressDragAnimation()
983 {
984     FI_HILOGD("enter");
985     if (!CheckNodesValid()) {
986         FI_HILOGE("Check nodes valid failed");
987         return;
988     }
989     LongPressDragAlphaAnimation();
990     LongPressDragZoomInAnimation();
991     Rosen::RSAnimationTimingProtocol protocolZoomOut;
992     protocolZoomOut.SetDuration(ZOOM_DURATION);
993     Rosen::RSNode::Animate(protocolZoomOut, CURVE, [&]() {
994         ShadowInfo shadowInfo;
995         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
996         CHKPV(currentPixelMap);
997         float widthScale = CalculateWidthScale();
998         currentPixelMap->scale(widthScale, widthScale, Media::AntiAliasingOption::HIGH);
999         shadowInfo.pixelMap = currentPixelMap;
1000         shadowInfo.x = g_drawingInfo.pixelMapX * widthScale;
1001         shadowInfo.y = g_drawingInfo.pixelMapY * widthScale;
1002         UpdateShadowPic(shadowInfo);
1003     },  []() { FI_HILOGD("Scale zoom out end"); });
1004 
1005     g_drawingInfo.startNum = START_TIME;
1006     g_drawingInfo.needDestroyDragWindow = false;
1007     StartVsync();
1008     FI_HILOGD("leave");
1009     return;
1010 }
1011 
OnStartDrag(const DragAnimationData & dragAnimationData)1012 void DragDrawing::OnStartDrag(const DragAnimationData &dragAnimationData)
1013 {
1014     FI_HILOGI("enter");
1015     if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
1016         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1017         return;
1018     }
1019     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
1020     CHKPV(shadowNode);
1021     if (DrawShadow(shadowNode) != RET_OK) {
1022         FI_HILOGE("Draw shadow failed");
1023         return;
1024     }
1025     g_drawingInfo.isCurrentDefaultStyle = true;
1026     FI_HILOGI("leave");
1027 }
1028 
1029 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
OnStartDragExt()1030 void DragDrawing::OnStartDragExt()
1031 {
1032     if (dragExtHandler_ == nullptr) {
1033         FI_HILOGE("Fail to open drag drop extension library");
1034         return;
1035     }
1036     auto dragDropStartExtFunc = reinterpret_cast<DragStartExtFunc>(dlsym(dragExtHandler_, "OnStartDragExt"));
1037     if (dragDropStartExtFunc == nullptr) {
1038         FI_HILOGE("Fail to get drag drop extension function");
1039         CHKPV(dragExtHandler_);
1040         dlclose(dragExtHandler_);
1041         dragExtHandler_ = nullptr;
1042         return;
1043     }
1044 #ifdef OHOS_DRAG_ENABLE_ANIMATION
1045     if (!GetSuperHubHandler()->PostTask(
1046         [dragDropStartExtFunc] {
1047             return dragDropStartExtFunc(g_dragDataForSuperHub);
1048         })
1049     ) {
1050         FI_HILOGE("Start style animation failed");
1051     }
1052 #endif // OHOS_DRAG_ENABLE_ANIMATION
1053 }
1054 
NotifyDragInfo(const std::string & sourceName,const std::string & targetName)1055 void DragDrawing::NotifyDragInfo(const std::string &sourceName, const std::string &targetName)
1056 {
1057     FI_HILOGI("NotifyDragInfo");
1058     if (dragExtHandler_ == nullptr) {
1059         FI_HILOGE("Fail to open drag drop extension library");
1060         return;
1061     }
1062     auto dragDropExtFunc = reinterpret_cast<DragNotifyExtFunc>(dlsym(dragExtHandler_, "OnNotifyDragInfo"));
1063     if (dragDropExtFunc == nullptr) {
1064         FI_HILOGE("Fail to get drag drop extension function");
1065         CHKPV(dragExtHandler_);
1066         dlclose(dragExtHandler_);
1067         dragExtHandler_ = nullptr;
1068         return;
1069     }
1070     struct DragEventInfo dragEventInfo;
1071     dragEventInfo.sourcePkgName = sourceName;
1072     dragEventInfo.targetPkgName = targetName;
1073     if (!GetSuperHubHandler()->PostTask([dragDropExtFunc, dragEventInfo] ()
1074         mutable { return dragDropExtFunc(dragEventInfo); })) {
1075         FI_HILOGE("notify drag info failed");
1076     }
1077 }
1078 
GetSuperHubHandler()1079 std::shared_ptr<AppExecFwk::EventHandler> DragDrawing::GetSuperHubHandler()
1080 {
1081     if (superHubHandler_ == nullptr) {
1082         auto runner = AppExecFwk::EventRunner::Create(SUPER_HUB_THREAD_NAME);
1083         superHubHandler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1084     }
1085     return superHubHandler_;
1086 }
1087 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1088 
AdjustDoubleValue(double doubleValue)1089 float DragDrawing::AdjustDoubleValue(double doubleValue)
1090 {
1091     FI_HILOGI("doubleValue is %{public}f", doubleValue);
1092     float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
1093     if (dragOriginDpi > EPSILON) {
1094         float scalingValue = GetScaling() / dragOriginDpi;
1095         doubleValue = doubleValue * scalingValue;
1096         if (fabs(scalingValue - 1.0f) > EPSILON) {
1097             float widthScale = CalculateWidthScale();
1098             doubleValue = doubleValue * widthScale;
1099         }
1100     }
1101     float floatValue = static_cast<float>(doubleValue);
1102     FI_HILOGI("floatValue is %{public}f", floatValue);
1103     return floatValue;
1104 }
1105 
CheckStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)1106 void DragDrawing::CheckStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)
1107 {
1108     FI_HILOGD("enter");
1109     CHKPV(styleNode);
1110     if (drawStyleChangeModifier_ != nullptr) {
1111         styleNode->RemoveModifier(drawStyleChangeModifier_);
1112         drawStyleChangeModifier_ = nullptr;
1113     }
1114     if (drawStyleScaleModifier_ != nullptr && hasRunningScaleAnimation_) {
1115         needBreakStyleScaleAnimation_ = true;
1116     }
1117     styleNode->RemoveAllAnimations();
1118     FI_HILOGD("leave");
1119 }
1120 
RemoveStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)1121 void DragDrawing::RemoveStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)
1122 {
1123     FI_HILOGD("enter");
1124     CHKPV(styleNode);
1125     if (drawStyleChangeModifier_ != nullptr) {
1126         styleNode->RemoveModifier(drawStyleChangeModifier_);
1127         drawStyleChangeModifier_ = nullptr;
1128     }
1129     if (drawStyleScaleModifier_ != nullptr) {
1130         styleNode->RemoveModifier(drawStyleScaleModifier_);
1131         drawStyleScaleModifier_ = nullptr;
1132     }
1133     FI_HILOGD("leave");
1134 }
1135 
UpdateAnimationProtocol(Rosen::RSAnimationTimingProtocol protocol)1136 void DragDrawing::UpdateAnimationProtocol(Rosen::RSAnimationTimingProtocol protocol)
1137 {
1138     FI_HILOGD("enter");
1139     g_drawingInfo.startNum = START_TIME;
1140     interruptNum_ = START_TIME * INTERRUPT_SCALE;
1141     hasRunningAnimation_ = true;
1142     bool stopSignal = true;
1143     CHKPV(rsUiDirector_);
1144     while (hasRunningAnimation_) {
1145         hasRunningAnimation_ = rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
1146         rsUiDirector_->FlushModifier();
1147         rsUiDirector_->SendMessages();
1148         if ((g_drawingInfo.startNum >= interruptNum_) && stopSignal) {
1149             protocol.SetDuration(TIME_STOP);
1150             stopSignal = false;
1151         }
1152         g_drawingInfo.startNum += INTERVAL_TIME;
1153         usleep(TIME_SLEEP);
1154     }
1155     FI_HILOGD("leave");
1156 }
1157 
StartStyleAnimation(float startScale,float endScale,int32_t duration)1158 void DragDrawing::StartStyleAnimation(float startScale, float endScale, int32_t duration)
1159 {
1160     FI_HILOGI("StartStyleAnimation, startScale is %{public}lf", startScale);
1161     if (!CheckNodesValid() || needBreakStyleScaleAnimation_ || hasRunningStopAnimation_) {
1162         FI_HILOGE("needBreakStyleScaleAnimation_ or hasRunningStopAnimation_, return");
1163         return;
1164     }
1165     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1166         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1167         return;
1168     }
1169     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1170     CHKPV(dragStyleNode);
1171     RemoveStyleNodeModifier(dragStyleNode);
1172     drawStyleScaleModifier_ = std::make_shared<DrawStyleScaleModifier>();
1173     dragStyleNode->AddModifier(drawStyleScaleModifier_);
1174     CHKPV(drawStyleScaleModifier_);
1175     drawStyleScaleModifier_->SetScale(startScale);
1176     Rosen::RSAnimationTimingProtocol protocol;
1177     protocol.SetDuration(duration);
1178     auto springCurveStyle = endScale == STYLE_END_SCALE
1179         ? Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_030, BEZIER_000, BEZIER_040, BEZIER_100)
1180         : Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_020, BEZIER_000, BEZIER_060, BEZIER_100);
1181     Rosen::RSNode::Animate(protocol, springCurveStyle, [&]() {
1182         if (drawStyleScaleModifier_ != nullptr) {
1183             drawStyleScaleModifier_->SetScale(endScale);
1184         }
1185     }, []() { FI_HILOGD("StartStyleAnimation end"); });
1186     UpdateAnimationProtocol(protocol);
1187     if (endScale == STYLE_CHANGE_SCALE) {
1188         if (drawStyleChangeModifier_ != nullptr) {
1189             dragStyleNode->RemoveModifier(drawStyleChangeModifier_);
1190             drawStyleChangeModifier_ = nullptr;
1191         }
1192         if (drawStyleScaleModifier_ != nullptr) {
1193             dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1194             drawStyleScaleModifier_ = nullptr;
1195         }
1196         drawStyleChangeModifier_ = std::make_shared<DrawStyleChangeModifier>(g_drawingInfo.stylePixelMap);
1197         dragStyleNode->AddModifier(drawStyleChangeModifier_);
1198     }
1199     if (endScale == STYLE_END_SCALE && drawStyleScaleModifier_ != nullptr) {
1200         dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1201         drawStyleScaleModifier_ = nullptr;
1202     }
1203 }
1204 
ChangeStyleAnimation()1205 void DragDrawing::ChangeStyleAnimation()
1206 {
1207     FI_HILOGD("enter");
1208     hasRunningScaleAnimation_ = true;
1209     StartStyleAnimation(START_STYLE_SCALE, STYLE_CHANGE_SCALE, TIME_DRAG_CHANGE_STYLE);
1210     StartStyleAnimation(STYLE_CHANGE_SCALE, STYLE_MAX_SCALE, TIME_DRAG_CHANGE_STYLE);
1211     StartStyleAnimation(STYLE_MAX_SCALE, STYLE_END_SCALE, TIME_DRAG_STYLE);
1212     needBreakStyleScaleAnimation_ = false;
1213     hasRunningScaleAnimation_ = false;
1214     FI_HILOGD("leave");
1215 }
1216 
OnDragStyleAnimation()1217 void DragDrawing::OnDragStyleAnimation()
1218 {
1219     FI_HILOGD("enter");
1220     if (!CheckNodesValid()) {
1221         FI_HILOGE("Check nodes valid failed");
1222         return;
1223     }
1224     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1225         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1226         return;
1227     }
1228     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1229     CHKPV(dragStyleNode);
1230     needBreakStyleScaleAnimation_ = false;
1231     if (g_drawingInfo.isPreviousDefaultStyle == true || g_drawingInfo.isCurrentDefaultStyle == true) {
1232         FI_HILOGE("Has DefaultStyle, change style and return");
1233         CheckStyleNodeModifier(dragStyleNode);
1234         drawStyleChangeModifier_ = std::make_shared<DrawStyleChangeModifier>(g_drawingInfo.stylePixelMap);
1235         dragStyleNode->AddModifier(drawStyleChangeModifier_);
1236         return;
1237     }
1238 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1239     if (handler_ == nullptr) {
1240         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1241         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1242     }
1243 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1244     CheckStyleNodeModifier(dragStyleNode);
1245 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1246     CHKPV(handler_);
1247     handler_->PostTask(std::bind(&DragDrawing::ChangeStyleAnimation, this));
1248 #else
1249     ChangeStyleAnimation();
1250 #endif
1251     FI_HILOGD("leave");
1252 }
1253 
OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)1254 void DragDrawing::OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
1255     std::shared_ptr<Media::PixelMap> stylePixelMap)
1256 {
1257     FI_HILOGD("enter");
1258     CHKPV(dragStyleNode);
1259     CHKPV(stylePixelMap);
1260 #ifdef OHOS_DRAG_ENABLE_ANIMATION
1261     if (handler_ == nullptr) {
1262         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1263         CHKPV(runner);
1264         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1265     }
1266     if (drawSVGModifier_ != nullptr) {
1267         dragStyleNode->RemoveModifier(drawSVGModifier_);
1268         drawSVGModifier_ = nullptr;
1269     }
1270     CHKPV(handler_);
1271     if (!handler_->PostTask([this] { this->OnDragStyleAnimation(); })) {
1272         FI_HILOGE("Drag style animation failed");
1273         DrawStyle(dragStyleNode, stylePixelMap);
1274     }
1275 #else // OHOS_DRAG_ENABLE_ANIMATION
1276     DrawStyle(dragStyleNode, stylePixelMap);
1277 #endif // OHOS_DRAG_ENABLE_ANIMATION
1278     FI_HILOGD("leave");
1279 }
1280 
OnStopAnimationSuccess()1281 void DragDrawing::OnStopAnimationSuccess()
1282 {
1283     FI_HILOGI("enter");
1284     if (!CheckNodesValid()) {
1285         FI_HILOGE("Check nodes valid failed");
1286         return;
1287     }
1288     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1289         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1290         return;
1291     }
1292     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1293     if (dragStyleNode != nullptr && drawStyleScaleModifier_ != nullptr) {
1294         dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1295         dragStyleNode->RemoveAllAnimations();
1296         drawStyleScaleModifier_ = nullptr;
1297         needBreakStyleScaleAnimation_ = true;
1298     }
1299     CHKPV(g_drawingInfo.rootNode);
1300     hasRunningStopAnimation_ = true;
1301     if (drawDragStopModifier_ != nullptr) {
1302         g_drawingInfo.rootNode->RemoveModifier(drawDragStopModifier_);
1303         drawDragStopModifier_ = nullptr;
1304     }
1305     drawDragStopModifier_ = std::make_shared<DrawDragStopModifier>();
1306     g_drawingInfo.rootNode->AddModifier(drawDragStopModifier_);
1307     drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1308     drawDragStopModifier_->SetScale(BEGIN_SCALE);
1309     drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1310     drawDragStopModifier_->SetStyleAlpha(START_STYLE_ALPHA);
1311     Rosen::RSAnimationTimingProtocol windowProtocol;
1312     Rosen::RSAnimationTimingProtocol styleProtocol;
1313     windowProtocol.SetDuration(TIME_STOP_SUCCESS_WINDOW);
1314     styleProtocol.SetDuration(TIME_STOP_SUCCESS_STYLE);
1315     auto springCurveSuccessWindow = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_040, BEZIER_000,
1316         BEZIER_100, BEZIER_100);
1317     auto springCurveSuccessStyle = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_000, BEZIER_000,
1318         BEZIER_100, BEZIER_100);
1319     Rosen::RSNode::Animate(windowProtocol, springCurveSuccessWindow, [&]() {
1320         drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1321         drawDragStopModifier_->SetScale(END_SCALE_SUCCESS);
1322         Rosen::RSNode::Animate(styleProtocol, springCurveSuccessStyle, [&]() {
1323             drawDragStopModifier_->SetStyleAlpha(END_STYLE_ALPHA);
1324             drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1325         });
1326     },  []() { FI_HILOGD("OnStopAnimationSuccess end"); });
1327     DoEndAnimation();
1328     FI_HILOGI("leave");
1329 }
1330 
OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)1331 void DragDrawing::OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,
1332     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
1333 {
1334     FI_HILOGD("enter");
1335     auto animateCb = [this] { return this->InitVSync(END_ALPHA, END_SCALE_SUCCESS); };
1336 #ifdef OHOS_DRAG_ENABLE_ANIMATION
1337     ResetAnimationParameter();
1338     auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1339     CHKPV(runner);
1340     handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1341     CHKPV(handler_);
1342     if (!handler_->PostTask([this] { return this->OnStopAnimationSuccess(); })) {
1343         FI_HILOGE("Failed to stop style animation");
1344         RunAnimation(animateCb);
1345     }
1346 #else // OHOS_DRAG_ENABLE_ANIMATION
1347     RunAnimation(animateCb);
1348 #endif // OHOS_DRAG_ENABLE_ANIMATION
1349     FI_HILOGD("leave");
1350 }
1351 
OnStopAnimationFail()1352 void DragDrawing::OnStopAnimationFail()
1353 {
1354     FI_HILOGI("enter");
1355     if (!CheckNodesValid()) {
1356         FI_HILOGE("Check nodes valid failed");
1357         return;
1358     }
1359     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1360         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1361         return;
1362     }
1363     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1364     if (dragStyleNode != nullptr && drawStyleScaleModifier_ != nullptr) {
1365         dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1366         dragStyleNode->RemoveAllAnimations();
1367         drawStyleScaleModifier_ = nullptr;
1368         needBreakStyleScaleAnimation_ = true;
1369     }
1370     CHKPV(g_drawingInfo.rootNode);
1371     if (drawDragStopModifier_ != nullptr) {
1372         g_drawingInfo.rootNode->RemoveModifier(drawDragStopModifier_);
1373         drawDragStopModifier_ = nullptr;
1374     }
1375     drawDragStopModifier_ = std::make_shared<DrawDragStopModifier>();
1376     hasRunningStopAnimation_ = true;
1377     g_drawingInfo.rootNode->AddModifier(drawDragStopModifier_);
1378     drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1379     drawDragStopModifier_->SetScale(BEGIN_SCALE);
1380     drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1381     drawDragStopModifier_->SetStyleAlpha(START_STYLE_ALPHA);
1382     Rosen::RSAnimationTimingProtocol protocol;
1383     protocol.SetDuration(TIME_STOP_FAIL_WINDOW);
1384     auto springCurveFail = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_033, BEZIER_000,
1385         BEZIER_067, BEZIER_100);
1386     Rosen::RSNode::Animate(protocol, springCurveFail, [&]() {
1387         drawDragStopModifier_->SetAlpha(END_ALPHA);
1388         drawDragStopModifier_->SetScale(END_SCALE_FAIL);
1389         drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1390         drawDragStopModifier_->SetStyleAlpha(END_STYLE_ALPHA);
1391     }, []() { FI_HILOGD("OnStopAnimationFail end"); });
1392     DoEndAnimation();
1393     FI_HILOGI("leave");
1394 }
1395 
OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,std::shared_ptr<Rosen::RSNode> rootNode)1396 void DragDrawing::OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,
1397     std::shared_ptr<Rosen::RSNode> rootNode)
1398 {
1399     FI_HILOGD("enter");
1400     auto animateCb = [this] { return this->InitVSync(END_ALPHA, END_SCALE_FAIL); };
1401 #ifdef OHOS_DRAG_ENABLE_ANIMATION
1402     ResetAnimationParameter();
1403     auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1404     CHKPV(runner);
1405     handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1406     CHKPV(handler_);
1407     if (!handler_->PostTask([this] { this->OnStopAnimationFail(); })) {
1408         FI_HILOGE("Failed to stop style animation");
1409         RunAnimation(animateCb);
1410     }
1411 #else // OHOS_DRAG_ENABLE_ANIMATION
1412     RunAnimation(animateCb);
1413 #endif // OHOS_DRAG_ENABLE_ANIMATION
1414     FI_HILOGD("leave");
1415 }
1416 
OnStopAnimation()1417 void DragDrawing::OnStopAnimation()
1418 {
1419     FI_HILOGD("enter");
1420 }
1421 
RunAnimation(std::function<int32_t ()> cb)1422 int32_t DragDrawing::RunAnimation(std::function<int32_t()> cb)
1423 {
1424     FI_HILOGD("enter");
1425     ResetAnimationParameter();
1426 #ifndef IOS_PLATFORM
1427     auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1428 #else
1429     auto runner = AppExecFwk::EventRunner::Current(); // IOS animation can run main thread
1430 #endif // IOS_PLATFORM
1431     CHKPR(runner, RET_ERR);
1432     handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1433     if (!handler_->PostTask(cb)) {
1434         FI_HILOGE("Send vsync event failed");
1435         return RET_ERR;
1436     }
1437     FI_HILOGD("leave");
1438     return RET_OK;
1439 }
1440 
DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)1441 int32_t DragDrawing::DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)
1442 {
1443     FI_HILOGD("enter");
1444     CHKPR(shadowNode, RET_ERR);
1445     if (drawPixelMapModifier_ != nullptr) {
1446         shadowNode->RemoveModifier(drawPixelMapModifier_);
1447         drawPixelMapModifier_ = nullptr;
1448     }
1449     drawPixelMapModifier_ = std::make_shared<DrawPixelMapModifier>();
1450     shadowNode->AddModifier(drawPixelMapModifier_);
1451     FilterInfo filterInfo = g_drawingInfo.filterInfo;
1452     Rosen::Vector4f cornerRadiusVector = { filterInfo.cornerRadius1, filterInfo.cornerRadius2,
1453         filterInfo.cornerRadius3, filterInfo.cornerRadius4 };
1454     shadowNode->SetCornerRadius(cornerRadiusVector * filterInfo.dipScale * filterInfo.scale);
1455     shadowNode->SetAlpha(filterInfo.opacity);
1456     FI_HILOGD("leave");
1457     return RET_OK;
1458 }
1459 
DrawMouseIcon()1460 int32_t DragDrawing::DrawMouseIcon()
1461 {
1462     FI_HILOGD("enter");
1463     if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
1464         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
1465         return RET_ERR;
1466     }
1467     if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
1468         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1469         return RET_ERR;
1470     }
1471     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
1472     CHKPR(mouseIconNode, RET_ERR);
1473     if (drawMouseIconModifier_ != nullptr) {
1474         mouseIconNode->RemoveModifier(drawMouseIconModifier_);
1475         drawMouseIconModifier_ = nullptr;
1476     }
1477 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1478     int32_t ret = MMI::InputManager::GetInstance()->GetPointerStyle(GLOBAL_WINDOW_ID, pointerStyle_);
1479     if (ret != RET_OK) {
1480         FI_HILOGE("Get pointer style failed, ret:%{public}d", ret);
1481         return RET_ERR;
1482     }
1483     drawMouseIconModifier_ = std::make_shared<DrawMouseIconModifier>(pointerStyle_);
1484     mouseIconNode->AddModifier(drawMouseIconModifier_);
1485 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1486     FI_HILOGD("leave");
1487     return RET_OK;
1488 }
1489 
FlushDragPosition(uint64_t nanoTimestamp)1490 void DragDrawing::FlushDragPosition(uint64_t nanoTimestamp)
1491 {
1492 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1493     if (dragState_ == DragState::MOTION_DRAGGING) {
1494         FI_HILOGD("Current in MOTION_DRAGGING, skip");
1495         return;
1496     }
1497     if (rsUiDirector_ != nullptr) {
1498         rsUiDirector_->SetTimeStamp(nanoTimestamp, RENDER_THREAD_NAME);
1499     } else {
1500         FI_HILOGE("rsUiDirector_ is nullptr");
1501     }
1502     DragMoveEvent event = dragSmoothProcessor_.SmoothMoveEvent(nanoTimestamp,
1503         vSyncStation_.GetVSyncPeriod());
1504     FI_HILOGD("Move position x:%{private}f, y:%{private}f, timestamp:%{public}" PRId64
1505         "displayId:%{public}d", event.displayX, event.displayY, event.timestamp, event.displayId);
1506     StartTrace(HITRACE_TAG_MSDP,
1507         "OnDragMove,displayX:" + std::to_string(event.displayX) + ",displayY:" + std::to_string(event.displayY));
1508     UpdateDragPosition(event.displayId, event.displayX, event.displayY);
1509     FinishTrace(HITRACE_TAG_MSDP);
1510     vSyncStation_.RequestFrame(TYPE_FLUSH_DRAG_POSITION, frameCallback_);
1511 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1512 }
1513 
OnDragMove(int32_t displayId,int32_t displayX,int32_t displayY,int64_t actionTime)1514 void DragDrawing::OnDragMove(int32_t displayId, int32_t displayX, int32_t displayY, int64_t actionTime)
1515 {
1516     if (screenRotateState_) {
1517         screenRotateState_ = false;
1518     }
1519     if (isRunningRotateAnimation_) {
1520         FI_HILOGD("Doing rotate drag window animate, ignore draw drag window");
1521         return;
1522     }
1523 #ifdef IOS_PLATFORM
1524     actionTime_ = actionTime;
1525 #endif // IOS_PLATFORM
1526 
1527 #ifdef OHOS_BUILD_PC_PRODUCT
1528     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
1529         UpdateDragPosition(displayId, displayX, displayY);
1530         return;
1531     }
1532 #endif // OHOS_BUILD_PC_PRODUCT
1533 
1534 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1535     std::chrono::microseconds microseconds(actionTime);
1536     TimeStamp time(microseconds);
1537     uint64_t actionTimeCount = static_cast<uint64_t>(time.time_since_epoch().count());
1538     DragMoveEvent event = {
1539         .displayX = displayX,
1540         .displayY = displayY,
1541         .displayId = displayId,
1542         .timestamp = actionTimeCount,
1543     };
1544     dragSmoothProcessor_.InsertEvent(event);
1545     if (frameCallback_ == nullptr) {
1546         frameCallback_ = std::make_shared<DragFrameCallback>([this](uint64_t nanoTimestamp) {
1547             this->FlushDragPosition(nanoTimestamp);
1548         });
1549     }
1550     vSyncStation_.RequestFrame(TYPE_FLUSH_DRAG_POSITION, frameCallback_);
1551 #else
1552     UpdateDragPosition(displayId, displayX, displayY);
1553 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1554 }
1555 
DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)1556 int32_t DragDrawing::DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
1557     std::shared_ptr<Media::PixelMap> stylePixelMap)
1558 {
1559     FI_HILOGD("enter");
1560     CHKPR(dragStyleNode, RET_ERR);
1561     CHKPR(stylePixelMap, RET_ERR);
1562     if (drawSVGModifier_ != nullptr) {
1563         dragStyleNode->RemoveModifier(drawSVGModifier_);
1564         drawSVGModifier_ = nullptr;
1565     }
1566     drawSVGModifier_ = std::make_shared<DrawSVGModifier>(stylePixelMap);
1567     dragStyleNode->AddModifier(drawSVGModifier_);
1568     FI_HILOGD("leave");
1569     return RET_OK;
1570 }
1571 
InitVSync(float endAlpha,float endScale)1572 int32_t DragDrawing::InitVSync(float endAlpha, float endScale)
1573 {
1574     FI_HILOGD("enter");
1575     CHKPR(g_drawingInfo.rootNode, RET_ERR);
1576     if (drawDynamicEffectModifier_ != nullptr) {
1577         g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
1578         drawDynamicEffectModifier_ = nullptr;
1579     }
1580     drawDynamicEffectModifier_ = std::make_shared<DrawDynamicEffectModifier>();
1581     g_drawingInfo.rootNode->AddModifier(drawDynamicEffectModifier_);
1582     drawDynamicEffectModifier_->SetAlpha(BEGIN_ALPHA);
1583     drawDynamicEffectModifier_->SetScale(BEGIN_SCALE);
1584 
1585     Rosen::RSAnimationTimingProtocol protocol;
1586     protocol.SetDuration(SUCCESS_ANIMATION_DURATION);
1587     Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
1588         drawDynamicEffectModifier_->SetAlpha(endAlpha);
1589         drawDynamicEffectModifier_->SetScale(endScale);
1590     },  []() { FI_HILOGD("InitVSync end"); });
1591     Rosen::RSTransaction::FlushImplicitTransaction();
1592     DoEndAnimation();
1593     FI_HILOGD("leave");
1594     return RET_OK;
1595 }
1596 
StartVsync()1597 int32_t DragDrawing::StartVsync()
1598 {
1599     FI_HILOGI("enter");
1600     auto currentReceiver = AccessReceiverLocked();
1601     if (currentReceiver == nullptr) {
1602         CHKPR(handler_, RET_ERR);
1603         currentReceiver = Rosen::RSInterfaces::GetInstance().CreateVSyncReceiver("DragDrawing", handler_);
1604         CHKPR(currentReceiver, RET_ERR);
1605         UpdateReceiverLocked(currentReceiver);
1606     }
1607 #ifdef IOS_PLATFORM
1608     rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
1609 #endif // IOS_PLATFORM
1610     int32_t ret = currentReceiver->Init();
1611     if (ret != RET_OK) {
1612         FI_HILOGE("Receiver init failed");
1613         return RET_ERR;
1614     }
1615     Rosen::VSyncReceiver::FrameCallback fcb = {
1616         .userData_ = this,
1617         .callback_ = [this](int64_t parm1, void *parm2) { this->OnVsync(); }
1618     };
1619     ret = currentReceiver->RequestNextVSync(fcb);
1620     if (ret != RET_OK) {
1621         FI_HILOGE("Request next vsync failed");
1622     }
1623     FI_HILOGI("leave");
1624     return ret;
1625 }
1626 
OnVsync()1627 void DragDrawing::OnVsync()
1628 {
1629     FI_HILOGD("enter");
1630     CHKPV(rsUiDirector_);
1631     bool hasRunningAnimation = rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
1632     rsUiDirector_->FlushModifier();
1633     rsUiDirector_->SendMessages();
1634     if (!hasRunningAnimation) {
1635         FI_HILOGI("Stop runner, hasRunningAnimation:%{public}d, needDestroyDragWindow:%{public}d",
1636             hasRunningAnimation, g_drawingInfo.needDestroyDragWindow.load());
1637         if (g_drawingInfo.needDestroyDragWindow) {
1638             ResetAnimationFlag();
1639         }
1640         return;
1641     }
1642     Rosen::VSyncReceiver::FrameCallback fcb = {
1643         .userData_ = this,
1644         .callback_ = [this](int64_t parm1, void *parm2) { this->OnVsync(); }
1645     };
1646     auto currentReceiver = AccessReceiverLocked();
1647     CHKPV(currentReceiver);
1648     int32_t ret = currentReceiver->RequestNextVSync(fcb);
1649     if (ret != RET_OK) {
1650         FI_HILOGE("Request next vsync failed");
1651     }
1652     rsUiDirector_->SendMessages();
1653     g_drawingInfo.startNum += INTERVAL_TIME;
1654     FI_HILOGD("leave");
1655 }
1656 
InitDrawingInfo(const DragData & dragData,bool isLongPressDrag)1657 void DragDrawing::InitDrawingInfo(const DragData &dragData, bool isLongPressDrag)
1658 {
1659     g_drawingInfo.isRunning = true;
1660     if (dragData.shadowInfos.empty()) {
1661         FI_HILOGE("ShadowInfos is empty");
1662         return;
1663     }
1664     DragDrawing::UpdataGlobalPixelMapLocked(dragData.shadowInfos.front().pixelMap);
1665     g_drawingInfo.pixelMapX = dragData.shadowInfos.front().x;
1666     g_drawingInfo.pixelMapY = dragData.shadowInfos.front().y;
1667     float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
1668     if (dragOriginDpi > EPSILON) {
1669         float scalingValue = GetScaling() / dragOriginDpi;
1670         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
1671         CHKPV(currentPixelMap);
1672         currentPixelMap->scale(scalingValue, scalingValue, Media::AntiAliasingOption::HIGH);
1673         g_drawingInfo.pixelMapX = g_drawingInfo.pixelMapX * scalingValue;
1674         g_drawingInfo.pixelMapY = g_drawingInfo.pixelMapY * scalingValue;
1675         if (fabs(scalingValue - 1.0f) > EPSILON) {
1676             float widthScale = CalculateWidthScale();
1677             CHKPV(currentPixelMap);
1678             currentPixelMap->scale(widthScale, widthScale, Media::AntiAliasingOption::HIGH);
1679             g_drawingInfo.pixelMapX = g_drawingInfo.pixelMapX * widthScale;
1680             g_drawingInfo.pixelMapY = g_drawingInfo.pixelMapY * widthScale;
1681         }
1682     }
1683     g_drawingInfo.currentDragNum = dragData.dragNum;
1684     g_drawingInfo.sourceType = dragData.sourceType;
1685     g_drawingInfo.displayId = dragData.displayId;
1686     g_drawingInfo.displayX = dragData.displayX;
1687     g_drawingInfo.displayY = dragData.displayY;
1688     RotateDisplayXY(g_drawingInfo.displayX, g_drawingInfo.displayY);
1689     if (!ParserExtraInfo(dragData.extraInfo, g_drawingInfo.extraInfo)) {
1690         FI_HILOGI("No parser valid extraInfo data");
1691     }
1692     if (!ParserFilterInfo(dragData.filterInfo, g_drawingInfo.filterInfo)) {
1693         FI_HILOGI("No parser valid filterInfo data");
1694     }
1695     size_t shadowInfosSize = dragData.shadowInfos.size();
1696     for (size_t i = 1; i < shadowInfosSize; ++i) {
1697         std::shared_ptr<Media::PixelMap> pixelMap = dragData.shadowInfos[i].pixelMap;
1698         if (dragOriginDpi > EPSILON) {
1699             float scalingValue = GetScaling() / dragOriginDpi;
1700             CHKPV(pixelMap);
1701             pixelMap->scale(scalingValue, scalingValue, Media::AntiAliasingOption::HIGH);
1702         }
1703         g_drawingInfo.multiSelectedPixelMaps.emplace_back(pixelMap);
1704     }
1705 }
1706 
InitDragAnimationData(DragAnimationData & dragAnimationData)1707 int32_t DragDrawing::InitDragAnimationData(DragAnimationData &dragAnimationData)
1708 {
1709     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
1710     CHKPR(currentPixelMap, RET_ERR);
1711     dragAnimationData.pixelMap = currentPixelMap;
1712     dragAnimationData.displayX = g_drawingInfo.displayX;
1713     dragAnimationData.displayY = g_drawingInfo.displayY;
1714     dragAnimationData.offsetX = g_drawingInfo.pixelMapX;
1715     dragAnimationData.offsetY = g_drawingInfo.pixelMapY;
1716     return RET_OK;
1717 }
1718 
InitLayer()1719 int32_t DragDrawing::InitLayer()
1720 {
1721     FI_HILOGI("enter");
1722     if (g_drawingInfo.surfaceNode == nullptr) {
1723         FI_HILOGE("Init layer failed, surfaceNode is nullptr");
1724         return RET_ERR;
1725     }
1726 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1727     auto surface = g_drawingInfo.surfaceNode->GetSurface();
1728     if (surface == nullptr) {
1729         g_drawingInfo.surfaceNode->DetachFromWindowContainer(g_drawingInfo.displayId);
1730         g_drawingInfo.surfaceNode = nullptr;
1731         FI_HILOGE("Init layer failed, surface is nullptr");
1732         Rosen::RSTransaction::FlushImplicitTransaction();
1733         return RET_ERR;
1734     }
1735 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1736     if (g_drawingInfo.isInitUiDirector) {
1737         g_drawingInfo.isInitUiDirector = false;
1738         rsUiDirector_ = Rosen::RSUIDirector::Create();
1739         CHKPR(rsUiDirector_, RET_ERR);
1740         rsUiDirector_->Init();
1741         rsUiDirector_->SetUITaskRunner([this](const std::function<void()>& task, uint32_t delay = 0) {
1742             CHKPV(this->handler_);
1743             this->handler_->PostTask(task, delay);
1744         });
1745     }
1746     rsUiDirector_->SetRSSurfaceNode(g_drawingInfo.surfaceNode);
1747 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1748 #ifndef OHOS_BUILD_PC_PRODUCT
1749     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
1750 #else
1751     sptr<Rosen::DisplayInfo> display =
1752         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
1753         FI_HILOGI("Get visible area display info by id, displayid:%{public}d", g_drawingInfo.displayId);
1754 #endif // OHOS_BUILD_PC_PRODUCT
1755     if (display == nullptr) {
1756         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
1757 #ifndef OHOS_BUILD_PC_PRODUCT
1758         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
1759 #else
1760         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
1761 #endif // OHOS_BUILD_PC_PRODUCT
1762         if (display == nullptr) {
1763             FI_HILOGE("Get display info failed, display is nullptr");
1764             return RET_ERR;
1765         }
1766     }
1767     int32_t rootNodeSize = std::max(display->GetWidth(), display->GetHeight());
1768     InitCanvas(rootNodeSize, rootNodeSize);
1769     FI_HILOGI("Root node size:%{public}d, display Width:%{public}d, display height:%{public}d",
1770         rootNodeSize, display->GetWidth(), display->GetHeight());
1771 #else
1772     CHKPR(window_, RET_ERR);
1773     InitCanvas(window_->GetRect().width_, window_->GetRect().height_);
1774 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1775     if (rotation_ != Rosen::Rotation::ROTATION_0) {
1776         RotateDragWindow(rotation_);
1777     } else {
1778         DragWindowRotateInfo_.rotation = ROTATION_0;
1779     }
1780     Rosen::RSTransaction::FlushImplicitTransaction();
1781     FI_HILOGI("leave");
1782     return RET_OK;
1783 }
1784 
InitCanvas(int32_t width,int32_t height)1785 void DragDrawing::InitCanvas(int32_t width, int32_t height)
1786 {
1787     FI_HILOGI("enter");
1788     if (g_drawingInfo.rootNode == nullptr) {
1789         g_drawingInfo.rootNode = Rosen::RSRootNode::Create();
1790         CHKPV(g_drawingInfo.rootNode);
1791     }
1792     g_drawingInfo.rootNode->SetBounds(0, 0, width, height);
1793     g_drawingInfo.rootNode->SetFrame(0, 0, width, height);
1794     g_drawingInfo.rootNode->SetBackgroundColor(SK_ColorTRANSPARENT);
1795     std::shared_ptr<Rosen::RSCanvasNode> filterNode = Rosen::RSCanvasNode::Create();
1796     CHKPV(filterNode);
1797     g_drawingInfo.nodes.emplace_back(filterNode);
1798     ProcessFilter();
1799     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = Rosen::RSCanvasNode::Create();
1800     CHKPV(pixelMapNode);
1801     pixelMapNode->SetForegroundColor(TRANSPARENT_COLOR_ARGB);
1802     pixelMapNode->SetGrayScale(g_drawingInfo.filterInfo.dragNodeGrayscale);
1803     g_drawingInfo.nodes.emplace_back(pixelMapNode);
1804     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = Rosen::RSCanvasNode::Create();
1805     CHKPV(dragStyleNode);
1806     g_drawingInfo.nodes.emplace_back(dragStyleNode);
1807     if (g_drawingInfo.parentNode == nullptr) {
1808         g_drawingInfo.parentNode = Rosen::RSCanvasNode::Create();
1809         CHKPV(g_drawingInfo.parentNode);
1810     }
1811     g_drawingInfo.parentNode->AddChild(filterNode);
1812     g_drawingInfo.parentNode->AddChild(pixelMapNode);
1813     if (!g_drawingInfo.multiSelectedPixelMaps.empty()) {
1814         InitMultiSelectedNodes();
1815         if (!g_drawingInfo.multiSelectedNodes.empty()) {
1816             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
1817             for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
1818                 g_drawingInfo.rootNode->AddChild(g_drawingInfo.multiSelectedNodes[i]);
1819             }
1820         }
1821     }
1822     g_drawingInfo.rootNode->AddChild(g_drawingInfo.parentNode);
1823     CHKPV(rsUiDirector_);
1824 #ifndef OHOS_BUILD_PC_PRODUCT
1825     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
1826         std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = Rosen::RSCanvasNode::Create();
1827         CHKPV(mouseIconNode);
1828         g_drawingInfo.nodes.emplace_back(mouseIconNode);
1829         g_drawingInfo.rootNode->AddChild(mouseIconNode);
1830         rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
1831         return;
1832     }
1833 #endif // OHOS_BUILD_PC_PRODUCT
1834     rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
1835     FI_HILOGI("leave");
1836 }
1837 
CreateWindow()1838 void DragDrawing::CreateWindow()
1839 {
1840 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1841     FI_HILOGD("Parameter screen number:%{public}llu", static_cast<unsigned long long>(screenId_));
1842     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
1843     surfaceNodeConfig.SurfaceNodeName = "drag window";
1844     surfaceNodeConfig.surfaceWindowType = Rosen::SurfaceWindowType::SYSTEM_SCB_WINDOW;
1845     Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
1846     g_drawingInfo.surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
1847     CHKPV(g_drawingInfo.surfaceNode);
1848 #ifndef OHOS_BUILD_PC_PRODUCT
1849     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
1850 #else
1851     sptr<Rosen::DisplayInfo> display =
1852         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
1853 #endif // OHOS_BUILD_PC_PRODUCT
1854     if (display == nullptr) {
1855         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
1856 #ifndef OHOS_BUILD_PC_PRODUCT
1857         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
1858 #else
1859         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
1860 #endif // OHOS_BUILD_PC_PRODUCT
1861         if (display == nullptr) {
1862             FI_HILOGE("Get display info failed, display is nullptr");
1863             return;
1864         }
1865     }
1866     uint64_t rsScreenId = screenId_;
1867     sptr<Rosen::Screen> screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId_);
1868     if ((screen != nullptr) && (!screen->IsReal())) {
1869         if (!Rosen::DisplayManager::GetInstance().ConvertScreenIdToRsScreenId(screenId_, rsScreenId)) {
1870             FI_HILOGE("ConvertScreenIdToRsScreenId failed");
1871             return;
1872         }
1873     }
1874     screenId_ = rsScreenId;
1875     int32_t surfaceNodeSize = std::max(display->GetWidth(), display->GetHeight());
1876     g_drawingInfo.surfaceNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
1877 #else
1878     CHKPV(window_);
1879     g_drawingInfo.surfaceNode = window_->GetSurfaceNode();
1880     CHKPV(g_drawingInfo.surfaceNode);
1881     g_drawingInfo.surfaceNode->SetBounds(0, 0, window_->GetRect().width_, window_->GetRect().height_);
1882 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1883     g_drawingInfo.surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
1884     g_drawingInfo.surfaceNode->SetPositionZ(DRAG_WINDOW_POSITION_Z);
1885     g_drawingInfo.surfaceNode->SetBackgroundColor(SK_ColorTRANSPARENT);
1886 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
1887     g_drawingInfo.surfaceNode->AttachToWindowContainer(rsScreenId);
1888 #endif // OHOS_BUILD_ENABLE_ARKUI_X
1889     g_drawingInfo.surfaceNode->SetVisible(false);
1890     Rosen::RSTransaction::FlushImplicitTransaction();
1891 }
1892 
RemoveModifier()1893 void DragDrawing::RemoveModifier()
1894 {
1895     FI_HILOGD("enter");
1896     if ((g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
1897         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
1898         return;
1899     }
1900 
1901     if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX || g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1902         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1903         return;
1904     }
1905     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
1906     CHKPV(pixelMapNode);
1907     if (drawPixelMapModifier_ != nullptr) {
1908         pixelMapNode->RemoveModifier(drawPixelMapModifier_);
1909         drawPixelMapModifier_ = nullptr;
1910     }
1911     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1912     CHKPV(dragStyleNode);
1913     if (drawSVGModifier_ != nullptr) {
1914         dragStyleNode->RemoveModifier(drawSVGModifier_);
1915         drawSVGModifier_ = nullptr;
1916     }
1917     FI_HILOGD("leave");
1918 }
1919 
UpdateSvgNodeInfo(xmlNodePtr curNode,int32_t extendSvgWidth)1920 int32_t DragDrawing::UpdateSvgNodeInfo(xmlNodePtr curNode, int32_t extendSvgWidth)
1921 {
1922     FI_HILOGD("enter");
1923     if (xmlStrcmp(curNode->name, BAD_CAST "svg")) {
1924         FI_HILOGE("Svg format invalid");
1925         return RET_ERR;
1926     }
1927     std::ostringstream oStrStream;
1928     oStrStream << xmlGetProp(curNode, BAD_CAST "width");
1929     std::string srcSvgWidth = oStrStream.str();
1930     if (srcSvgWidth.length() < STRING_PX_LENGTH) {
1931         FI_HILOGE("Svg width invalid, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
1932         return RET_ERR;
1933     }
1934     srcSvgWidth = srcSvgWidth.substr(0, srcSvgWidth.length() - STRING_PX_LENGTH);
1935     if (!IsNum(srcSvgWidth)) {
1936         FI_HILOGE("srcSvgWidth is not digital, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
1937         return RET_ERR;
1938     }
1939     int32_t number = std::stoi(srcSvgWidth) + extendSvgWidth;
1940     std::string tgtSvgWidth = std::to_string(number);
1941     tgtSvgWidth.append("px");
1942     xmlSetProp(curNode, BAD_CAST "width", BAD_CAST tgtSvgWidth.c_str());
1943     oStrStream.str("");
1944     oStrStream << xmlGetProp(curNode, BAD_CAST "viewBox");
1945     std::string srcViewBox = oStrStream.str();
1946     std::istringstream iStrStream(srcViewBox);
1947     std::string tmpString;
1948     std::string tgtViewBox;
1949     int32_t i = 0;
1950     while (iStrStream >> tmpString) {
1951         if (i == VIEW_BOX_POS) {
1952             if (!IsNum(tmpString)) {
1953                 FI_HILOGE("tmpString is not digital, tmpString:%{public}s", tmpString.c_str());
1954                 return RET_ERR;
1955             }
1956             number = std::stoi(tmpString) + extendSvgWidth;
1957             tmpString = std::to_string(number);
1958         }
1959         tgtViewBox.append(tmpString);
1960         tgtViewBox += " ";
1961         ++i;
1962     }
1963 
1964     xmlSetProp(curNode, BAD_CAST "viewBox", BAD_CAST tgtViewBox.c_str());
1965     FI_HILOGD("leave");
1966     return RET_OK;
1967 }
1968 
GetRectNode(xmlNodePtr curNode)1969 xmlNodePtr DragDrawing::GetRectNode(xmlNodePtr curNode)
1970 {
1971     FI_HILOGD("enter");
1972     curNode = curNode->xmlChildrenNode;
1973     while (curNode != nullptr) {
1974         if (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
1975             while (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
1976                 curNode = curNode->xmlChildrenNode;
1977             }
1978             break;
1979         }
1980         curNode = curNode->next;
1981     }
1982     FI_HILOGD("leave");
1983     return curNode;
1984 }
1985 
UpdateRectNode(int32_t extendSvgWidth,xmlNodePtr curNode)1986 xmlNodePtr DragDrawing::UpdateRectNode(int32_t extendSvgWidth, xmlNodePtr curNode)
1987 {
1988     FI_HILOGD("enter");
1989     while (curNode != nullptr) {
1990         if (!xmlStrcmp(curNode->name, BAD_CAST "rect")) {
1991             std::ostringstream oStrStream;
1992             oStrStream << xmlGetProp(curNode, BAD_CAST "width");
1993             std::string srcRectWidth = oStrStream.str();
1994             if (!IsNum(srcRectWidth)) {
1995                 FI_HILOGE("srcRectWidth is not digital, srcRectWidth:%{public}s", srcRectWidth.c_str());
1996                 return nullptr;
1997             }
1998             int32_t number = std::stoi(srcRectWidth) + extendSvgWidth;
1999             xmlSetProp(curNode, BAD_CAST "width", BAD_CAST std::to_string(number).c_str());
2000         }
2001         if (!xmlStrcmp(curNode->name, BAD_CAST "text")) {
2002             return curNode->xmlChildrenNode;
2003         }
2004         curNode = curNode->next;
2005     }
2006     FI_HILOGE("Empty node of XML");
2007     return nullptr;
2008 }
2009 
UpdateTspanNode(xmlNodePtr curNode)2010 void DragDrawing::UpdateTspanNode(xmlNodePtr curNode)
2011 {
2012     FI_HILOGD("enter");
2013     while (curNode != nullptr) {
2014         if (!xmlStrcmp(curNode->name, BAD_CAST "tspan")) {
2015             xmlNodeSetContent(curNode, BAD_CAST std::to_string(g_drawingInfo.currentDragNum).c_str());
2016         }
2017         curNode = curNode->next;
2018     }
2019     FI_HILOGD("leave");
2020 }
2021 
ParseAndAdjustSvgInfo(xmlNodePtr curNode)2022 int32_t DragDrawing::ParseAndAdjustSvgInfo(xmlNodePtr curNode)
2023 {
2024     FI_HILOGD("enter");
2025     CHKPR(curNode, RET_ERR);
2026     std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
2027     if (strStyle.empty()) {
2028         FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
2029         return RET_ERR;
2030     }
2031     int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
2032     xmlKeepBlanksDefault(0);
2033     int32_t ret = UpdateSvgNodeInfo(curNode, extendSvgWidth);
2034     if (ret != RET_OK) {
2035         FI_HILOGE("Update svg node info failed, ret:%{public}d", ret);
2036         return RET_ERR;
2037     }
2038     curNode = GetRectNode(curNode);
2039     CHKPR(curNode, RET_ERR);
2040     curNode = UpdateRectNode(extendSvgWidth, curNode);
2041     CHKPR(curNode, RET_ERR);
2042     UpdateTspanNode(curNode);
2043     FI_HILOGD("leave");
2044     return RET_OK;
2045 }
2046 
DecodeSvgToPixelMap(const std::string & filePath)2047 std::shared_ptr<Media::PixelMap> DragDrawing::DecodeSvgToPixelMap(
2048     const std::string &filePath)
2049 {
2050     FI_HILOGD("enter");
2051     xmlDocPtr xmlDoc = xmlReadFile(filePath.c_str(), 0, XML_PARSE_NOBLANKS);
2052     if (NeedAdjustSvgInfo()) {
2053         xmlNodePtr node = xmlDocGetRootElement(xmlDoc);
2054         CHKPP(node);
2055         int32_t ret = ParseAndAdjustSvgInfo(node);
2056         if (ret != RET_OK) {
2057             FI_HILOGE("Parse and adjust svg info failed, ret:%{public}d", ret);
2058             return nullptr;
2059         }
2060     }
2061     xmlChar *xmlbuff = nullptr;
2062     int32_t buffersize = 0;
2063     xmlDocDumpFormatMemory(xmlDoc, &xmlbuff, &buffersize, 1);
2064     std::ostringstream oStrStream;
2065     oStrStream << xmlbuff;
2066     std::string content = oStrStream.str();
2067     xmlFree(xmlbuff);
2068     xmlFreeDoc(xmlDoc);
2069     Media::SourceOptions opts;
2070     opts.formatHint = "image/svg+xml";
2071     uint32_t errCode = 0;
2072     auto imageSource = Media::ImageSource::CreateImageSource(reinterpret_cast<const uint8_t*>(content.c_str()),
2073         content.size(), opts, errCode);
2074     CHKPP(imageSource);
2075     Media::DecodeOptions decodeOpts;
2076     SetDecodeOptions(decodeOpts);
2077     std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
2078     FI_HILOGD("leave");
2079     return pixelMap;
2080 }
2081 
NeedAdjustSvgInfo()2082 bool DragDrawing::NeedAdjustSvgInfo()
2083 {
2084     FI_HILOGD("enter");
2085     if (g_drawingInfo.currentStyle == DragCursorStyle::DEFAULT) {
2086         return false;
2087     }
2088     if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) &&
2089         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
2090         return false;
2091     }
2092     if ((g_drawingInfo.currentStyle == DragCursorStyle::MOVE) &&
2093         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
2094         return false;
2095     }
2096     if ((g_drawingInfo.currentStyle == DragCursorStyle::FORBIDDEN) &&
2097         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
2098         return false;
2099     }
2100     FI_HILOGD("leave");
2101     return true;
2102 }
2103 
2104 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
GetFilePath(std::string & filePath)2105 int32_t DragDrawing::GetFilePath(std::string &filePath)
2106 {
2107     FI_HILOGD("enter");
2108     switch (g_drawingInfo.currentStyle) {
2109         case DragCursorStyle::COPY: {
2110             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
2111                 filePath = COPY_ONE_DRAG_PATH;
2112             } else {
2113                 filePath = COPY_DRAG_PATH;
2114             }
2115             break;
2116         }
2117         case DragCursorStyle::MOVE: {
2118             filePath = MOVE_DRAG_PATH;
2119             break;
2120         }
2121         case DragCursorStyle::FORBIDDEN: {
2122             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
2123                 filePath = FORBID_ONE_DRAG_PATH;
2124             } else {
2125                 filePath = FORBID_DRAG_PATH;
2126             }
2127             break;
2128         }
2129         case DragCursorStyle::DEFAULT:
2130         default: {
2131             FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
2132             break;
2133         }
2134     }
2135     FI_HILOGD("leave");
2136     return RET_OK;
2137 }
2138 #else
GetFilePath(std::string & filePath)2139 int32_t DragDrawing::GetFilePath(std::string &filePath)
2140 {
2141     FI_HILOGD("enter");
2142     switch (g_drawingInfo.currentStyle) {
2143         case DragCursorStyle::COPY: {
2144             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
2145                 filePath = svgFilePath_ + COPY_ONE_DRAG_NAME;
2146             } else {
2147                 filePath = svgFilePath_ + COPY_DRAG_NAME;
2148             }
2149             break;
2150         }
2151         case DragCursorStyle::MOVE: {
2152             filePath = svgFilePath_ + MOVE_DRAG_NAME;
2153             break;
2154         }
2155         case DragCursorStyle::FORBIDDEN: {
2156             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
2157                 filePath = svgFilePath_ + FORBID_ONE_DRAG_NAME;
2158             } else {
2159                 filePath = svgFilePath_ + FORBID_DRAG_NAME;
2160             }
2161             break;
2162         }
2163         case DragCursorStyle::DEFAULT:
2164         default: {
2165             FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
2166             break;
2167         }
2168     }
2169     FI_HILOGD("leave");
2170     return RET_OK;
2171 }
2172 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2173 
SetDecodeOptions(Media::DecodeOptions & decodeOpts)2174 void DragDrawing::SetDecodeOptions(Media::DecodeOptions &decodeOpts)
2175 {
2176     FI_HILOGD("enter");
2177     std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
2178     if (strStyle.empty()) {
2179         FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
2180         return;
2181     }
2182     int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
2183     if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
2184         decodeOpts.desiredSize = {
2185             .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
2186             .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
2187         };
2188     } else {
2189         decodeOpts.desiredSize = {
2190             .width = (DEVICE_INDEPENDENT_PIXEL + extendSvgWidth) * GetScaling(),
2191             .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
2192         };
2193     }
2194     FI_HILOGD("leave");
2195 }
2196 
ParserDragShadowInfo(cJSON * filterInfoParser,FilterInfo & filterInfo)2197 void DragDrawing::ParserDragShadowInfo(cJSON* filterInfoParser, FilterInfo &filterInfo)
2198 {
2199     CHKPV(filterInfoParser);
2200     cJSON *offsetX = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_offsetX");
2201     if (cJSON_IsNumber(offsetX)) {
2202         filterInfo.offsetX = static_cast<float>(offsetX->valuedouble);
2203     }
2204     cJSON *offsetY = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_offsetY");
2205     if (cJSON_IsNumber(offsetY)) {
2206         filterInfo.offsetY = static_cast<float>(offsetY->valuedouble);
2207     }
2208     cJSON *argb = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_argb");
2209     if (cJSON_IsNumber(argb)) {
2210         filterInfo.argb = static_cast<uint32_t>(argb->valueint);
2211     }
2212     cJSON *shadowIsFilled   = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_is_filled");
2213     if (cJSON_IsBool(shadowIsFilled)) {
2214         filterInfo.shadowIsFilled = cJSON_IsTrue(shadowIsFilled);
2215     }
2216     cJSON *shadowMask   = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_mask");
2217     if (cJSON_IsBool(shadowMask)) {
2218         filterInfo.shadowMask = cJSON_IsTrue(shadowMask);
2219     }
2220     cJSON *shadowColorStrategy  = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_color_strategy");
2221     if (cJSON_IsNumber(shadowColorStrategy)) {
2222         filterInfo.shadowColorStrategy = shadowColorStrategy->valueint;
2223     }
2224     cJSON *isHardwareAcceleration  = cJSON_GetObjectItemCaseSensitive(
2225         filterInfoParser, "shadow_is_hardwareacceleration");
2226     if (cJSON_IsBool(isHardwareAcceleration)) {
2227         filterInfo.isHardwareAcceleration = cJSON_IsTrue(isHardwareAcceleration);
2228     }
2229     if (filterInfo.isHardwareAcceleration) {
2230         cJSON *elevation  = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_elevation");
2231         if (cJSON_IsNumber(elevation)) {
2232             filterInfo.elevation = static_cast<float>(elevation->valuedouble);
2233         }
2234     } else {
2235         cJSON *shadowCorner = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_corner");
2236         if (cJSON_IsNumber(shadowCorner)) {
2237             filterInfo.shadowCorner = static_cast<float>(shadowCorner->valuedouble);
2238         }
2239     }
2240 }
2241 
ParserTextDragShadowInfo(cJSON * filterInfoParser,FilterInfo & filterInfo)2242 void DragDrawing::ParserTextDragShadowInfo(cJSON* filterInfoParser, FilterInfo &filterInfo)
2243 {
2244     CHKPV(filterInfoParser);
2245     cJSON *path = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_path");
2246     if (cJSON_IsString(path)) {
2247         float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
2248         if (dragOriginDpi > EPSILON) {
2249             filterInfo.path = "";
2250         } else {
2251             filterInfo.path = path->valuestring;
2252         }
2253     }
2254 }
2255 
PrintDragShadowInfo()2256 void DragDrawing::PrintDragShadowInfo()
2257 {
2258     FilterInfo filterInfo = g_drawingInfo.filterInfo;
2259     if (!filterInfo.shadowEnable) {
2260         FI_HILOGI("Not supported shadow");
2261         return;
2262     }
2263     FI_HILOGI("dragType:%{public}s, shadowIsFilled:%{public}s, shadowMask:%{public}s, shadowColorStrategy :%{public}d, "
2264         "shadowCorner:%{public}f, offsetX:%{private}f, offsetY:%{private}f, argb:%{public}u, elevation:%{public}f, "
2265         "isHardwareAcceleration:%{public}s", filterInfo.dragType.c_str(),
2266         filterInfo.shadowIsFilled ? "true" : "false", filterInfo.shadowMask ? "true" : "false",
2267         filterInfo.shadowColorStrategy, filterInfo.shadowCorner, filterInfo.offsetX, filterInfo.offsetY,
2268         filterInfo.argb, filterInfo.elevation, filterInfo.isHardwareAcceleration ? "true" : "false");
2269     if (!filterInfo.path.empty()) {
2270         FI_HILOGI("path:%{private}s", filterInfo.path.c_str());
2271     }
2272 }
2273 
ParserFilterInfo(const std::string & filterInfoStr,FilterInfo & filterInfo)2274 bool DragDrawing::ParserFilterInfo(const std::string &filterInfoStr, FilterInfo &filterInfo)
2275 {
2276     FI_HILOGD("FilterInfo size:%{public}zu, filterInfo:%{public}s", filterInfoStr.size(), filterInfoStr.c_str());
2277     if (filterInfoStr.empty()) {
2278         FI_HILOGD("FilterInfo is empty");
2279         return false;
2280     }
2281     JsonParser filterInfoParser;
2282     filterInfoParser.json = cJSON_Parse(filterInfoStr.c_str());
2283     if (!cJSON_IsObject(filterInfoParser.json)) {
2284         FI_HILOGE("FilterInfo is not json object");
2285         return false;
2286     }
2287     cJSON *dipScale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "dip_scale");
2288     if (cJSON_IsNumber(dipScale)) {
2289         filterInfo.dipScale = AdjustDoubleValue(dipScale->valuedouble);
2290     }
2291     cJSON *scale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "scale");
2292     if (cJSON_IsNumber(scale)) {
2293         filterInfo.scale = AdjustDoubleValue(scale->valuedouble);
2294     }
2295     ParserCornerRadiusInfo(filterInfoParser.json, g_drawingInfo.filterInfo);
2296     cJSON *dragType = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "drag_type");
2297     if (cJSON_IsString(dragType)) {
2298         filterInfo.dragType = dragType->valuestring;
2299     }
2300     cJSON *shadowEnable = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "shadow_enable");
2301     if (cJSON_IsBool(shadowEnable)) {
2302         filterInfo.shadowEnable = cJSON_IsTrue(shadowEnable);
2303     }
2304     if (filterInfo.shadowEnable) {
2305         ParserDragShadowInfo(filterInfoParser.json, filterInfo);
2306         if (filterInfo.dragType == "text") {
2307             ParserTextDragShadowInfo(filterInfoParser.json, filterInfo);
2308         }
2309         PrintDragShadowInfo();
2310     }
2311     ParserBlurInfo(filterInfoParser.json, g_drawingInfo.filterInfo);
2312     cJSON *dragNodeGrayscale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "drag_node_gray_scale");
2313     if (cJSON_IsNumber(dragNodeGrayscale)) {
2314         filterInfo.dragNodeGrayscale = static_cast<float>(dragNodeGrayscale->valuedouble);
2315     }
2316     cJSON *eventId = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "event_id");
2317     if (cJSON_IsNumber(eventId)) {
2318         DRAG_DATA_MGR.SetEventId(eventId->valueint);
2319     }
2320     return true;
2321 }
2322 
ParserCornerRadiusInfo(const cJSON * cornerRadiusInfoStr,FilterInfo & filterInfo)2323 void DragDrawing::ParserCornerRadiusInfo(const cJSON *cornerRadiusInfoStr, FilterInfo &filterInfo)
2324 {
2325     CHKPV(cornerRadiusInfoStr);
2326     cJSON *cornerRadius1 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius1");
2327     if (cJSON_IsNumber(cornerRadius1)) {
2328         filterInfo.cornerRadius1 = static_cast<float>(cornerRadius1->valuedouble);
2329     }
2330     cJSON *cornerRadius2 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius2");
2331     if (cJSON_IsNumber(cornerRadius2)) {
2332         filterInfo.cornerRadius2 = static_cast<float>(cornerRadius2->valuedouble);
2333     }
2334     cJSON *cornerRadius3 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius3");
2335     if (cJSON_IsNumber(cornerRadius3)) {
2336         filterInfo.cornerRadius3 = static_cast<float>(cornerRadius3->valuedouble);
2337     }
2338     cJSON *cornerRadius4 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius4");
2339     if (cJSON_IsNumber(cornerRadius4)) {
2340         filterInfo.cornerRadius4 = static_cast<float>(cornerRadius4->valuedouble);
2341     }
2342 }
2343 
ParserBlurInfo(const cJSON * BlurInfoInfoStr,FilterInfo & filterInfo)2344 void DragDrawing::ParserBlurInfo(const cJSON *BlurInfoInfoStr, FilterInfo &filterInfo)
2345 {
2346     CHKPV(BlurInfoInfoStr);
2347     cJSON *opacity = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "dip_opacity");
2348     if (cJSON_IsNumber(opacity)) {
2349         if ((opacity->valuedouble) > MAX_OPACITY || (opacity->valuedouble) <= MIN_OPACITY) {
2350             FI_HILOGE("Parser opacity limits abnormal, opacity:%{public}f", opacity->valuedouble);
2351         } else {
2352             filterInfo.opacity = static_cast<float>(opacity->valuedouble);
2353         }
2354     }
2355     float tempCoef1 = 0.0f;
2356     cJSON *coef1 = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_coef1");
2357     if (cJSON_IsNumber(coef1)) {
2358         tempCoef1 = static_cast<float>(coef1->valuedouble);
2359     }
2360     float tempCoef2 = 0.0f;
2361     cJSON *coef2 = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_coef2");
2362     if (cJSON_IsNumber(coef2)) {
2363         tempCoef2 = static_cast<float>(coef2->valuedouble);
2364     }
2365     filterInfo.coef = { tempCoef1, tempCoef2 };
2366     cJSON *blurRadius = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_radius");
2367     if (cJSON_IsNumber(blurRadius)) {
2368         filterInfo.blurRadius = AdjustDoubleValue(blurRadius->valuedouble);
2369     }
2370     cJSON *blurStaturation = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_staturation");
2371     if (cJSON_IsNumber(blurStaturation)) {
2372         filterInfo.blurStaturation = static_cast<float>(blurStaturation->valuedouble);
2373     }
2374     cJSON *blurBrightness = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_brightness");
2375     if (cJSON_IsNumber(blurBrightness)) {
2376         filterInfo.blurBrightness = static_cast<float>(blurBrightness->valuedouble);
2377     }
2378     cJSON *blurColor = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_color");
2379     if (cJSON_IsNumber(blurColor)) {
2380         filterInfo.blurColor = static_cast<uint32_t>(blurColor->valueint);
2381     }
2382     cJSON *blurStyle = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_style");
2383     if (cJSON_IsNumber(blurStyle)) {
2384         filterInfo.blurStyle = blurStyle->valueint;
2385     }
2386     return;
2387 }
2388 
ParserExtraInfo(const std::string & extraInfoStr,ExtraInfo & extraInfo)2389 bool DragDrawing::ParserExtraInfo(const std::string &extraInfoStr, ExtraInfo &extraInfo)
2390 {
2391     FI_HILOGD("ExtraInfo size:%{public}zu, extraInfo:%{public}s",
2392         extraInfoStr.size(), extraInfoStr.c_str());
2393     if (extraInfoStr.empty()) {
2394         FI_HILOGD("ExtraInfo is empty");
2395         return false;
2396     }
2397     JsonParser extraInfoParser;
2398     extraInfoParser.json = cJSON_Parse(extraInfoStr.c_str());
2399     if (!cJSON_IsObject(extraInfoParser.json)) {
2400         FI_HILOGE("ExtraInfo is not json object");
2401         return false;
2402     }
2403     cJSON *componentType = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_data_type");
2404     if (cJSON_IsString(componentType)) {
2405         extraInfo.componentType = componentType->valuestring;
2406     }
2407     cJSON *blurStyle = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_blur_style");
2408     if (cJSON_IsNumber(blurStyle)) {
2409         extraInfo.blurStyle = blurStyle->valueint;
2410     }
2411     cJSON *cornerRadius = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_corner_radius");
2412     if (cJSON_IsNumber(cornerRadius)) {
2413         extraInfo.cornerRadius = static_cast<float>(cornerRadius->valuedouble);
2414     }
2415     cJSON *allowDistributed = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_allow_distributed");
2416     if (cJSON_IsBool(allowDistributed)) {
2417         extraInfo.allowDistributed = cJSON_IsTrue(allowDistributed) ? true : false;
2418     }
2419     float tempCoef1 = 0.0f;
2420     cJSON *coef1 = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "blur_coef1");
2421     if (cJSON_IsNumber(coef1)) {
2422         tempCoef1 = static_cast<float>(coef1->valuedouble);
2423     }
2424     float tempCoef2 = 0.0f;
2425     cJSON *coef2 = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "blur_coef2");
2426     if (cJSON_IsNumber(coef2)) {
2427         tempCoef2 = static_cast<float>(coef2->valuedouble);
2428     }
2429     extraInfo.coef = { tempCoef1, tempCoef2 };
2430     return true;
2431 }
2432 
GetAllowDragState()2433 bool DragDrawing::GetAllowDragState()
2434 {
2435     return g_drawingInfo.extraInfo.allowDistributed;
2436 }
2437 
SetScreenId(uint64_t screenId)2438 void DragDrawing::SetScreenId(uint64_t screenId)
2439 {
2440     FI_HILOGD("enter");
2441     screenId_ = screenId;
2442 }
2443 
RotateDragWindow(Rosen::Rotation rotation,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool isAnimated)2444 int32_t DragDrawing::RotateDragWindow(Rosen::Rotation rotation,
2445     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool isAnimated)
2446 {
2447     if (needRotatePixelMapXY_) {
2448         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2449         CHKPR(currentPixelMap, RET_ERR);
2450         g_drawingInfo.pixelMapX = -(HALF_RATIO * currentPixelMap->GetWidth());
2451         g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
2452     }
2453     float rotateAngle = (rotation == Rosen::Rotation::ROTATION_0) ? ROTATION_0 :
2454         ROTATION_360 - (ROTATION_90 * static_cast<int32_t>(rotation));
2455     FI_HILOGI("rotateAngle:%{public}f, isAnimated:%{public}d", rotateAngle, isAnimated);
2456     return DoRotateDragWindow(rotateAngle, rsTransaction, isAnimated);
2457 }
2458 
RotateCanvasNode(float pivotX,float pivotY,float rotation)2459 void DragDrawing::RotateCanvasNode(float pivotX, float pivotY, float rotation)
2460 {
2461     FI_HILOGD("enter");
2462     CHKPV(g_drawingInfo.parentNode);
2463     g_drawingInfo.parentNode->SetPivot(pivotX, pivotY);
2464     g_drawingInfo.parentNode->SetRotation(rotation);
2465     if (!g_drawingInfo.multiSelectedNodes.empty()) {
2466         size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2467         for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2468             std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
2469             CHKPV(multiSelectedNode);
2470             float degrees = DEFAULT_ANGLE;
2471             if (i == FIRST_PIXELMAP_INDEX) {
2472                 degrees = rotation + POSITIVE_ANGLE;
2473             } else if (i == SECOND_PIXELMAP_INDEX) {
2474                 degrees = rotation + NEGATIVE_ANGLE;
2475             }
2476             multiSelectedNode->SetPivot(HALF_PIVOT, HALF_PIVOT);
2477             multiSelectedNode->SetRotation(degrees);
2478         }
2479     }
2480 #ifndef OHOS_BUILD_PC_PRODUCT
2481     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
2482         if (!CheckNodesValid()) {
2483             FI_HILOGE("Check nodes valid failed");
2484             return;
2485         }
2486         std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2487         CHKPV(mouseIconNode);
2488         mouseIconNode->SetPivot(DEFAULT_PIVOT, DEFAULT_PIVOT);
2489         mouseIconNode->SetRotation(rotation);
2490     }
2491 #endif // OHOS_BUILD_PC_PRODUCT
2492     float positionX = g_drawingInfo.currentPositionX;
2493     float positionY = g_drawingInfo.currentPositionY;
2494     AdjustRotateDisplayXY(positionX, positionY);
2495     DrawRotateDisplayXY(positionX, positionY);
2496     FI_HILOGD("leave");
2497 }
2498 
SetRotation(Rosen::Rotation rotation)2499 void DragDrawing::SetRotation(Rosen::Rotation rotation)
2500 {
2501     rotation_ = rotation;
2502 }
2503 
ProcessFilter()2504 void DragDrawing::ProcessFilter()
2505 {
2506     FI_HILOGD("enter");
2507     if (g_drawingInfo.nodes.size() <= BACKGROUND_FILTER_INDEX) {
2508         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2509         return;
2510     }
2511     std::shared_ptr<Rosen::RSCanvasNode> filterNode = g_drawingInfo.nodes[BACKGROUND_FILTER_INDEX];
2512     CHKPV(filterNode);
2513     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2514     CHKPV(currentPixelMap);
2515     FilterInfo filterInfo = g_drawingInfo.filterInfo;
2516     ExtraInfo extraInfo = g_drawingInfo.extraInfo;
2517     if (filterInfo.blurStyle != -1) {
2518         SetCustomDragBlur(filterInfo, filterNode);
2519     } else if (extraInfo.componentType == BIG_FOLDER_LABEL) {
2520         SetComponentDragBlur(filterInfo, extraInfo, filterNode);
2521     }
2522     FI_HILOGD("Add filter successfully");
2523     FI_HILOGD("leave");
2524 }
2525 
SetCustomDragBlur(const FilterInfo & filterInfo,std::shared_ptr<Rosen::RSCanvasNode> filterNode)2526 void DragDrawing::SetCustomDragBlur(const FilterInfo &filterInfo, std::shared_ptr<Rosen::RSCanvasNode> filterNode)
2527 {
2528     CHKPV(filterNode);
2529     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2530     CHKPV(currentPixelMap);
2531     Rosen::BLUR_COLOR_MODE mode = (Rosen::BLUR_COLOR_MODE)filterInfo.blurStyle;
2532     std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
2533         RadiusVp2Sigma(filterInfo.blurRadius, filterInfo.dipScale),
2534         filterInfo.blurStaturation, filterInfo.blurBrightness, filterInfo.blurColor, mode);
2535     if (backFilter == nullptr) {
2536         FI_HILOGE("Create backgroundFilter failed");
2537         return;
2538     }
2539     filterNode->SetBackgroundFilter(backFilter);
2540     filterNode->SetGreyCoef(filterInfo.coef);
2541     filterNode->SetAlpha(filterInfo.opacity);
2542     int32_t adjustSize = TWELVE_SIZE * GetScaling();
2543     filterNode->SetBounds(DEFAULT_POSITION_X, adjustSize, currentPixelMap->GetWidth(),
2544         currentPixelMap->GetHeight());
2545     filterNode->SetFrame(DEFAULT_POSITION_X, adjustSize, currentPixelMap->GetWidth(),
2546         currentPixelMap->GetHeight());
2547     if ((filterInfo.blurRadius < 0) || (filterInfo.dipScale < 0) ||
2548         (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
2549         / filterInfo.dipScale) < filterInfo.blurRadius)) {
2550         FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
2551             filterInfo.blurRadius, filterInfo.dipScale);
2552         return;
2553     }
2554     Rosen::Vector4f cornerRadiusVector = { filterInfo.cornerRadius1, filterInfo.cornerRadius2,
2555         filterInfo.cornerRadius3, filterInfo.cornerRadius4 };
2556     filterNode->SetCornerRadius(cornerRadiusVector * filterInfo.dipScale);
2557     FI_HILOGD("Set custom drag blur successfully");
2558 }
2559 
SetComponentDragBlur(const FilterInfo & filterInfo,const ExtraInfo & extraInfo,std::shared_ptr<Rosen::RSCanvasNode> filterNode)2560 void DragDrawing::SetComponentDragBlur(const FilterInfo &filterInfo, const ExtraInfo &extraInfo,
2561     std::shared_ptr<Rosen::RSCanvasNode> filterNode)
2562 {
2563     CHKPV(filterNode);
2564     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2565     CHKPV(currentPixelMap);
2566     std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
2567         RadiusVp2Sigma(RADIUS_VP, filterInfo.dipScale),
2568         DEFAULT_SATURATION, DEFAULT_BRIGHTNESS, DEFAULT_COLOR_VALUE);
2569     if (backFilter == nullptr) {
2570         FI_HILOGE("Create backgroundFilter failed");
2571         return;
2572     }
2573     filterNode->SetBackgroundFilter(backFilter);
2574     filterNode->SetGreyCoef(extraInfo.coef);
2575     filterNode->SetAlpha(filterInfo.opacity);
2576     int32_t adjustSize = TWELVE_SIZE * GetScaling();
2577     filterNode->SetBounds(DEFAULT_POSITION_X, adjustSize, currentPixelMap->GetWidth(),
2578         currentPixelMap->GetHeight());
2579     filterNode->SetFrame(DEFAULT_POSITION_X, adjustSize, currentPixelMap->GetWidth(),
2580         currentPixelMap->GetHeight());
2581     if ((extraInfo.cornerRadius < 0) || (filterInfo.dipScale < 0) ||
2582         (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
2583         / filterInfo.dipScale) < extraInfo.cornerRadius)) {
2584         FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
2585             extraInfo.cornerRadius, filterInfo.dipScale);
2586         return;
2587     }
2588     filterNode->SetCornerRadius(extraInfo.cornerRadius * filterInfo.dipScale);
2589     FI_HILOGD("Set component drag blur successfully");
2590     return;
2591 }
2592 
SetNodesLocation()2593 int32_t DragDrawing::SetNodesLocation()
2594 {
2595     FI_HILOGD("enter");
2596     Rosen::RSAnimationTimingProtocol protocol;
2597     Rosen::RSNode::Animate(protocol, SPRING, [&]() {
2598         float displayX = g_drawingInfo.currentPositionX;
2599         float displayY = g_drawingInfo.currentPositionY;
2600         AdjustRotateDisplayXY(displayX, displayY);
2601         int32_t positionX = displayX + g_drawingInfo.pixelMapX;
2602         int32_t positionY = displayY + g_drawingInfo.pixelMapY - TWELVE_SIZE * GetScaling();
2603         int32_t adjustSize = TWELVE_SIZE * GetScaling();
2604         CHKPV(g_drawingInfo.parentNode);
2605         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2606         CHKPV(currentPixelMap);
2607         g_drawingInfo.parentNode->SetBounds(positionX, positionY, currentPixelMap->GetWidth(),
2608             currentPixelMap->GetHeight() + adjustSize);
2609         g_drawingInfo.parentNode->SetFrame(positionX, positionY, currentPixelMap->GetWidth(),
2610             currentPixelMap->GetHeight() + adjustSize);
2611         if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
2612             size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2613             size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
2614             for (size_t i = 0; (i < multiSelectedNodesSize) && (i < multiSelectedPixelMapsSize); ++i) {
2615                 std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
2616                 std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
2617                 auto pixelMap  = currentPixelMap;
2618                 CHKPV(pixelMap);
2619                 CHKPV(multiSelectedNode);
2620                 CHKPV(multiSelectedPixelMap);
2621                 float multiSelectedPositionX = positionX + (static_cast<float>(pixelMap->GetWidth()) / TWICE_SIZE) -
2622                     (static_cast<float>(multiSelectedPixelMap->GetWidth()) / TWICE_SIZE);
2623                 float multiSelectedPositionY = positionY + (static_cast<float>(pixelMap->GetHeight()) / TWICE_SIZE) -
2624                     (static_cast<float>(multiSelectedPixelMap->GetHeight()) / TWICE_SIZE - adjustSize);
2625                     multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
2626                         multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2627                     multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
2628                         multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2629             }
2630         }
2631     }, [this]() {
2632         FI_HILOGD("SetNodesLocation end");
2633     });
2634 #ifdef IOS_PLATFORM
2635     g_drawingInfo.startNum = actionTime_; // IOS animation starts time
2636 #else
2637     g_drawingInfo.startNum = START_TIME;
2638 #endif // IOS_PLATFORM
2639     g_drawingInfo.needDestroyDragWindow = false;
2640     StartVsync();
2641     FI_HILOGD("leave");
2642     return RET_OK;
2643 }
2644 
2645 
EnterTextEditorArea(bool enable)2646 int32_t DragDrawing::EnterTextEditorArea(bool enable)
2647 {
2648     FI_HILOGD("enter");
2649     if (enable) {
2650         DRAG_DATA_MGR.SetInitialPixelMapLocation({ g_drawingInfo.pixelMapX, g_drawingInfo.pixelMapY });
2651         needRotatePixelMapXY_ = true;
2652         RotatePixelMapXY();
2653     } else {
2654         needRotatePixelMapXY_ = false;
2655         auto initialPixelMapLocation = DRAG_DATA_MGR.GetInitialPixelMapLocation();
2656         g_drawingInfo.pixelMapX = initialPixelMapLocation.first;
2657         g_drawingInfo.pixelMapY = initialPixelMapLocation.second;
2658     }
2659     DRAG_DATA_MGR.SetPixelMapLocation({ g_drawingInfo.pixelMapX, g_drawingInfo.pixelMapY });
2660     if (RunAnimation([this] {
2661         return this->SetNodesLocation();
2662     }) != RET_OK) {
2663         FI_HILOGE("RunAnimation to SetNodesLocation failed");
2664         return RET_ERR;
2665     }
2666     DRAG_DATA_MGR.SetTextEditorAreaFlag(enable);
2667     FI_HILOGI("EnterTextEditorArea %{public}s successfully", (enable ? "true" : "false"));
2668     return RET_OK;
2669 }
2670 
RadiusVp2Sigma(float radiusVp,float dipScale)2671 float DragDrawing::RadiusVp2Sigma(float radiusVp, float dipScale)
2672 {
2673     float radiusPx = radiusVp * dipScale;
2674     return radiusPx > 0.0f ? BLUR_SIGMA_SCALE * radiusPx + 0.5f : 0.0f;
2675 }
2676 
UpdatePreviewStyle(const PreviewStyle & previewStyle)2677 int32_t DragDrawing::UpdatePreviewStyle(const PreviewStyle &previewStyle)
2678 {
2679     FI_HILOGD("enter");
2680     if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
2681         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2682         return RET_ERR;
2683     } else if (ModifyPreviewStyle(g_drawingInfo.nodes[PIXEL_MAP_INDEX], previewStyle) != RET_OK) {
2684         FI_HILOGE("ModifyPreviewStyle failed");
2685         return RET_ERR;
2686     }
2687     if (ModifyMultiPreviewStyle(std::vector<PreviewStyle>(g_drawingInfo.multiSelectedNodes.size(), previewStyle)) !=
2688         RET_OK) {
2689         FI_HILOGE("ModifyPreviewStyle failed");
2690         return RET_ERR;
2691     }
2692     Rosen::RSTransaction::FlushImplicitTransaction();
2693     FI_HILOGD("leave");
2694     return RET_OK;
2695 }
2696 
UpdatePreviewStyleWithAnimation(const PreviewStyle & previewStyle,const PreviewAnimation & animation)2697 int32_t DragDrawing::UpdatePreviewStyleWithAnimation(const PreviewStyle &previewStyle,
2698     const PreviewAnimation &animation)
2699 {
2700     FI_HILOGD("enter");
2701     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
2702     CHKPR(pixelMapNode, RET_ERR);
2703     PreviewStyle originStyle;
2704     originStyle.types = previewStyle.types;
2705     if (auto color = pixelMapNode->GetShowingProperties().GetForegroundColor(); color.has_value()) {
2706         originStyle.foregroundColor = color->AsArgbInt();
2707         originStyle.radius = previewStyle.radius;
2708     }
2709     size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2710     std::vector<PreviewStyle> multiOriginStyles;
2711     for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2712         if (auto color = g_drawingInfo.multiSelectedNodes[i]->GetShowingProperties().GetForegroundColor();
2713             color.has_value()) {
2714             PreviewStyle currentStyle;
2715             currentStyle.types = { PreviewType::FOREGROUND_COLOR, PreviewType::RADIUS };
2716             currentStyle.foregroundColor = color->AsArgbInt();
2717             currentStyle.radius = previewStyle.radius;
2718             multiOriginStyles.push_back(currentStyle);
2719         }
2720     }
2721     if (ModifyPreviewStyle(pixelMapNode, originStyle) != RET_OK) {
2722         FI_HILOGE("ModifyPreviewStyle failed");
2723         return RET_ERR;
2724     }
2725     if (ModifyMultiPreviewStyle(multiOriginStyles) != RET_OK) {
2726         FI_HILOGE("ModifyMultiPreviewStyle failed");
2727         return RET_ERR;
2728     }
2729     Rosen::RSAnimationTimingProtocol protocol;
2730     protocol.SetDuration(animation.duration);
2731     auto curve = AnimationCurve::CreateCurve(animation.curveName, animation.curve);
2732     Rosen::RSNode::Animate(protocol, curve, [&]() {
2733         if (ModifyPreviewStyle(pixelMapNode, previewStyle) != RET_OK) {
2734             FI_HILOGE("ModifyPreviewStyle failed");
2735         }
2736         if (ModifyMultiPreviewStyle(std::vector<PreviewStyle>(multiSelectedNodesSize, previewStyle)) != RET_OK) {
2737             FI_HILOGE("ModifyMultiPreviewStyle failed");
2738         }
2739     },  []() { FI_HILOGD("UpdatePreviewStyleWithAnimation end"); });
2740     FI_HILOGD("leave");
2741     return RET_OK;
2742 }
2743 
UpdateMousePosition(float mousePositionX,float mousePositionY)2744 void DragDrawing::UpdateMousePosition(float mousePositionX, float mousePositionY)
2745 {
2746     if (!CheckNodesValid()) {
2747         FI_HILOGE("Check nodes valid failed");
2748         return;
2749     }
2750     if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
2751         FI_HILOGE("The index out of bounds, node size:%{public}zu", g_drawingInfo.nodes.size());
2752         return;
2753     }
2754     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2755     CHKPV(mouseIconNode);
2756 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
2757     if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE || pointerStyle_.options == MAGIC_STYLE_OPT) {
2758         float positionX = mousePositionX - (static_cast<float>(g_drawingInfo.mouseWidth) / CURSOR_CIRCLE_MIDDLE);
2759         float positionY = mousePositionY - (static_cast<float>(g_drawingInfo.mouseHeight) / CURSOR_CIRCLE_MIDDLE);
2760         mouseIconNode->SetBounds(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2761         mouseIconNode->SetFrame(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2762     } else {
2763         mouseIconNode->SetBounds(mousePositionX, mousePositionY,
2764             g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2765         mouseIconNode->SetFrame(mousePositionX, mousePositionY,
2766             g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2767     }
2768 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2769 }
2770 
RotateDragWindowAsync(Rosen::Rotation rotation)2771 int32_t DragDrawing::RotateDragWindowAsync(Rosen::Rotation rotation)
2772 {
2773     isRunningRotateAnimation_ = true;
2774     int32_t repeatTime = 1;
2775 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
2776     CHKPR(context_, RET_ERR);
2777     timerId_ = context_->GetTimerManager().AddTimer(ASYNC_ROTATE_TIME, repeatTime, [this]() {
2778         RotateDragWindow(rotation_, nullptr, true);
2779         isRunningRotateAnimation_ = false;
2780     });
2781 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2782     if (timerId_ < 0) {
2783         FI_HILOGE("Add timer failed, timerId_:%{public}d", timerId_);
2784         isRunningRotateAnimation_ = false;
2785         return RET_ERR;
2786     }
2787     return RET_OK;
2788 }
2789 
RotateDragWindowSync(const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)2790 int32_t DragDrawing::RotateDragWindowSync(const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
2791 {
2792     FI_HILOGD("enter");
2793     isRunningRotateAnimation_ = true;
2794     RotateDragWindow(rotation_, rsTransaction, true);
2795     isRunningRotateAnimation_ = false;
2796 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
2797     if ((context_ != nullptr) && (timerId_ >= 0)) {
2798         context_->GetTimerManager().RemoveTimer(timerId_);
2799         timerId_ = -1;
2800     }
2801 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2802     return RET_OK;
2803 }
2804 
DoDrawMouse(int32_t mousePositionX,int32_t mousePositionY)2805 void DragDrawing::DoDrawMouse(int32_t mousePositionX, int32_t mousePositionY)
2806 {
2807     if (!CheckNodesValid()) {
2808         FI_HILOGE("Check nodes valid failed");
2809         return;
2810     }
2811     if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
2812         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2813         return;
2814     }
2815 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
2816     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2817     CHKPV(mouseIconNode);
2818     if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE || pointerStyle_.options == MAGIC_STYLE_OPT) {
2819         int32_t positionX = mousePositionX - (g_drawingInfo.mouseWidth / CURSOR_CIRCLE_MIDDLE);
2820         int32_t positionY = mousePositionY - (g_drawingInfo.mouseHeight / CURSOR_CIRCLE_MIDDLE);
2821         mouseIconNode->SetBounds(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2822         mouseIconNode->SetFrame(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2823     } else {
2824         mouseIconNode->SetBounds(mousePositionX, mousePositionY,
2825             g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2826         mouseIconNode->SetFrame(mousePositionX, mousePositionY,
2827             g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2828     }
2829 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2830 }
2831 
UpdateDefaultDragStyle(DragCursorStyle style)2832 int32_t DragDrawing::UpdateDefaultDragStyle(DragCursorStyle style)
2833 {
2834     if (!CheckNodesValid()) {
2835         FI_HILOGE("Check nodes valid failed");
2836         return RET_ERR;
2837     }
2838     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
2839         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2840         return RET_ERR;
2841     }
2842     if (!g_drawingInfo.isCurrentDefaultStyle) {
2843         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2844         CHKPR(dragStyleNode, RET_ERR);
2845         CHKPR(g_drawingInfo.parentNode, RET_ERR);
2846         g_drawingInfo.parentNode->RemoveChild(dragStyleNode);
2847         CHKPR(rsUiDirector_, RET_ERR);
2848         rsUiDirector_->SendMessages();
2849     }
2850     g_drawingInfo.currentStyle = style;
2851     bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
2852     g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
2853     g_drawingInfo.isCurrentDefaultStyle = true;
2854     return RET_OK;
2855 }
2856 
UpdateValidDragStyle(DragCursorStyle style)2857 int32_t DragDrawing::UpdateValidDragStyle(DragCursorStyle style)
2858 {
2859     g_drawingInfo.currentStyle = style;
2860     if (g_drawingInfo.isCurrentDefaultStyle) {
2861         if (!CheckNodesValid()) {
2862             FI_HILOGE("Check nodes valid failed");
2863             return RET_ERR;
2864         }
2865         if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
2866             FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2867             return RET_ERR;
2868         }
2869         std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2870         CHKPR(dragStyleNode, RET_ERR);
2871         CHKPR(g_drawingInfo.parentNode, RET_ERR);
2872         g_drawingInfo.parentNode->AddChild(dragStyleNode);
2873     }
2874     std::string filePath;
2875     if (GetFilePath(filePath) != RET_OK) {
2876         FI_HILOGD("Get file path failed");
2877         return RET_ERR;
2878     }
2879     if (!IsValidSvgFile(filePath)) {
2880         FI_HILOGE("Svg file is invalid");
2881         return RET_ERR;
2882     }
2883     std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
2884     CHKPR(pixelMap, RET_ERR);
2885     bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
2886     g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
2887     g_drawingInfo.isCurrentDefaultStyle = false;
2888     g_drawingInfo.stylePixelMap = pixelMap;
2889     if (!CheckNodesValid()) {
2890         FI_HILOGE("Check nodes valid failed");
2891         return RET_ERR;
2892     }
2893     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2894     CHKPR(dragStyleNode, RET_ERR);
2895     OnDragStyle(dragStyleNode, pixelMap);
2896     CHKPR(rsUiDirector_, RET_ERR);
2897     rsUiDirector_->SendMessages();
2898 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
2899 #ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
2900     DragDFX::WriteUpdateDragStyle(style, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
2901 #endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
2902 #endif // OHOS_BUILD_ENABLE_ARKUI_X
2903     return RET_OK;
2904 }
2905 
ModifyPreviewStyle(std::shared_ptr<Rosen::RSCanvasNode> node,const PreviewStyle & previewStyle)2906 int32_t DragDrawing::ModifyPreviewStyle(std::shared_ptr<Rosen::RSCanvasNode> node, const PreviewStyle &previewStyle)
2907 {
2908     FI_HILOGD("enter");
2909     CHKPR(node, RET_ERR);
2910     if (float radius = 0.0F; ParserRadius(radius)) {
2911         node->SetCornerRadius(radius);
2912         FI_HILOGD("SetCornerRadius by radius:%{public}f", radius);
2913     }
2914     for (const auto &type : previewStyle.types) {
2915         switch (type) {
2916             case PreviewType::FOREGROUND_COLOR: {
2917                 node->SetForegroundColor(previewStyle.foregroundColor);
2918                 break;
2919             }
2920             case PreviewType::OPACITY: {
2921                 node->SetAlpha(previewStyle.opacity / static_cast<float>(HEX_FF));
2922                 break;
2923             }
2924             case PreviewType::RADIUS: {
2925                 node->SetCornerRadius(previewStyle.radius);
2926                 break;
2927             }
2928             case PreviewType::SCALE: {
2929                 node->SetScale(previewStyle.scale);
2930                 break;
2931             }
2932             default: {
2933                 FI_HILOGE("Unsupported type");
2934                 break;
2935             }
2936         }
2937     }
2938     FI_HILOGD("leave");
2939     return RET_OK;
2940 }
2941 
ModifyMultiPreviewStyle(const std::vector<PreviewStyle> & previewStyles)2942 int32_t DragDrawing::ModifyMultiPreviewStyle(const std::vector<PreviewStyle> &previewStyles)
2943 {
2944     size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2945     if (previewStyles.size() != multiSelectedNodesSize) {
2946         FI_HILOGE("Size of previewStyles:%{public}zu does not match multiSelectedNodesSize:%{public}zu",
2947             previewStyles.size(), multiSelectedNodesSize);
2948         return RET_ERR;
2949     }
2950     for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2951         if (ModifyPreviewStyle(g_drawingInfo.multiSelectedNodes[i], previewStyles[i]) != RET_OK) {
2952             FI_HILOGW("ModifyPreviewStyle No.%{public}zu failed", i);
2953         }
2954     }
2955     return RET_OK;
2956 }
2957 
MultiSelectedAnimation(int32_t positionX,int32_t positionY,int32_t adjustSize,bool isMultiSelectedAnimation)2958 void DragDrawing::MultiSelectedAnimation(int32_t positionX, int32_t positionY, int32_t adjustSize,
2959     bool isMultiSelectedAnimation)
2960 {
2961     size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2962     size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
2963     for (size_t i = 0; (i < multiSelectedNodesSize) && (i < multiSelectedPixelMapsSize); ++i) {
2964         std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
2965         std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
2966         auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
2967         CHKPV(currentPixelMap);
2968         CHKPV(multiSelectedNode);
2969         CHKPV(multiSelectedPixelMap);
2970         int32_t multiSelectedPositionX = positionX + (currentPixelMap->GetWidth() / TWICE_SIZE) -
2971             (multiSelectedPixelMap->GetWidth() / TWICE_SIZE);
2972         int32_t multiSelectedPositionY = positionY + (currentPixelMap->GetHeight() / TWICE_SIZE) -
2973             ((multiSelectedPixelMap->GetHeight() / TWICE_SIZE) - adjustSize);
2974         if (isMultiSelectedAnimation) {
2975             Rosen::RSAnimationTimingProtocol protocol;
2976             if (i == FIRST_PIXELMAP_INDEX) {
2977                 protocol.SetDuration(SHORT_DURATION);
2978             } else {
2979                 protocol.SetDuration(LONG_DURATION);
2980             }
2981             Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
2982                 multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
2983                     multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2984                 multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
2985                     multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2986             },  []() { FI_HILOGD("MultiSelectedAnimation end"); });
2987         } else {
2988             multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
2989                 multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2990             multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
2991                 multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2992         }
2993     }
2994 }
2995 
InitMultiSelectedNodes()2996 void DragDrawing::InitMultiSelectedNodes()
2997 {
2998     FI_HILOGD("enter");
2999     size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
3000     for (size_t i = 0; i < multiSelectedPixelMapsSize; ++i) {
3001         std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
3002         std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = Rosen::RSCanvasNode::Create();
3003         multiSelectedNode->SetBgImageWidth(multiSelectedPixelMap->GetWidth());
3004         multiSelectedNode->SetBgImageHeight(multiSelectedPixelMap->GetHeight());
3005         multiSelectedNode->SetBgImagePositionX(0);
3006         multiSelectedNode->SetBgImagePositionY(0);
3007         multiSelectedNode->SetForegroundColor(TRANSPARENT_COLOR_ARGB);
3008         auto rosenImage = std::make_shared<Rosen::RSImage>();
3009         rosenImage->SetPixelMap(multiSelectedPixelMap);
3010         rosenImage->SetImageRepeat(0);
3011         multiSelectedNode->SetBgImage(rosenImage);
3012         float alpha = DEFAULT_ALPHA;
3013         float degrees = DEFAULT_ANGLE;
3014         if (i == FIRST_PIXELMAP_INDEX) {
3015             alpha = FIRST_PIXELMAP_ALPHA;
3016             degrees = POSITIVE_ANGLE;
3017         } else if (i == SECOND_PIXELMAP_INDEX) {
3018             alpha = SECOND_PIXELMAP_ALPHA;
3019             degrees = NEGATIVE_ANGLE;
3020         }
3021         multiSelectedNode->SetRotation(degrees);
3022         multiSelectedNode->SetCornerRadius(g_drawingInfo.filterInfo.cornerRadius1 * g_drawingInfo.filterInfo.dipScale *
3023             g_drawingInfo.filterInfo.scale);
3024         multiSelectedNode->SetAlpha(alpha);
3025         g_drawingInfo.multiSelectedNodes.emplace_back(multiSelectedNode);
3026     }
3027     FI_HILOGD("leave");
3028 }
3029 
ClearMultiSelectedData()3030 void DragDrawing::ClearMultiSelectedData()
3031 {
3032     FI_HILOGD("enter");
3033     if (!g_drawingInfo.multiSelectedNodes.empty()) {
3034         g_drawingInfo.multiSelectedNodes.clear();
3035         g_drawingInfo.multiSelectedNodes.shrink_to_fit();
3036     }
3037     if (!g_drawingInfo.multiSelectedPixelMaps.empty()) {
3038         g_drawingInfo.multiSelectedPixelMaps.clear();
3039         g_drawingInfo.multiSelectedPixelMaps.shrink_to_fit();
3040     }
3041     FI_HILOGD("leave");
3042 }
3043 
RotateDisplayXY(int32_t & displayX,int32_t & displayY)3044 void DragDrawing::RotateDisplayXY(int32_t &displayX, int32_t &displayY)
3045 {
3046 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3047 #ifndef OHOS_BUILD_PC_PRODUCT
3048     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
3049 #else
3050     sptr<Rosen::DisplayInfo> display =
3051         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
3052 #endif // OHOS_BUILD_PC_PRODUCT
3053     if (display == nullptr) {
3054         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
3055 #ifndef OHOS_BUILD_PC_PRODUCT
3056         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3057 #else
3058         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
3059 #endif // OHOS_BUILD_PC_PRODUCT
3060         CHKPV(display);
3061     }
3062     int32_t width = display->GetWidth();
3063     int32_t height = display->GetHeight();
3064 #else
3065     CHKPV(window_);
3066     int32_t width = window_->GetRect().width_;
3067     int32_t height = window_->GetRect().height_;
3068 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3069     switch (rotation_) {
3070         case Rosen::Rotation::ROTATION_0: {
3071             break;
3072         }
3073         case Rosen::Rotation::ROTATION_90: {
3074             int32_t temp = displayY;
3075             displayY = width - displayX;
3076             displayX = temp;
3077             break;
3078         }
3079         case Rosen::Rotation::ROTATION_180: {
3080             displayX = width - displayX;
3081             displayY = height - displayY;
3082             break;
3083         }
3084         case Rosen::Rotation::ROTATION_270: {
3085             int32_t temp = displayX;
3086             displayX = height - displayY;
3087             displayY = temp;
3088             break;
3089         }
3090         default: {
3091             FI_HILOGW("Unknown parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
3092             break;
3093         }
3094     }
3095 }
3096 
RotatePosition(float & displayX,float & displayY)3097 void DragDrawing::RotatePosition(float &displayX, float &displayY)
3098 {
3099 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3100 #ifndef OHOS_BUILD_PC_PRODUCT
3101     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
3102 #else
3103     sptr<Rosen::DisplayInfo> display =
3104         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
3105 #endif // OHOS_BUILD_PC_PRODUCT
3106     if (display == nullptr) {
3107         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
3108 #ifndef OHOS_BUILD_PC_PRODUCT
3109         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3110 #else
3111         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
3112 #endif // OHOS_BUILD_PC_PRODUCT
3113         CHKPV(display);
3114     }
3115     int32_t width = display->GetWidth();
3116     int32_t height = display->GetHeight();
3117 #else
3118     CHKPV(window_);
3119     int32_t width = window_->GetRect().width_;
3120     int32_t height = window_->GetRect().height_;
3121 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3122     switch (rotation_) {
3123         case Rosen::Rotation::ROTATION_0: {
3124             break;
3125         }
3126         case Rosen::Rotation::ROTATION_90: {
3127             int32_t temp = displayY;
3128             displayY = width - displayX;
3129             displayX = temp;
3130             break;
3131         }
3132         case Rosen::Rotation::ROTATION_180: {
3133             displayX = width - displayX;
3134             displayY = height - displayY;
3135             break;
3136         }
3137         case Rosen::Rotation::ROTATION_270: {
3138             int32_t temp = displayX;
3139             displayX = height - displayY;
3140             displayY = temp;
3141             break;
3142         }
3143         default: {
3144             FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
3145             break;
3146         }
3147     }
3148 }
3149 
RotatePixelMapXY()3150 void DragDrawing::RotatePixelMapXY()
3151 {
3152     FI_HILOGI("rotation:%{public}d", static_cast<int32_t>(rotation_));
3153     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3154     CHKPV(currentPixelMap);
3155     switch (rotation_) {
3156         case Rosen::Rotation::ROTATION_0:
3157         case Rosen::Rotation::ROTATION_180: {
3158             g_drawingInfo.pixelMapX = -(HALF_RATIO * currentPixelMap->GetWidth());
3159             g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
3160             break;
3161         }
3162         case Rosen::Rotation::ROTATION_90:
3163         case Rosen::Rotation::ROTATION_270: {
3164             g_drawingInfo.pixelMapX = -(HALF_RATIO * currentPixelMap->GetWidth());
3165             g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
3166             break;
3167         }
3168         default: {
3169             FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
3170             break;
3171         }
3172     }
3173 }
3174 
ResetAnimationParameter()3175 void DragDrawing::ResetAnimationParameter()
3176 {
3177     FI_HILOGI("enter");
3178     hasRunningScaleAnimation_ = false;
3179     CHKPV(handler_);
3180 #ifndef IOS_PLATFORM
3181     handler_->RemoveAllEvents();
3182     handler_->RemoveAllFileDescriptorListeners();
3183 #endif // IOS_PLATFORM
3184     handler_ = nullptr;
3185     UpdateReceiverLocked(nullptr);
3186     FI_HILOGI("leave");
3187 }
3188 
ResetAnimationFlag(bool isForce)3189 void DragDrawing::ResetAnimationFlag(bool isForce)
3190 {
3191     FI_HILOGI("enter");
3192 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3193     if (!isForce && (g_drawingInfo.context != nullptr) && (g_drawingInfo.timerId >= 0)) {
3194         g_drawingInfo.context->GetTimerManager().RemoveTimer(g_drawingInfo.timerId);
3195         g_drawingInfo.timerId = -1;
3196     }
3197 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3198     if (drawDynamicEffectModifier_ != nullptr) {
3199         CHKPV(g_drawingInfo.rootNode);
3200         g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
3201         drawDynamicEffectModifier_ = nullptr;
3202     }
3203     DestroyDragWindow();
3204     g_drawingInfo.isRunning = false;
3205     g_drawingInfo.timerId = -1;
3206     ResetAnimationParameter();
3207     FI_HILOGI("leave");
3208 }
3209 
DoEndAnimation()3210 void DragDrawing::DoEndAnimation()
3211 {
3212     FI_HILOGI("enter");
3213 #ifdef IOS_PLATFORM
3214     g_drawingInfo.startNum = actionTime_;
3215 #else
3216     g_drawingInfo.startNum = START_TIME;
3217 #endif // IOS_PLATFORM
3218     g_drawingInfo.needDestroyDragWindow = true;
3219 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3220     if (g_drawingInfo.context != nullptr) {
3221         int32_t repeatCount = 1;
3222         g_drawingInfo.timerId = g_drawingInfo.context->GetTimerManager().AddTimer(TIMEOUT_MS, repeatCount, [this]() {
3223             FI_HILOGW("Timeout, automatically reset animation flag");
3224             ResetAnimationFlag(true);
3225         });
3226     }
3227 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3228     StartVsync();
3229     FI_HILOGI("leave");
3230 }
3231 
ResetParameter()3232 void DragDrawing::ResetParameter()
3233 {
3234     FI_HILOGI("enter");
3235     g_drawingInfo.startNum = START_TIME;
3236     g_drawingInfo.needDestroyDragWindow = false;
3237     needRotatePixelMapXY_ = false;
3238     hasRunningStopAnimation_ = false;
3239     needMultiSelectedAnimation_ = true;
3240     pointerStyle_ = {};
3241     g_drawingInfo.isExistScalingValue = false;
3242     g_drawingInfo.currentPositionX = -1.0f;
3243     g_drawingInfo.currentPositionY = -1.0f;
3244     g_drawingInfo.sourceType = -1;
3245     g_drawingInfo.currentDragNum = -1;
3246     g_drawingInfo.pixelMapX = -1;
3247     g_drawingInfo.pixelMapY = -1;
3248     g_drawingInfo.displayX = -1;
3249     g_drawingInfo.displayY = -1;
3250     g_drawingInfo.mouseWidth = 0;
3251     g_drawingInfo.mouseHeight = 0;
3252     g_drawingInfo.rootNodeWidth = -1;
3253     g_drawingInfo.rootNodeHeight = -1;
3254     DragDrawing::UpdataGlobalPixelMapLocked(nullptr);
3255     g_drawingInfo.stylePixelMap = nullptr;
3256     g_drawingInfo.isPreviousDefaultStyle = false;
3257     g_drawingInfo.isCurrentDefaultStyle = false;
3258     g_drawingInfo.currentStyle = DragCursorStyle::DEFAULT;
3259     g_drawingInfo.filterInfo = {};
3260     g_drawingInfo.extraInfo = {};
3261 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3262     StopVSyncStation();
3263     frameCallback_ = nullptr;
3264 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3265     isRunningRotateAnimation_ = false;
3266     screenRotateState_ = false;
3267     FI_HILOGI("leave");
3268 }
3269 
3270 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
StopVSyncStation()3271 void DragDrawing::StopVSyncStation()
3272 {
3273     FI_HILOGI("enter");
3274     dragSmoothProcessor_.ResetParameters();
3275     vSyncStation_.StopVSyncRequest();
3276     FI_HILOGI("leave");
3277 }
3278 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3279 
DoRotateDragWindow(float rotation,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool isAnimated)3280 int32_t DragDrawing::DoRotateDragWindow(float rotation,
3281     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool isAnimated)
3282 {
3283     FI_HILOGI("Rotation:%{public}f, isAnimated:%{public}d", rotation, isAnimated);
3284     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3285     CHKPR(currentPixelMap, RET_ERR);
3286     if ((currentPixelMap->GetWidth() <= 0) || (currentPixelMap->GetHeight() <= 0)) {
3287         FI_HILOGE("Invalid parameter pixelmap");
3288         return RET_ERR;
3289     }
3290     float adjustSize = TWELVE_SIZE * GetScaling();
3291     float pivotX = HALF_PIVOT;
3292     float pivotY = 0.0f;
3293     if (fabsf(adjustSize + currentPixelMap->GetHeight()) < EPSILON) {
3294         pivotY = HALF_PIVOT;
3295     } else {
3296         pivotY = ((currentPixelMap->GetHeight() * 1.0 / TWICE_SIZE) + adjustSize) /
3297             (adjustSize + currentPixelMap->GetHeight());
3298     }
3299     if (!isAnimated) {
3300         DragWindowRotateInfo_.rotation = rotation;
3301         DragWindowRotateInfo_.pivotX = pivotX;
3302         DragWindowRotateInfo_.pivotY = pivotY;
3303         RotateCanvasNode(pivotX, pivotY, rotation);
3304         Rosen::RSTransaction::FlushImplicitTransaction();
3305         return RET_OK;
3306     }
3307     return DoRotateDragWindowAnimation(rotation, pivotX, pivotY, rsTransaction);
3308 }
3309 
3310 template <typename T>
AdjustRotateDisplayXY(T & displayX,T & displayY)3311 void DragDrawing::AdjustRotateDisplayXY(T &displayX, T &displayY)
3312 {
3313     FI_HILOGD("rotation:%{public}d", static_cast<int32_t>(rotation_));
3314     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3315     CHKPV(currentPixelMap);
3316     switch (rotation_) {
3317         case Rosen::Rotation::ROTATION_0: {
3318             break;
3319         }
3320         case Rosen::Rotation::ROTATION_90: {
3321             displayX -= (currentPixelMap->GetWidth() - currentPixelMap->GetHeight()) / TWICE_SIZE +
3322                 g_drawingInfo.pixelMapX - g_drawingInfo.pixelMapY;
3323             displayY -= (currentPixelMap->GetWidth() - currentPixelMap->GetHeight()) / TWICE_SIZE +
3324                 g_drawingInfo.pixelMapX + currentPixelMap->GetHeight() + g_drawingInfo.pixelMapY;
3325             break;
3326         }
3327         case Rosen::Rotation::ROTATION_180: {
3328             displayX -= currentPixelMap->GetWidth() + (g_drawingInfo.pixelMapX * TWICE_SIZE);
3329             displayY -= currentPixelMap->GetHeight() + (g_drawingInfo.pixelMapY * TWICE_SIZE);
3330             break;
3331         }
3332         case Rosen::Rotation::ROTATION_270: {
3333             displayX -= (currentPixelMap->GetWidth() - currentPixelMap->GetHeight()) / TWICE_SIZE +
3334                 g_drawingInfo.pixelMapX + currentPixelMap->GetHeight() + g_drawingInfo.pixelMapY;
3335             displayY += (currentPixelMap->GetWidth() - currentPixelMap->GetHeight()) / TWICE_SIZE +
3336                 g_drawingInfo.pixelMapX - g_drawingInfo.pixelMapY;
3337             break;
3338         }
3339         default: {
3340             FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
3341             break;
3342         }
3343     }
3344 }
3345 
DrawRotateDisplayXY(float positionX,float positionY)3346 void DragDrawing::DrawRotateDisplayXY(float positionX, float positionY)
3347 {
3348     FI_HILOGD("enter");
3349     float adjustSize = TWELVE_SIZE * GetScaling();
3350     float parentPositionX = positionX + g_drawingInfo.pixelMapX;
3351     float parentPositionY = positionY + g_drawingInfo.pixelMapY - adjustSize;
3352     auto parentNode = g_drawingInfo.parentNode;
3353     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3354     CHKPV(parentNode);
3355     CHKPV(currentPixelMap);
3356     parentNode->SetBounds(parentPositionX, parentPositionY, currentPixelMap->GetWidth(),
3357         currentPixelMap->GetHeight() + adjustSize);
3358     parentNode->SetFrame(parentPositionX, parentPositionY, currentPixelMap->GetWidth(),
3359         currentPixelMap->GetHeight() + adjustSize);
3360     if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
3361         DoMultiSelectedAnimation(parentPositionX, parentPositionY, adjustSize, false);
3362     }
3363     FI_HILOGD("leave");
3364 }
3365 
ScreenRotateAdjustDisplayXY(Rosen::Rotation rotation,Rosen::Rotation lastRotation,float & displayX,float & displayY)3366 void DragDrawing::ScreenRotateAdjustDisplayXY(
3367     Rosen::Rotation rotation, Rosen::Rotation lastRotation, float &displayX, float &displayY)
3368 {
3369     FI_HILOGI("enter");
3370 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3371 #ifndef OHOS_BUILD_PC_PRODUCT
3372     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
3373 #else
3374     sptr<Rosen::DisplayInfo> display =
3375         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
3376 #endif // OHOS_BUILD_PC_PRODUCT
3377     if (display == nullptr) {
3378         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
3379 #ifndef OHOS_BUILD_PC_PRODUCT
3380         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3381 #else
3382         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
3383 #endif // OHOS_BUILD_PC_PRODUCT
3384         CHKPV(display);
3385     }
3386     int32_t width = display->GetWidth();
3387     int32_t height = display->GetHeight();
3388 #else
3389     CHKPV(window_);
3390     int32_t width = window_->GetRect().width_;
3391     int32_t height = window_->GetRect().height_;
3392 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3393     if ((static_cast<int32_t>(lastRotation) + NUM_ONE) % NUM_FOUR == static_cast<int32_t>(rotation)) {
3394         int32_t temp = displayX;
3395         displayX = width - displayY;
3396         displayY = temp;
3397     } else if ((static_cast<int32_t>(lastRotation) + NUM_TWO) % NUM_FOUR == static_cast<int32_t>(rotation)) {
3398         displayX = width - displayX;
3399         displayY = height - displayY;
3400     } else {
3401         int32_t temp = displayY;
3402         displayY = height - displayX;
3403         displayX = temp;
3404     }
3405     FI_HILOGI("leave");
3406 }
3407 
UpdateDragDataForSuperHub(const DragData & dragData)3408 void DragDrawing::UpdateDragDataForSuperHub(const DragData &dragData)
3409 {
3410     g_dragDataForSuperHub.extraInfo = dragData.extraInfo;
3411     g_dragDataForSuperHub.sourceType = dragData.sourceType;
3412     g_dragDataForSuperHub.displayX = dragData.displayX;
3413     g_dragDataForSuperHub.displayY = dragData.displayY;
3414     g_dragDataForSuperHub.dragNum = dragData.dragNum;
3415     g_dragDataForSuperHub.summarys = dragData.summarys;
3416 }
3417 
AccessGlobalPixelMapLocked()3418 std::shared_ptr<Media::PixelMap> DragDrawing::AccessGlobalPixelMapLocked()
3419 {
3420     std::shared_lock<std::shared_mutex> lock(g_pixelMapLock);
3421     return g_drawingInfo.pixelMap;
3422 }
3423 
UpdataGlobalPixelMapLocked(std::shared_ptr<Media::PixelMap> pixelmap)3424 void DragDrawing::UpdataGlobalPixelMapLocked(std::shared_ptr<Media::PixelMap> pixelmap)
3425 {
3426     std::unique_lock<std::shared_mutex> lock(g_pixelMapLock);
3427     g_drawingInfo.pixelMap = pixelmap;
3428 }
3429 
AccessReceiverLocked()3430 std::shared_ptr<Rosen::VSyncReceiver> DragDrawing::AccessReceiverLocked()
3431 {
3432     std::shared_lock<std::shared_mutex> lock(receiverMutex_);
3433     return receiver_;
3434 }
3435 
UpdateReceiverLocked(std::shared_ptr<Rosen::VSyncReceiver> receiver)3436 void DragDrawing::UpdateReceiverLocked(std::shared_ptr<Rosen::VSyncReceiver> receiver)
3437 {
3438     std::unique_lock<std::shared_mutex> lock(receiverMutex_);
3439     receiver_ = receiver;
3440 }
3441 
ScreenRotate(Rosen::Rotation rotation,Rosen::Rotation lastRotation)3442 void DragDrawing::ScreenRotate(Rosen::Rotation rotation, Rosen::Rotation lastRotation)
3443 {
3444     FI_HILOGI("enter, rotation:%{public}d, lastRotation:%{public}d", static_cast<int32_t>(rotation),
3445         static_cast<int32_t>(lastRotation));
3446     ScreenRotateAdjustDisplayXY(rotation, lastRotation, g_drawingInfo.x, g_drawingInfo.y);
3447     DrawRotateDisplayXY(g_drawingInfo.x, g_drawingInfo.y);
3448 #ifndef OHOS_BUILD_PC_PRODUCT
3449     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
3450         ScreenRotateAdjustDisplayXY(
3451             rotation, lastRotation, g_drawingInfo.currentPositionX, g_drawingInfo.currentPositionY);
3452         UpdateMousePosition(g_drawingInfo.currentPositionX, g_drawingInfo.currentPositionY);
3453     }
3454 #endif // OHOS_BUILD_PC_PRODUCT
3455     Rosen::RSTransaction::FlushImplicitTransaction();
3456     screenRotateState_ = true;
3457     FI_HILOGI("leave");
3458 }
3459 
DoRotateDragWindowAnimation(float rotation,float pivotX,float pivotY,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)3460 int32_t DragDrawing::DoRotateDragWindowAnimation(float rotation, float pivotX, float pivotY,
3461     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
3462 {
3463     FI_HILOGD("enter");
3464     if (rsTransaction != nullptr) {
3465         Rosen::RSTransaction::FlushImplicitTransaction();
3466         rsTransaction->Begin();
3467     }
3468     if ((rotation == ROTATION_0) && (DragWindowRotateInfo_.rotation == ROTATION_270)) {
3469         RotateCanvasNode(DragWindowRotateInfo_.pivotX, DragWindowRotateInfo_.pivotY, -ROTATION_90);
3470     } else if ((rotation == ROTATION_270) && (DragWindowRotateInfo_.rotation == ROTATION_0)) {
3471         RotateCanvasNode(DragWindowRotateInfo_.pivotX, DragWindowRotateInfo_.pivotY, ROTATION_360);
3472     }
3473 
3474     Rosen::RSAnimationTimingProtocol protocol;
3475     protocol.SetDuration(ANIMATION_DURATION);
3476     Rosen::RSNode::Animate(protocol, SPRING, [&]() {
3477         RotateCanvasNode(pivotX, pivotY, rotation);
3478         DragWindowRotateInfo_.rotation = rotation;
3479         DragWindowRotateInfo_.pivotX = pivotX;
3480         DragWindowRotateInfo_.pivotY = pivotY;
3481         return RET_OK;
3482     },  []() { FI_HILOGD("DoRotateDragWindowAnimation end"); });
3483     if (rsTransaction != nullptr) {
3484         rsTransaction->Commit();
3485     } else {
3486         Rosen::RSTransaction::FlushImplicitTransaction();
3487     }
3488     FI_HILOGD("leave");
3489     return RET_OK;
3490 }
3491 
ParserRadius(float & radius)3492 bool DragDrawing::ParserRadius(float &radius)
3493 {
3494     FilterInfo filterInfo = g_drawingInfo.filterInfo;
3495     ExtraInfo extraInfo = g_drawingInfo.extraInfo;
3496     if ((extraInfo.cornerRadius < 0) || (filterInfo.dipScale < 0) ||
3497         (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
3498         / filterInfo.dipScale) < extraInfo.cornerRadius)) {
3499         FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
3500             extraInfo.cornerRadius, filterInfo.dipScale);
3501         return false;
3502     }
3503     radius = extraInfo.cornerRadius * filterInfo.dipScale;
3504     return true;
3505 }
3506 
~DragDrawing()3507 DragDrawing::~DragDrawing()
3508 {
3509 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3510     if (dragExtHandler_ != nullptr) {
3511         dlclose(dragExtHandler_);
3512         dragExtHandler_ = nullptr;
3513     }
3514 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3515 }
3516 
Draw(Rosen::RSDrawingContext & context) const3517 void DrawSVGModifier::Draw(Rosen::RSDrawingContext& context) const
3518 {
3519     FI_HILOGD("enter");
3520     CHKPV(stylePixelMap_);
3521     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3522     CHKPV(currentPixelMap);
3523     float scalingValue = GetScaling();
3524     if (SCALE_THRESHOLD_EIGHT < scalingValue || fabsf(SCALE_THRESHOLD_EIGHT - scalingValue) < EPSILON) {
3525         FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
3526         return;
3527     }
3528     int32_t adjustSize = EIGHT_SIZE * scalingValue;
3529     int32_t svgTouchPositionX = currentPixelMap->GetWidth() + adjustSize - stylePixelMap_->GetWidth();
3530     if (!CheckNodesValid()) {
3531         FI_HILOGE("Check nodes valid failed");
3532         return;
3533     }
3534     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3535     CHKPV(dragStyleNode);
3536     adjustSize = (TWELVE_SIZE - EIGHT_SIZE) * scalingValue;
3537     dragStyleNode->SetBounds(svgTouchPositionX, adjustSize, stylePixelMap_->GetWidth() + adjustSize,
3538         stylePixelMap_->GetHeight());
3539     dragStyleNode->SetFrame(svgTouchPositionX, adjustSize, stylePixelMap_->GetWidth() + adjustSize,
3540         stylePixelMap_->GetHeight());
3541     dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
3542     dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
3543     dragStyleNode->SetBgImagePositionX(0);
3544     dragStyleNode->SetBgImagePositionY(0);
3545     auto rosenImage = std::make_shared<Rosen::RSImage>();
3546     rosenImage->SetPixelMap(stylePixelMap_);
3547     rosenImage->SetImageRepeat(0);
3548     dragStyleNode->SetBgImage(rosenImage);
3549     Rosen::RSTransaction::FlushImplicitTransaction();
3550     FI_HILOGD("leave");
3551 }
3552 
ConvertShadowColorStrategy(int32_t shadowColorStrategy) const3553 Rosen::SHADOW_COLOR_STRATEGY DrawPixelMapModifier::ConvertShadowColorStrategy(int32_t shadowColorStrategy) const
3554 {
3555     if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE)) {
3556         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE ;
3557     } else if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_AVERAGE)) {
3558         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_AVERAGE ;
3559     } else if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN)) {
3560         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN ;
3561     } else {
3562         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE;
3563     }
3564 }
3565 
SetTextDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const3566 void DrawPixelMapModifier::SetTextDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const
3567 {
3568     if (!g_drawingInfo.filterInfo.path.empty()) {
3569         FI_HILOGD("path:%{private}s", g_drawingInfo.filterInfo.path.c_str());
3570         pixelMapNode->SetShadowPath(Rosen::RSPath::CreateRSPath(g_drawingInfo.filterInfo.path));
3571     } else {
3572         FI_HILOGW("path is empty");
3573     }
3574 }
3575 
SetDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const3576 void DrawPixelMapModifier::SetDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const
3577 {
3578     if ((g_drawingInfo.filterInfo.dragType == "text") && (g_drawingInfo.filterInfo.path.empty())) {
3579         FI_HILOGI("path is empty");
3580         return;
3581     }
3582     pixelMapNode->SetShadowOffset(g_drawingInfo.filterInfo.offsetX, g_drawingInfo.filterInfo.offsetY);
3583     pixelMapNode->SetShadowColor(g_drawingInfo.filterInfo.argb);
3584     pixelMapNode->SetShadowMask(g_drawingInfo.filterInfo.shadowMask);
3585     pixelMapNode->SetShadowIsFilled(g_drawingInfo.filterInfo.shadowIsFilled);
3586     pixelMapNode->SetShadowColorStrategy(ConvertShadowColorStrategy(g_drawingInfo.filterInfo.shadowColorStrategy));
3587     if (g_drawingInfo.filterInfo.isHardwareAcceleration) {
3588         pixelMapNode->SetShadowElevation(g_drawingInfo.filterInfo.elevation);
3589     } else {
3590         pixelMapNode->SetShadowRadius(g_drawingInfo.filterInfo.shadowCorner);
3591     }
3592     if (g_drawingInfo.filterInfo.dragType == "text") {
3593         SetTextDragShadow(pixelMapNode);
3594     }
3595 }
3596 
Draw(Rosen::RSDrawingContext & context) const3597 void DrawPixelMapModifier::Draw(Rosen::RSDrawingContext &context) const
3598 {
3599     FI_HILOGD("enter");
3600     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3601     CHKPV(currentPixelMap);
3602     int32_t pixelMapWidth = currentPixelMap->GetWidth();
3603     int32_t pixelMapHeight = currentPixelMap->GetHeight();
3604     if (!CheckNodesValid()) {
3605         FI_HILOGE("Check nodes valid failed");
3606         return;
3607     }
3608     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
3609     CHKPV(pixelMapNode);
3610     if (g_drawingInfo.filterInfo.shadowEnable) {
3611         SetDragShadow(pixelMapNode);
3612     }
3613     int32_t adjustSize = TWELVE_SIZE * GetScaling();
3614     pixelMapNode->SetBounds(DEFAULT_POSITION_X, adjustSize, pixelMapWidth, pixelMapHeight);
3615     pixelMapNode->SetFrame(DEFAULT_POSITION_X, adjustSize, pixelMapWidth, pixelMapHeight);
3616     pixelMapNode->SetBgImageWidth(pixelMapWidth);
3617     pixelMapNode->SetBgImageHeight(pixelMapHeight);
3618     pixelMapNode->SetBgImagePositionX(0);
3619     pixelMapNode->SetBgImagePositionY(0);
3620     Rosen::Drawing::AdaptiveImageInfo rsImageInfo = { 1, 0, {}, 1, 0, pixelMapWidth, pixelMapHeight };
3621     auto cvs = pixelMapNode->BeginRecording(pixelMapWidth, pixelMapHeight);
3622     CHKPV(cvs);
3623     Rosen::Drawing::Brush brush;
3624     cvs->AttachBrush(brush);
3625     FilterInfo filterInfo = g_drawingInfo.filterInfo;
3626     if (g_drawingInfo.filterInfo.shadowEnable && !filterInfo.path.empty() &&
3627         g_drawingInfo.filterInfo.dragType == "text") {
3628         auto rsPath = Rosen::RSPath::CreateRSPath(filterInfo.path);
3629         cvs->Save();
3630         cvs->ClipPath(rsPath->GetDrawingPath(), Rosen::Drawing::ClipOp::INTERSECT, true);
3631         cvs->DrawPixelMapWithParm(currentPixelMap, rsImageInfo, Rosen::Drawing::SamplingOptions());
3632         cvs->Restore();
3633     } else {
3634         cvs->DrawPixelMapWithParm(currentPixelMap, rsImageInfo, Rosen::Drawing::SamplingOptions());
3635     }
3636     cvs->DetachBrush();
3637     pixelMapNode->SetClipToBounds(true);
3638     pixelMapNode->FinishRecording();
3639     Rosen::RSTransaction::FlushImplicitTransaction();
3640     FI_HILOGD("leave");
3641 }
3642 
Draw(Rosen::RSDrawingContext & context) const3643 void DrawMouseIconModifier::Draw(Rosen::RSDrawingContext &context) const
3644 {
3645     FI_HILOGD("enter");
3646 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3647     std::shared_ptr<Media::PixelMap> pixelMap = std::make_shared<Media::PixelMap>();
3648     int32_t ret = RET_ERR;
3649 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
3650     ret = MMI::InputManager::GetInstance()->GetPointerSnapshot(&pixelMap);
3651 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
3652     if (ret != RET_OK) {
3653         FI_HILOGE("Get pointer snapshot failed, ret:%{public}d", ret);
3654         pixelMap = DrawFromSVG();
3655     }
3656     CHKPV(pixelMap);
3657     OnDraw(pixelMap);
3658 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3659     FI_HILOGD("leave");
3660 }
3661 
DrawFromSVG() const3662 std::shared_ptr<Media::PixelMap> DrawMouseIconModifier::DrawFromSVG() const
3663 {
3664     std::string imagePath;
3665     if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE) {
3666         imagePath = MOUSE_DRAG_CURSOR_CIRCLE_PATH;
3667     } else {
3668         imagePath = MOUSE_DRAG_DEFAULT_PATH;
3669     }
3670     int32_t pointerSize = pointerStyle_.size;
3671     int32_t pointerColor = pointerStyle_.color;
3672     int32_t cursorPixel = DEVICE_INDEPENDENT_PIXEL;
3673 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3674     if (pointerStyle_.options == MAGIC_STYLE_OPT) {
3675         imagePath = MOUSE_DRAG_MAGIC_DEFAULT_PATH;
3676         int32_t ret = MMI::InputManager::GetInstance()->GetPointerSize(pointerSize);
3677         if (ret != RET_OK) {
3678             FI_HILOGW("Get pointer size failed, ret:%{public}d", ret);
3679         }
3680         ret = MMI::InputManager::GetInstance()->GetPointerColor(pointerColor);
3681         if (ret != RET_OK) {
3682             FI_HILOGW("Get pointer color failed, ret:%{public}d", ret);
3683         }
3684         cursorPixel = MAGIC_INDEPENDENT_PIXEL;
3685     }
3686 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3687     Media::SourceOptions opts;
3688     opts.formatHint = "image/svg+xml";
3689     uint32_t errCode = 0;
3690     auto imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errCode);
3691     if (imageSource == nullptr) {
3692         FI_HILOGW("imageSource is null");
3693         return nullptr;
3694     }
3695     if (pointerSize < DEFAULT_MOUSE_SIZE) {
3696         FI_HILOGD("Invalid pointerSize:%{public}d", pointerSize);
3697         pointerSize = DEFAULT_MOUSE_SIZE;
3698     }
3699     Media::DecodeOptions decodeOpts;
3700     decodeOpts.desiredSize = {
3701         .width = pow(INCREASE_RATIO, pointerSize - 1) * cursorPixel * GetScaling(),
3702         .height = pow(INCREASE_RATIO, pointerSize - 1) * cursorPixel * GetScaling()
3703     };
3704     if (pointerColor != INVALID_COLOR_VALUE) {
3705         decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
3706     }
3707     return imageSource->CreatePixelMap(decodeOpts, errCode);
3708 }
3709 
OnDraw(std::shared_ptr<Media::PixelMap> pixelMap) const3710 void DrawMouseIconModifier::OnDraw(std::shared_ptr<Media::PixelMap> pixelMap) const
3711 {
3712     FI_HILOGD("enter");
3713 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3714     CHKPV(pixelMap);
3715     if (!CheckNodesValid()) {
3716         FI_HILOGE("Check nodes valid failed");
3717         return;
3718     }
3719     g_drawingInfo.mouseWidth = pixelMap->GetWidth();
3720     g_drawingInfo.mouseHeight = pixelMap->GetHeight();
3721     if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
3722         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3723         return;
3724     }
3725     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
3726     CHKPV(mouseIconNode);
3727     mouseIconNode->SetBgImageWidth(pixelMap->GetWidth());
3728     mouseIconNode->SetBgImageHeight(pixelMap->GetHeight());
3729     mouseIconNode->SetBgImagePositionX(0);
3730     mouseIconNode->SetBgImagePositionY(0);
3731     auto rosenImage = std::make_shared<Rosen::RSImage>();
3732     rosenImage->SetPixelMap(pixelMap);
3733     rosenImage->SetImageRepeat(0);
3734     mouseIconNode->SetBgImage(rosenImage);
3735     Rosen::RSTransaction::FlushImplicitTransaction();
3736 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3737     FI_HILOGD("leave");
3738 }
3739 
Draw(Rosen::RSDrawingContext & context) const3740 void DrawDynamicEffectModifier::Draw(Rosen::RSDrawingContext &context) const
3741 {
3742     FI_HILOGD("enter");
3743     CHKPV(alpha_);
3744     CHKPV(g_drawingInfo.parentNode);
3745     g_drawingInfo.parentNode->SetAlpha(alpha_->Get());
3746     CHKPV(scale_);
3747     g_drawingInfo.parentNode->SetScale(scale_->Get(), scale_->Get());
3748     Rosen::RSTransaction::FlushImplicitTransaction();
3749     FI_HILOGD("leave");
3750 }
3751 
SetAlpha(float alpha)3752 void DrawDynamicEffectModifier::SetAlpha(float alpha)
3753 {
3754     FI_HILOGD("enter");
3755     if (alpha_ == nullptr) {
3756         alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3757         Rosen::RSModifier::AttachProperty(alpha_);
3758         return;
3759     }
3760     alpha_->Set(alpha);
3761     FI_HILOGD("leave");
3762 }
3763 
SetScale(float scale)3764 void DrawDynamicEffectModifier::SetScale(float scale)
3765 {
3766     FI_HILOGD("enter");
3767     if (scale_ == nullptr) {
3768         scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3769         Rosen::RSModifier::AttachProperty(scale_);
3770         return;
3771     }
3772     scale_->Set(scale);
3773     FI_HILOGD("leave");
3774 }
3775 
Draw(Rosen::RSDrawingContext & context) const3776 void DrawStyleChangeModifier::Draw(Rosen::RSDrawingContext &context) const
3777 {
3778     FI_HILOGD("enter");
3779     if (!CheckNodesValid()) {
3780         FI_HILOGE("Check nodes valid failed");
3781         return;
3782     }
3783     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3784         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3785         return;
3786     }
3787     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3788     CHKPV(dragStyleNode);
3789     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
3790     CHKPV(currentPixelMap);
3791     float pixelMapWidth = currentPixelMap->GetWidth();
3792     if (stylePixelMap_ == nullptr) {
3793         if (scale_ == nullptr) {
3794             return;
3795         }
3796         dragStyleNode->SetScale(scale_->Get());
3797         return;
3798     }
3799     float scalingValue = GetScaling();
3800     if ((1.0 * INT_MAX / EIGHT_SIZE) <= scalingValue) {
3801         return;
3802     }
3803     int32_t adjustSize = EIGHT_SIZE * scalingValue;
3804     int32_t svgTouchPositionX = pixelMapWidth + adjustSize - stylePixelMap_->GetWidth();
3805     dragStyleNode->SetBounds(svgTouchPositionX, (TWELVE_SIZE-EIGHT_SIZE)*scalingValue, stylePixelMap_->GetWidth(),
3806         stylePixelMap_->GetHeight());
3807     dragStyleNode->SetFrame(svgTouchPositionX, (TWELVE_SIZE-EIGHT_SIZE)*scalingValue, stylePixelMap_->GetWidth(),
3808         stylePixelMap_->GetHeight());
3809     dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
3810     dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
3811     dragStyleNode->SetBgImagePositionX(0);
3812     dragStyleNode->SetBgImagePositionY(0);
3813     auto rosenImage = std::make_shared<Rosen::RSImage>();
3814     rosenImage->SetPixelMap(stylePixelMap_);
3815     rosenImage->SetImageRepeat(0);
3816     dragStyleNode->SetBgImage(rosenImage);
3817     Rosen::RSTransaction::FlushImplicitTransaction();
3818     FI_HILOGD("leave");
3819 }
3820 
SetScale(float scale)3821 void DrawStyleChangeModifier::SetScale(float scale)
3822 {
3823     FI_HILOGD("enter");
3824     if (scale_ == nullptr) {
3825         scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3826         Rosen::RSModifier::AttachProperty(scale_);
3827     } else {
3828         scale_->Set(scale);
3829     }
3830     FI_HILOGD("leave");
3831 }
3832 
Draw(Rosen::RSDrawingContext & context) const3833 void DrawStyleScaleModifier::Draw(Rosen::RSDrawingContext &context) const
3834 {
3835     FI_HILOGD("enter");
3836     if (!CheckNodesValid()) {
3837         FI_HILOGE("Check nodes valid failed");
3838         return;
3839     }
3840     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3841         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3842         return;
3843     }
3844     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3845     CHKPV(dragStyleNode);
3846     CHKPV(scale_);
3847     dragStyleNode->SetScale(scale_->Get());
3848     FI_HILOGD("leave");
3849 }
3850 
SetScale(float scale)3851 void DrawStyleScaleModifier::SetScale(float scale)
3852 {
3853     FI_HILOGD("enter");
3854     if (scale_ == nullptr) {
3855         scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3856         Rosen::RSModifier::AttachProperty(scale_);
3857     } else {
3858         scale_->Set(scale);
3859     }
3860     FI_HILOGD("leave");
3861 }
3862 
Draw(Rosen::RSDrawingContext & context) const3863 void DrawDragStopModifier::Draw(Rosen::RSDrawingContext &context) const
3864 {
3865     FI_HILOGD("enter");
3866     CHKPV(alpha_);
3867     CHKPV(scale_);
3868     if (!CheckNodesValid()) {
3869         FI_HILOGE("Check nodes valid failed");
3870         return;
3871     }
3872     CHKPV(g_drawingInfo.parentNode);
3873     g_drawingInfo.parentNode->SetAlpha(alpha_->Get());
3874     g_drawingInfo.parentNode->SetScale(scale_->Get(), scale_->Get());
3875     if (!g_drawingInfo.multiSelectedNodes.empty()) {
3876         size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
3877         for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
3878             std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
3879             CHKPV(multiSelectedNode);
3880             multiSelectedNode->SetAlpha(alpha_->Get());
3881             multiSelectedNode->SetScale(scale_->Get(), scale_->Get());
3882         }
3883     }
3884     if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3885         FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3886         return;
3887     }
3888     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3889     CHKPV(dragStyleNode);
3890     CHKPV(styleScale_);
3891     CHKPV(styleAlpha_);
3892     dragStyleNode->SetScale(styleScale_->Get());
3893     dragStyleNode->SetAlpha(styleAlpha_->Get());
3894     FI_HILOGD("leave");
3895 }
3896 
SetAlpha(float alpha)3897 void DrawDragStopModifier::SetAlpha(float alpha)
3898 {
3899     FI_HILOGD("enter");
3900     if (alpha_ == nullptr) {
3901         alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3902         Rosen::RSModifier::AttachProperty(alpha_);
3903     } else {
3904         alpha_->Set(alpha);
3905     }
3906     FI_HILOGD("leave");
3907 }
3908 
SetScale(float scale)3909 void DrawDragStopModifier::SetScale(float scale)
3910 {
3911     FI_HILOGD("enter");
3912     if (scale_ == nullptr) {
3913         scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3914         Rosen::RSModifier::AttachProperty(scale_);
3915     } else {
3916         scale_->Set(scale);
3917     }
3918     FI_HILOGD("leave");
3919 }
3920 
SetStyleScale(float scale)3921 void DrawDragStopModifier::SetStyleScale(float scale)
3922 {
3923     FI_HILOGD("enter");
3924     if (styleScale_ == nullptr) {
3925         styleScale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3926         Rosen::RSModifier::AttachProperty(styleScale_);
3927     } else {
3928         styleScale_->Set(scale);
3929     }
3930     FI_HILOGD("leave");
3931 }
3932 
SetStyleAlpha(float alpha)3933 void DrawDragStopModifier::SetStyleAlpha(float alpha)
3934 {
3935     FI_HILOGD("enter");
3936     if (styleAlpha_ == nullptr) {
3937         styleAlpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3938         Rosen::RSModifier::AttachProperty(styleAlpha_);
3939     } else {
3940         styleAlpha_->Set(alpha);
3941     }
3942     FI_HILOGD("leave");
3943 }
3944 
CalculateWidthScale()3945 float DragDrawing::CalculateWidthScale()
3946 {
3947 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
3948 #ifndef OHOS_BUILD_PC_PRODUCT
3949     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
3950 #else
3951     sptr<Rosen::DisplayInfo> display =
3952         Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(g_drawingInfo.displayId);
3953 #endif // OHOS_BUILD_PC_PRODUCT
3954     if (display == nullptr) {
3955         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
3956 #ifndef OHOS_BUILD_PC_PRODUCT
3957         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3958 #else
3959         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
3960 #endif // OHOS_BUILD_PC_PRODUCT
3961         if (display == nullptr) {
3962             FI_HILOGE("Get display info failed, display is nullptr");
3963             return DEFAULT_SCALING;
3964         }
3965     }
3966     auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
3967     if (defaultDisplay == nullptr) {
3968         FI_HILOGE("defaultDisplay is nullptr");
3969         return DEFAULT_SCALING;
3970     }
3971     int32_t width = display->GetWidth();
3972     int32_t height = display->GetHeight();
3973     float density = defaultDisplay->GetVirtualPixelRatio();
3974 #else
3975     if (window_ == nullptr) {
3976         FI_HILOGE("window_ is nullptr");
3977         return DEFAULT_SCALING;
3978     }
3979     int32_t width = window_->GetRect().width_;
3980     int32_t height = window_->GetRect().height_;
3981     float density = window_->GetDensity();
3982 #endif // OHOS_BUILD_ENABLE_ARKUI_X
3983     int32_t minSide = std::min(width, height);
3984     FI_HILOGD("density:%{public}f, minSide:%{public}d", density, minSide);
3985     if (minSide < MAX_SCREEN_WIDTH_SM * density) {
3986         currentScreenSize_ = ScreenSizeType::SM;
3987     } else if (minSide < MAX_SCREEN_WIDTH_MD * density) {
3988         currentScreenSize_ = ScreenSizeType::MD;
3989     } else if (minSide < MAX_SCREEN_WIDTH_LG * density) {
3990         currentScreenSize_ = ScreenSizeType::LG;
3991     } else {
3992         currentScreenSize_ = ScreenSizeType::XL;
3993     }
3994     float scale = GetMaxWidthScale(width, height);
3995     return scale;
3996 }
3997 
CalculateSMScale(int32_t pixelMapWidth,int32_t pixelMapHeight,int32_t shortSide)3998 float DragDrawing::CalculateSMScale(int32_t pixelMapWidth, int32_t pixelMapHeight, int32_t shortSide)
3999 {
4000     float scale = 1.0;
4001     if (g_dragDataForSuperHub.summarys.find("plain-text") != g_dragDataForSuperHub.summarys.end()) {
4002         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight, shortSide,
4003                                             shortSide / SCALE_TYPE_FIRST);
4004     } else {
4005         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight, shortSide / SCALE_TYPE_FIRST,
4006                                             shortSide / SCALE_TYPE_FIRST);
4007     }
4008     return scale;
4009 }
4010 
CalculateMDScale(int32_t pixelMapWidth,int32_t pixelMapHeight,int32_t shortSide)4011 float DragDrawing::CalculateMDScale(int32_t pixelMapWidth, int32_t pixelMapHeight, int32_t shortSide)
4012 {
4013     float scale = 1.0;
4014     if (g_dragDataForSuperHub.summarys.find("plain-text") != g_dragDataForSuperHub.summarys.end()) {
4015         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight, shortSide / SCALE_TYPE_FIRST,
4016                                             shortSide / SCALE_TYPE_THIRD);
4017     } else {
4018         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight, shortSide / SCALE_TYPE_THIRD,
4019                                             shortSide / SCALE_TYPE_THIRD);
4020     }
4021     return scale;
4022 }
4023 
CalculateDefaultScale(int32_t pixelMapWidth,int32_t pixelMapHeight,int32_t shortSide)4024 float DragDrawing::CalculateDefaultScale(int32_t pixelMapWidth, int32_t pixelMapHeight, int32_t shortSide)
4025 {
4026     float scale = 1.0;
4027     if (g_dragDataForSuperHub.summarys.find("plain-text") != g_dragDataForSuperHub.summarys.end()) {
4028         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight,
4029                                             shortSide * SCALE_TYPE_FIRST / SCALE_TYPE_SECOND,
4030                                             shortSide / SCALE_TYPE_SECOND);
4031     } else {
4032         scale = DragDrawing::CalculateScale(pixelMapWidth, pixelMapHeight, shortSide / SCALE_TYPE_SECOND,
4033                                             shortSide / SCALE_TYPE_SECOND);
4034     }
4035     return scale;
4036 }
4037 
GetMaxWidthScale(int32_t width,int32_t height)4038 float DragDrawing::GetMaxWidthScale(int32_t width, int32_t height)
4039 {
4040     FI_HILOGD("current device screen's width is %{public}d", width);
4041     float scale = 1.0;
4042     auto currentPixelMap = DragDrawing::AccessGlobalPixelMapLocked();
4043     if (currentPixelMap == nullptr) {
4044         FI_HILOGE("pixelMap is nullptr");
4045         return DEFAULT_SCALING;
4046     }
4047     int32_t pixelMapWidth = currentPixelMap->GetWidth();
4048     int32_t pixelMapHeight = currentPixelMap->GetHeight();
4049     if (pixelMapWidth == 0 || pixelMapHeight == 0) {
4050         FI_HILOGE("pixelMap width or height is 0");
4051         return DEFAULT_SCALING;
4052     }
4053     int32_t shortSide = fmin(width, height);
4054     FI_HILOGD("currentPixelMap width is %{public}d , height is %{public}d , shortSide is : %{public}d",
4055         width, height, shortSide);
4056     switch (currentScreenSize_) {
4057         case ScreenSizeType::SM: {
4058             scale = CalculateSMScale(pixelMapWidth, pixelMapHeight, shortSide);
4059             break;
4060         }
4061         case ScreenSizeType::MD: {
4062             scale = CalculateMDScale(pixelMapWidth, pixelMapHeight, shortSide);
4063             break;
4064         }
4065         default: {
4066             scale = CalculateDefaultScale(pixelMapWidth, pixelMapHeight, shortSide);
4067             break;
4068         }
4069     }
4070     FI_HILOGD("Screen Size Type is %{public}d and scale is %{public}f",
4071         static_cast<int32_t>(currentScreenSize_), scale);
4072     return scale;
4073 }
4074 
CalculateScale(float width,float height,float widthLimit,float heightLimit)4075 float DragDrawing::CalculateScale(float width, float height, float widthLimit, float heightLimit)
4076 {
4077     float scale = 1.0;
4078     if ((width > 0 && height > 0) && (width > widthLimit || height > heightLimit)) {
4079         scale = fmin(widthLimit / width, heightLimit / height);
4080     }
4081     return scale;
4082 }
4083 
4084 #ifdef OHOS_BUILD_ENABLE_ARKUI_X
SetDragWindow(std::shared_ptr<OHOS::Rosen::Window> window)4085 void DragDrawing::SetDragWindow(std::shared_ptr<OHOS::Rosen::Window> window)
4086 {
4087     CALL_INFO_TRACE;
4088     window_ = window;
4089 }
4090 
AddDragDestroy(std::function<void ()> cb)4091 void DragDrawing::AddDragDestroy(std::function<void()> cb)
4092 {
4093     CALL_INFO_TRACE;
4094     callback_ = cb;
4095 }
4096 
SetSVGFilePath(const std::string & filePath)4097 void DragDrawing::SetSVGFilePath(const std::string &filePath)
4098 {
4099     CALL_INFO_TRACE;
4100     svgFilePath_ = filePath;
4101 }
4102 #endif
4103 
LoadDragDropLib()4104 void DragDrawing::LoadDragDropLib()
4105 {
4106     FI_HILOGI("Begin to open drag drop extension library");
4107     if (dragExtHandler_ == nullptr) {
4108         dragExtHandler_ = dlopen(DRAG_DROP_EXTENSION_SO_PATH.c_str(), RTLD_LAZY);
4109     }
4110     CHKPL(dragExtHandler_);
4111     FI_HILOGI("End to open drag drop extension library");
4112 }
4113 
DetachToDisplay(int32_t displayId)4114 void DragDrawing::DetachToDisplay(int32_t displayId)
4115 {
4116 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
4117     CHKPV(g_drawingInfo.surfaceNode);
4118     g_drawingInfo.surfaceNode->DetachFromWindowContainer(screenId_);
4119     g_drawingInfo.displayId = displayId;
4120     StopVSyncStation();
4121     frameCallback_ = nullptr;
4122     Rosen::RSTransaction::FlushImplicitTransaction();
4123 #endif // OHOS_BUILD_ENABLE_ARKUI_X
4124 }
4125 
UpdateDragState(DragState dragState)4126 void DragDrawing::UpdateDragState(DragState dragState)
4127 {
4128     dragState_ = dragState;
4129 }
4130 
UpdateDragWindowDisplay(int32_t displayId)4131 void DragDrawing::UpdateDragWindowDisplay(int32_t displayId)
4132 {
4133 #ifndef OHOS_BUILD_ENABLE_ARKUI_X
4134     CHKPV(g_drawingInfo.rootNode);
4135     CHKPV(g_drawingInfo.surfaceNode);
4136 #ifndef OHOS_BUILD_PC_PRODUCT
4137     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
4138 #else
4139     sptr<Rosen::DisplayInfo> display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(displayId);
4140 #endif // OHOS_BUILD_PC_PRODUCT
4141     if (display == nullptr) {
4142         FI_HILOGD("Get display info failed, display:%{public}d", displayId);
4143 #ifndef OHOS_BUILD_PC_PRODUCT
4144         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
4145 #else
4146         display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
4147 #endif // OHOS_BUILD_PC_PRODUCT
4148         if (display == nullptr) {
4149             FI_HILOGE("Get display info failed, display is nullptr");
4150         }
4151         return;
4152     }
4153     screenId_ = static_cast<uint64_t>(displayId);
4154     int32_t surfaceNodeSize = std::max(display->GetWidth(), display->GetHeight());
4155     g_drawingInfo.rootNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
4156     g_drawingInfo.rootNode->SetFrame(0, 0, surfaceNodeSize, surfaceNodeSize);
4157     g_drawingInfo.surfaceNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
4158     g_drawingInfo.surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
4159     g_drawingInfo.surfaceNode->AttachToWindowContainer(screenId_);
4160     Rosen::RSTransaction::FlushImplicitTransaction();
4161 #endif // OHOS_BUILD_ENABLE_ARKUI_X
4162 }
4163 } // namespace DeviceStatus
4164 } // namespace Msdp
4165 } // namespace OHOS
4166