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