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