1 /*
2 * Copyright (c) 2023 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 <string>
22
23 #include <dlfcn.h>
24
25 #include "display_manager.h"
26 #include "include/core/SkTextBlob.h"
27 #include "image_source.h"
28 #include "image_type.h"
29 #include "image_utils.h"
30 #include "libxml/tree.h"
31 #include "libxml/parser.h"
32 #include "parameters.h"
33 #include "pointer_event.h"
34 #include "string_ex.h"
35 #include "transaction/rs_interfaces.h"
36 #include "ui/rs_surface_extractor.h"
37 #include "ui/rs_surface_node.h"
38 #include "ui/rs_ui_director.h"
39
40 #include "devicestatus_define.h"
41 #include "drag_data_manager.h"
42 #include "util.h"
43
44 namespace OHOS {
45 namespace Msdp {
46 namespace DeviceStatus {
47 namespace {
48 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DragDrawing" };
49 constexpr int32_t BASELINE_DENSITY { 160 };
50 constexpr int32_t DEVICE_INDEPENDENT_PIXEL { 40 };
51 constexpr int32_t DRAG_NUM_ONE { 1 };
52 constexpr int32_t STRING_PX_LENGTH { 2 };
53 constexpr int32_t EIGHT_SIZE { 8 };
54 constexpr int32_t TWELVE_SIZE { 12 };
55 constexpr int32_t IMAGE_WIDTH { 400 };
56 constexpr int32_t IMAGE_HEIGHT { 500 };
57 constexpr int64_t START_TIME { 181154000809 };
58 constexpr int64_t INTERVAL_TIME { 16666667 };
59 constexpr int32_t FRAMERATE { 30 };
60 constexpr int32_t SVG_WIDTH { 40 };
61 constexpr int32_t SVG_HEIGHT { 40 };
62 constexpr int32_t SIXTEEN { 16 };
63 constexpr int32_t SUCCESS_ANIMATION_DURATION { 300 };
64 constexpr int32_t VIEW_BOX_POS { 2 };
65 constexpr int32_t PIXEL_MAP_INDEX { 0 };
66 constexpr int32_t DRAG_STYLE_INDEX { 1 };
67 constexpr int32_t MOUSE_ICON_INDEX { 2 };
68 constexpr size_t TOUCH_NODE_MIN_COUNT { 2 };
69 constexpr size_t MOUSE_NODE_MIN_COUNT { 3 };
70 constexpr double ONETHOUSAND { 1000.0 };
71 constexpr float DEFAULT_SCALING { 1.0f };
72 constexpr float BEGIN_ALPHA { 1.0f };
73 constexpr float END_ALPHA { 0.0f };
74 constexpr float BEGIN_SCALE { 1.0f };
75 constexpr float END_SCALE_FAIL { 1.2f };
76 constexpr float END_SCALE_SUCCESS { 0.1f };
77 constexpr float PIVOT_X { 0.5f };
78 constexpr float PIVOT_Y { 0.5f };
79 constexpr float SVG_ORIGINAL_SIZE { 40.0f };;
80 const std::string DEVICE_TYPE_DEFAULT { "default" };
81 const std::string DEVICE_TYPE_PHONE { "phone" };
82 const std::string THREAD_NAME { "AnimationEventRunner" };
83 const std::string COPY_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
84 const std::string COPY_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_One_Drag.svg" };
85 const std::string DEFAULT_DRAG_PATH { "/system/etc/device_status/drag_icon/Default_Drag.svg" };
86 const std::string FORBID_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_Drag.svg" };
87 const std::string FORBID_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_One_Drag.svg" };
88 const std::string MOUSE_DRAG_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag.svg" };
89 const std::string MOVE_DRAG_PATH { "/system/etc/device_status/drag_icon/Move_Drag.svg" };
90 #ifdef __aarch64__
91 const std::string DRAG_ANIMATION_EXTENSION_SO_PATH { "/system/lib64/drag_drop_ext/libdrag_drop_ext.z.so" };
92 #else
93 const std::string DRAG_ANIMATION_EXTENSION_SO_PATH { "/system/lib/drag_drop_ext/libdrag_drop_ext.z.so" };
94 #endif
95 struct DrawingInfo g_drawingInfo;
96
CheckNodesValid()97 bool CheckNodesValid()
98 {
99 CALL_DEBUG_ENTER;
100 if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
101 (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT)) {
102 FI_HILOGE("Nodes size invalid when mouse type, node size:%{public}zu", g_drawingInfo.nodes.size());
103 return false;
104 }
105 if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
106 (g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
107 FI_HILOGE("Nodes size invalid when touchscreen type, node size:%{public}zu", g_drawingInfo.nodes.size());
108 return false;
109 }
110 return true;
111 }
112
GetScaling()113 float GetScaling()
114 {
115 CALL_DEBUG_ENTER;
116 sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
117 if (display == nullptr) {
118 FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
119 display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
120 if (display == nullptr) {
121 FI_HILOGE("Get display info failed, display is nullptr");
122 return DEFAULT_SCALING;
123 }
124 }
125
126 int32_t deviceDpi = display->GetDpi();
127 FI_HILOGD("displayId:%{public}d, deviceDpi:%{public}d", g_drawingInfo.displayId, deviceDpi);
128 if (deviceDpi < -std::numeric_limits<float>::epsilon()) {
129 FI_HILOGE("Invalid deviceDpi:%{public}d", deviceDpi);
130 return DEFAULT_SCALING;
131 }
132 return (1.0 * deviceDpi * DEVICE_INDEPENDENT_PIXEL / BASELINE_DENSITY) / SVG_ORIGINAL_SIZE;
133 }
134 } // namespace
135
Init(const DragData & dragData)136 int32_t DragDrawing::Init(const DragData &dragData)
137 {
138 CALL_DEBUG_ENTER;
139 if (g_drawingInfo.isRunning) {
140 FI_HILOGE("Drag drawing is running, can not init again");
141 return INIT_CANCEL;
142 }
143 CHKPR(dragData.shadowInfo.pixelMap, INIT_FAIL);
144 if ((dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
145 (dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN)) {
146 FI_HILOGE("Invalid sourceType:%{public}d", dragData.sourceType);
147 return INIT_FAIL;
148 }
149 if (dragData.dragNum < 0) {
150 FI_HILOGE("Invalid dragNum:%{public}d", dragData.dragNum);
151 return INIT_FAIL;
152 }
153 InitDrawingInfo(dragData);
154 CreateWindow(dragData.displayX, dragData.displayY);
155 CHKPR(g_drawingInfo.surfaceNode, INIT_FAIL);
156 if (InitLayer() != RET_OK) {
157 FI_HILOGE("Init layer failed");
158 return INIT_FAIL;
159 }
160 DragAnimationData dragAnimationData;
161 if (InitDragAnimationData(dragAnimationData) != RET_OK) {
162 FI_HILOGE("Init drag animation data failed");
163 return INIT_FAIL;
164 }
165 if (!CheckNodesValid()) {
166 FI_HILOGE("Check nodes valid failed");
167 return INIT_FAIL;
168 }
169 std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
170 CHKPR(shadowNode, INIT_FAIL);
171 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
172 CHKPR(dragStyleNode, INIT_FAIL);
173 dragExtHandle_ = dlopen(DRAG_ANIMATION_EXTENSION_SO_PATH.c_str(), RTLD_LAZY);
174 if (dragExtHandle_ == nullptr) {
175 FI_HILOGE("Failed to open drag extension library");
176 }
177 OnStartDrag(dragAnimationData, shadowNode, dragStyleNode);
178 CHKPR(rsUiDirector_, INIT_FAIL);
179 if (g_drawingInfo.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
180 rsUiDirector_->SendMessages();
181 return INIT_SUCCESS;
182 }
183 if (DrawMouseIcon() != RET_OK) {
184 FI_HILOGE("Draw mouse icon failed");
185 return INIT_FAIL;
186 }
187 rsUiDirector_->SendMessages();
188 return INIT_SUCCESS;
189 }
190
Draw(int32_t displayId,int32_t displayX,int32_t displayY)191 void DragDrawing::Draw(int32_t displayId, int32_t displayX, int32_t displayY)
192 {
193 CALL_DEBUG_ENTER;
194 if (displayId < 0) {
195 FI_HILOGE("Invalid displayId:%{public}d", displayId);
196 return;
197 }
198 g_drawingInfo.displayId = displayId;
199 g_drawingInfo.displayX = displayX;
200 g_drawingInfo.displayY = displayY;
201 if (displayX < 0) {
202 g_drawingInfo.displayX = 0;
203 }
204 if (displayY < 0) {
205 g_drawingInfo.displayY = 0;
206 }
207 int32_t adjustSize = TWELVE_SIZE * GetScaling();
208 int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
209 int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
210 if (g_drawingInfo.surfaceNode != nullptr) {
211 g_drawingInfo.surfaceNode->SetBounds(positionX, positionY,
212 g_drawingInfo.surfaceNode->GetStagingProperties().GetBounds().z_,
213 g_drawingInfo.surfaceNode->GetStagingProperties().GetBounds().w_);
214 Rosen::RSTransaction::FlushImplicitTransaction();
215 return;
216 }
217 CreateWindow(positionX, positionY);
218 CHKPV(g_drawingInfo.surfaceNode);
219 }
220
UpdateDragStyle(DragCursorStyle style)221 int32_t DragDrawing::UpdateDragStyle(DragCursorStyle style)
222 {
223 CALL_DEBUG_ENTER;
224 if ((style < DragCursorStyle::DEFAULT) || (style > DragCursorStyle::MOVE)) {
225 FI_HILOGE("Invalid style:%{public}d", style);
226 return RET_ERR;
227 }
228 if (g_drawingInfo.currentStyle == style) {
229 FI_HILOGD("Not need update drag style");
230 return RET_OK;
231 }
232 g_drawingInfo.currentStyle = style;
233 std::string filePath;
234 if (GetFilePath(filePath) != RET_OK) {
235 FI_HILOGD("Get file path failed");
236 return RET_ERR;
237 }
238 if (!IsValidSvgFile(filePath)) {
239 FI_HILOGE("Svg file is invalid");
240 return RET_ERR;
241 }
242 std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
243 CHKPR(pixelMap, RET_ERR);
244 bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
245 g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
246 g_drawingInfo.isCurrentDefaultStyle = (filePath == DEFAULT_DRAG_PATH);
247 g_drawingInfo.stylePixelMap = pixelMap;
248 if (!CheckNodesValid()) {
249 FI_HILOGE("Check nodes valid failed");
250 return RET_ERR;
251 }
252 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
253 CHKPR(dragStyleNode, RET_ERR);
254 OnDragStyle(dragStyleNode, pixelMap);
255 CHKPR(rsUiDirector_, RET_ERR);
256 rsUiDirector_->SendMessages();
257 return RET_OK;
258 }
259
UpdateShadowPic(const ShadowInfo & shadowInfo)260 int32_t DragDrawing::UpdateShadowPic(const ShadowInfo &shadowInfo)
261 {
262 CALL_DEBUG_ENTER;
263 CHKPR(shadowInfo.pixelMap, RET_ERR);
264 Draw(g_drawingInfo.displayId, g_drawingInfo.displayX + shadowInfo.x - g_drawingInfo.pixelMapX,
265 g_drawingInfo.displayY + shadowInfo.y - g_drawingInfo.pixelMapY);
266 g_drawingInfo.pixelMap = shadowInfo.pixelMap;
267 if (!CheckNodesValid()) {
268 FI_HILOGE("Check nodes valid failed");
269 return RET_ERR;
270 }
271 std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
272 CHKPR(shadowNode, RET_ERR);
273 DrawShadow(shadowNode);
274 float scalingValue = GetScaling();
275 if ((1.0 * INT32_MAX / (SVG_WIDTH + TWELVE_SIZE)) <= scalingValue) {
276 FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
277 return RET_ERR;
278 }
279 int32_t adjustSize = (SVG_WIDTH + TWELVE_SIZE) * scalingValue;
280 g_drawingInfo.rootNodeWidth = g_drawingInfo.pixelMap->GetWidth() + adjustSize;
281 g_drawingInfo.rootNodeHeight = g_drawingInfo.pixelMap->GetHeight() + adjustSize;
282 CHKPR(g_drawingInfo.rootNode, RET_ERR);
283 g_drawingInfo.rootNode->SetBounds(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
284 g_drawingInfo.rootNode->SetFrame(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
285 CHKPR(g_drawingInfo.surfaceNode, RET_ERR);
286 g_drawingInfo.surfaceNode->SetBoundsWidth(g_drawingInfo.rootNodeWidth);
287 g_drawingInfo.surfaceNode->SetBoundsHeight(g_drawingInfo.rootNodeHeight);
288 if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
289 g_drawingInfo.pixelMapX = shadowInfo.x;
290 g_drawingInfo.pixelMapY = shadowInfo.y;
291 DrawMouseIcon();
292 }
293 Rosen::RSTransaction::FlushImplicitTransaction();
294 CHKPR(rsUiDirector_, RET_ERR);
295 rsUiDirector_->SendMessages();
296 return RET_OK;
297 }
298
OnDragSuccess()299 void DragDrawing::OnDragSuccess()
300 {
301 CALL_DEBUG_ENTER;
302 if (!CheckNodesValid()) {
303 FI_HILOGE("Check nodes valid failed");
304 return;
305 }
306 std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
307 CHKPV(shadowNode);
308 std::shared_ptr<Rosen::RSCanvasNode> styleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
309 CHKPV(styleNode);
310 OnStopDragSuccess(shadowNode, styleNode);
311 }
312
OnDragFail()313 void DragDrawing::OnDragFail()
314 {
315 CALL_DEBUG_ENTER;
316 std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode = g_drawingInfo.surfaceNode;
317 CHKPV(surfaceNode);
318 std::shared_ptr<Rosen::RSNode> rootNode = g_drawingInfo.rootNode;
319 CHKPV(rootNode);
320 OnStopDragFail(surfaceNode, rootNode);
321 }
322
EraseMouseIcon()323 void DragDrawing::EraseMouseIcon()
324 {
325 CALL_DEBUG_ENTER;
326 if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
327 FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
328 return;
329 }
330 std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
331 CHKPV(mouseIconNode);
332 if (drawMouseIconModifier_ != nullptr) {
333 mouseIconNode->RemoveModifier(drawMouseIconModifier_);
334 drawMouseIconModifier_ = nullptr;
335 }
336 CHKPV(g_drawingInfo.rootNode);
337 g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
338 CHKPV(rsUiDirector_);
339 rsUiDirector_->SendMessages();
340 }
341
DestroyDragWindow()342 void DragDrawing::DestroyDragWindow()
343 {
344 CALL_DEBUG_ENTER;
345 startNum_ = START_TIME;
346 g_drawingInfo.sourceType = -1;
347 g_drawingInfo.currentDragNum = -1;
348 g_drawingInfo.pixelMapX = -1;
349 g_drawingInfo.pixelMapY = -1;
350 g_drawingInfo.displayX = -1;
351 g_drawingInfo.displayY = -1;
352 g_drawingInfo.rootNodeWidth = -1;
353 g_drawingInfo.rootNodeHeight = -1;
354 g_drawingInfo.pixelMap = nullptr;
355 g_drawingInfo.stylePixelMap = nullptr;
356 g_drawingInfo.isPreviousDefaultStyle = false;
357 g_drawingInfo.isCurrentDefaultStyle = false;
358 g_drawingInfo.currentStyle = DragCursorStyle::DEFAULT;
359 RemoveModifier();
360 if (!g_drawingInfo.nodes.empty()) {
361 g_drawingInfo.nodes.clear();
362 g_drawingInfo.nodes.shrink_to_fit();
363 }
364 if (g_drawingInfo.rootNode != nullptr) {
365 g_drawingInfo.rootNode->ClearChildren();
366 g_drawingInfo.rootNode.reset();
367 g_drawingInfo.rootNode = nullptr;
368 }
369 if (g_drawingInfo.surfaceNode != nullptr) {
370 g_drawingInfo.surfaceNode->DetachToDisplay(g_drawingInfo.displayId);
371 g_drawingInfo.surfaceNode = nullptr;
372 g_drawingInfo.displayId = -1;
373 Rosen::RSTransaction::FlushImplicitTransaction();
374 }
375 CHKPV(rsUiDirector_);
376 rsUiDirector_->SetRoot(-1);
377 rsUiDirector_->SendMessages();
378 }
379
UpdateDrawingState()380 void DragDrawing::UpdateDrawingState()
381 {
382 CALL_DEBUG_ENTER;
383 g_drawingInfo.isRunning = false;
384 }
385
UpdateDragWindowState(bool visible)386 void DragDrawing::UpdateDragWindowState(bool visible)
387 {
388 CALL_DEBUG_ENTER;
389 CHKPV(g_drawingInfo.surfaceNode);
390 if (visible) {
391 g_drawingInfo.surfaceNode->SetVisible(true);
392 FI_HILOGD("Drag surfaceNode show success");
393 } else {
394 g_drawingInfo.surfaceNode->SetVisible(false);
395 FI_HILOGD("Drag surfaceNode hide success");
396 }
397 Rosen::RSTransaction::FlushImplicitTransaction();
398 }
399
OnStartDrag(const DragAnimationData & dragAnimationData,std::shared_ptr<Rosen::RSCanvasNode> shadowNode,std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)400 void DragDrawing::OnStartDrag(const DragAnimationData &dragAnimationData,
401 std::shared_ptr<Rosen::RSCanvasNode> shadowNode, std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
402 {
403 CALL_DEBUG_ENTER;
404 CHKPV(shadowNode);
405 CHKPV(dragStyleNode);
406 if (DrawShadow(shadowNode) != RET_OK) {
407 FI_HILOGE("Draw shadow failed");
408 return;
409 }
410 if (InitDrawStyle(dragStyleNode) != RET_OK) {
411 FI_HILOGE("Init draw style failed");
412 return;
413 }
414 if (dragExtHandle_ == nullptr) {
415 FI_HILOGE("Failed to open drag extension library");
416 return;
417 }
418 auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStartDragExt"));
419 if (animationExtFunc == nullptr) {
420 FI_HILOGE("Failed to get drag extension func");
421 dlclose(dragExtHandle_);
422 dragExtHandle_ = nullptr;
423 return;
424 }
425 if (handler_ == nullptr) {
426 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
427 CHKPV(runner);
428 handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
429 }
430 if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
431 FI_HILOGE("Send animationExtFunc failed");
432 }
433 }
434
OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)435 void DragDrawing::OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
436 std::shared_ptr<Media::PixelMap> stylePixelMap)
437 {
438 CALL_DEBUG_ENTER;
439 CHKPV(dragStyleNode);
440 CHKPV(stylePixelMap);
441 if (dragExtHandle_ == nullptr) {
442 FI_HILOGE("Failed to open drag extension library");
443 DrawStyle(dragStyleNode, stylePixelMap);
444 return;
445 }
446 auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnDragStyleExt"));
447 if (animationExtFunc == nullptr) {
448 FI_HILOGE("Failed to get drag extension func");
449 DrawStyle(dragStyleNode, stylePixelMap);
450 dlclose(dragExtHandle_);
451 dragExtHandle_ = nullptr;
452 return;
453 }
454 if (handler_ == nullptr) {
455 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
456 CHKPV(runner);
457 handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
458 }
459 if (drawSVGModifier_ != nullptr) {
460 dragStyleNode->RemoveModifier(drawSVGModifier_);
461 drawSVGModifier_ = nullptr;
462 }
463 if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
464 FI_HILOGE("Send animationExtFunc failed");
465 DrawStyle(dragStyleNode, stylePixelMap);
466 }
467 }
468
OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)469 void DragDrawing::OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,
470 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
471 {
472 CALL_DEBUG_ENTER;
473 if (dragExtHandle_ == nullptr) {
474 FI_HILOGE("Failed to open drag extension library");
475 RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
476 return;
477 }
478 auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStopDragSuccessExt"));
479 if (animationExtFunc == nullptr) {
480 FI_HILOGE("Failed to get drag extension func");
481 RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
482 dlclose(dragExtHandle_);
483 dragExtHandle_ = nullptr;
484 return;
485 }
486 if (handler_ == nullptr) {
487 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
488 CHKPV(runner);
489 handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
490 }
491 if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
492 FI_HILOGE("Send animationExtFunc failed");
493 RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
494 } else {
495 StartVsync();
496 }
497 }
498
OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,std::shared_ptr<Rosen::RSNode> rootNode)499 void DragDrawing::OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,
500 std::shared_ptr<Rosen::RSNode> rootNode)
501 {
502 CALL_DEBUG_ENTER;
503 if (dragExtHandle_ == nullptr) {
504 FI_HILOGE("Failed to open drag extension library");
505 RunAnimation(END_ALPHA, END_SCALE_FAIL);
506 return;
507 }
508 auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStopDragFailExt"));
509 if (animationExtFunc == nullptr) {
510 FI_HILOGE("Failed to get drag extension func");
511 RunAnimation(END_ALPHA, END_SCALE_FAIL);
512 dlclose(dragExtHandle_);
513 dragExtHandle_ = nullptr;
514 return;
515 }
516 if (handler_ == nullptr) {
517 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
518 CHKPV(runner);
519 handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
520 }
521 if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
522 FI_HILOGE("Send animationExtFunc failed");
523 RunAnimation(END_ALPHA, END_SCALE_FAIL);
524 } else {
525 StartVsync();
526 }
527 }
528
OnStopAnimation()529 void DragDrawing::OnStopAnimation()
530 {
531 CALL_DEBUG_ENTER;
532 }
533
RunAnimation(float endAlpha,float endScale)534 void DragDrawing::RunAnimation(float endAlpha, float endScale)
535 {
536 CALL_DEBUG_ENTER;
537 if (handler_ == nullptr) {
538 auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
539 CHKPV(runner);
540 handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
541 }
542 if (!handler_->PostTask(std::bind(&DragDrawing::InitVSync, this, endAlpha, endScale))) {
543 FI_HILOGE("Send vsync event failed");
544 }
545 }
546
InitDrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)547 int32_t DragDrawing::InitDrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
548 {
549 CALL_DEBUG_ENTER;
550 CHKPR(dragStyleNode, RET_ERR);
551 std::string filePath;
552 if (GetFilePath(filePath) != RET_OK) {
553 FI_HILOGD("Get file path failed");
554 return RET_ERR;
555 }
556 if (!IsValidSvgFile(filePath)) {
557 FI_HILOGE("Svg file is invalid");
558 return RET_ERR;
559 }
560 g_drawingInfo.isCurrentDefaultStyle = (filePath == DEFAULT_DRAG_PATH);
561 std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
562 CHKPR(pixelMap, RET_ERR);
563 int32_t ret = DrawStyle(dragStyleNode, pixelMap);
564 if (ret != RET_OK) {
565 FI_HILOGE("Drag style failed");
566 }
567 return ret;
568 }
569
DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)570 int32_t DragDrawing::DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)
571 {
572 CALL_DEBUG_ENTER;
573 CHKPR(shadowNode, RET_ERR);
574 if (drawPixelMapModifier_ != nullptr) {
575 shadowNode->RemoveModifier(drawPixelMapModifier_);
576 drawPixelMapModifier_ = nullptr;
577 }
578 drawPixelMapModifier_ = std::make_shared<DrawPixelMapModifier>();
579 shadowNode->AddModifier(drawPixelMapModifier_);
580 return RET_OK;
581 }
582
DrawMouseIcon()583 int32_t DragDrawing::DrawMouseIcon()
584 {
585 CALL_DEBUG_ENTER;
586 if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
587 FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
588 return RET_ERR;
589 }
590 std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
591 CHKPR(mouseIconNode, RET_ERR);
592 if (drawMouseIconModifier_ != nullptr) {
593 mouseIconNode->RemoveModifier(drawMouseIconModifier_);
594 drawMouseIconModifier_ = nullptr;
595 }
596 drawMouseIconModifier_ = std::make_shared<DrawMouseIconModifier>();
597 mouseIconNode->AddModifier(drawMouseIconModifier_);
598 return RET_OK;
599 }
600
DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)601 int32_t DragDrawing::DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
602 std::shared_ptr<Media::PixelMap> stylePixelMap)
603 {
604 CALL_DEBUG_ENTER;
605 CHKPR(dragStyleNode, RET_ERR);
606 CHKPR(stylePixelMap, RET_ERR);
607 if (drawSVGModifier_ != nullptr) {
608 dragStyleNode->RemoveModifier(drawSVGModifier_);
609 drawSVGModifier_ = nullptr;
610 }
611 drawSVGModifier_ = std::make_shared<DrawSVGModifier>(stylePixelMap);
612 dragStyleNode->AddModifier(drawSVGModifier_);
613 return RET_OK;
614 }
615
InitVSync(float endAlpha,float endScale)616 int32_t DragDrawing::InitVSync(float endAlpha, float endScale)
617 {
618 CALL_DEBUG_ENTER;
619 startNum_ = START_TIME;
620 CHKPR(g_drawingInfo.rootNode, RET_ERR);
621 if (drawDynamicEffectModifier_ != nullptr) {
622 g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
623 drawDynamicEffectModifier_ = nullptr;
624 }
625 drawDynamicEffectModifier_ = std::make_shared<DrawDynamicEffectModifier>();
626 g_drawingInfo.rootNode->AddModifier(drawDynamicEffectModifier_);
627 drawDynamicEffectModifier_->SetAlpha(BEGIN_ALPHA);
628 drawDynamicEffectModifier_->SetScale(BEGIN_SCALE);
629
630 Rosen::RSAnimationTimingProtocol protocol;
631 protocol.SetDuration(SUCCESS_ANIMATION_DURATION);
632 Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
633 drawDynamicEffectModifier_->SetAlpha(endAlpha);
634 drawDynamicEffectModifier_->SetScale(endScale);
635 });
636 return StartVsync();
637 }
638
StartVsync()639 int32_t DragDrawing::StartVsync()
640 {
641 CHKPR(g_drawingInfo.surfaceNode, RET_ERR);
642 g_drawingInfo.surfaceNode->SetPivot(PIVOT_X, PIVOT_Y);
643 Rosen::RSTransaction::FlushImplicitTransaction();
644 if (receiver_ == nullptr) {
645 CHKPR(handler_, RET_ERR);
646 receiver_ = Rosen::RSInterfaces::GetInstance().CreateVSyncReceiver("DragDrawing", handler_);
647 CHKPR(receiver_, RET_ERR);
648 }
649 int32_t ret = receiver_->Init();
650 if (ret != RET_OK) {
651 FI_HILOGE("Receiver init failed");
652 return RET_ERR;
653 }
654 Rosen::VSyncReceiver::FrameCallback fcb = {
655 .userData_ = this,
656 .callback_ = std::bind(&DragDrawing::OnVsync, this)
657 };
658 int32_t changeFreq = static_cast<int32_t>((ONETHOUSAND / FRAMERATE) / SIXTEEN);
659 ret = receiver_->SetVSyncRate(fcb, changeFreq);
660 if (ret != RET_OK) {
661 FI_HILOGE("Set vsync rate failed");
662 }
663 return ret;
664 }
665
OnVsync()666 void DragDrawing::OnVsync()
667 {
668 CALL_DEBUG_ENTER;
669 CHKPV(rsUiDirector_);
670 bool hasRunningAnimation = rsUiDirector_->RunningCustomAnimation(startNum_);
671 if (!hasRunningAnimation) {
672 FI_HILOGD("Stop runner, hasRunningAnimation:%{public}d", hasRunningAnimation);
673 CHKPV(handler_);
674 handler_->RemoveAllEvents();
675 handler_->RemoveAllFileDescriptorListeners();
676 handler_ = nullptr;
677 g_drawingInfo.isRunning = false;
678 receiver_ = nullptr;
679 CHKPV(g_drawingInfo.rootNode);
680 if (drawDynamicEffectModifier_ != nullptr) {
681 g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
682 drawDynamicEffectModifier_ = nullptr;
683 }
684 DestroyDragWindow();
685 return;
686 }
687 rsUiDirector_->SendMessages();
688 startNum_ += INTERVAL_TIME;
689 }
690
InitDrawingInfo(const DragData & dragData)691 void DragDrawing::InitDrawingInfo(const DragData &dragData)
692 {
693 CALL_DEBUG_ENTER;
694 g_drawingInfo.isRunning = true;
695 g_drawingInfo.currentDragNum = dragData.dragNum;
696 g_drawingInfo.sourceType = dragData.sourceType;
697 g_drawingInfo.displayId = dragData.displayId;
698 g_drawingInfo.displayX = dragData.displayX;
699 g_drawingInfo.displayY = dragData.displayY;
700 g_drawingInfo.pixelMap = dragData.shadowInfo.pixelMap;
701 g_drawingInfo.pixelMapX = dragData.shadowInfo.x;
702 g_drawingInfo.pixelMapY = dragData.shadowInfo.y;
703 }
704
InitDragAnimationData(DragAnimationData & dragAnimationData)705 int32_t DragDrawing::InitDragAnimationData(DragAnimationData &dragAnimationData)
706 {
707 CALL_DEBUG_ENTER;
708 CHKPR(g_drawingInfo.pixelMap, RET_ERR);
709 dragAnimationData.pixelMap = g_drawingInfo.pixelMap;
710 dragAnimationData.displayX = g_drawingInfo.displayX;
711 dragAnimationData.displayY = g_drawingInfo.displayY;
712 dragAnimationData.offsetX = g_drawingInfo.pixelMapX;
713 dragAnimationData.offsetY = g_drawingInfo.pixelMapY;
714 return RET_OK;
715 }
716
InitLayer()717 int32_t DragDrawing::InitLayer()
718 {
719 CALL_DEBUG_ENTER;
720 if (g_drawingInfo.surfaceNode == nullptr) {
721 FI_HILOGE("Init layer failed, surfaceNode is nullptr");
722 return RET_ERR;
723 }
724 auto surface = g_drawingInfo.surfaceNode->GetSurface();
725 if (surface == nullptr) {
726 g_drawingInfo.surfaceNode->DetachToDisplay(g_drawingInfo.displayId);
727 g_drawingInfo.surfaceNode = nullptr;
728 FI_HILOGE("Init layer failed, surface is nullptr");
729 Rosen::RSTransaction::FlushImplicitTransaction();
730 return RET_ERR;
731 }
732 if (g_drawingInfo.isInitUiDirector) {
733 g_drawingInfo.isInitUiDirector = false;
734 rsUiDirector_ = Rosen::RSUIDirector::Create();
735 CHKPR(rsUiDirector_, RET_ERR);
736 rsUiDirector_->Init();
737 }
738 rsUiDirector_->SetRSSurfaceNode(g_drawingInfo.surfaceNode);
739 InitCanvas(IMAGE_WIDTH, IMAGE_HEIGHT);
740 Rosen::RSTransaction::FlushImplicitTransaction();
741 return RET_OK;
742 }
743
InitCanvas(int32_t width,int32_t height)744 void DragDrawing::InitCanvas(int32_t width, int32_t height)
745 {
746 CALL_DEBUG_ENTER;
747 if (g_drawingInfo.rootNode == nullptr) {
748 g_drawingInfo.rootNode = Rosen::RSRootNode::Create();
749 CHKPV(g_drawingInfo.rootNode);
750 }
751 int32_t adjustSize = TWELVE_SIZE * GetScaling();
752 g_drawingInfo.rootNode->SetBounds(g_drawingInfo.displayX, g_drawingInfo.displayY - adjustSize, width, height);
753 g_drawingInfo.rootNode->SetFrame(g_drawingInfo.displayX, g_drawingInfo.displayY - adjustSize, width, height);
754 g_drawingInfo.rootNode->SetBackgroundColor(SK_ColorTRANSPARENT);
755
756 std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = Rosen::RSCanvasNode::Create();
757 CHKPV(pixelMapNode);
758 CHKPV(g_drawingInfo.pixelMap);
759 pixelMapNode->SetBounds(0, adjustSize, g_drawingInfo.pixelMap->GetWidth(), g_drawingInfo.pixelMap->GetHeight());
760 pixelMapNode->SetFrame(0, adjustSize, g_drawingInfo.pixelMap->GetWidth(), g_drawingInfo.pixelMap->GetHeight());
761 g_drawingInfo.nodes.emplace_back(pixelMapNode);
762 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = Rosen::RSCanvasNode::Create();
763 CHKPV(dragStyleNode);
764 dragStyleNode->SetBounds(0, 0, SVG_HEIGHT, SVG_HEIGHT);
765 dragStyleNode->SetFrame(0, 0, SVG_HEIGHT, SVG_HEIGHT);
766 g_drawingInfo.nodes.emplace_back(dragStyleNode);
767
768 CHKPV(rsUiDirector_);
769 if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
770 std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = Rosen::RSCanvasNode::Create();
771 CHKPV(mouseIconNode);
772 mouseIconNode->SetBounds(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY,
773 SVG_HEIGHT, SVG_HEIGHT);
774 mouseIconNode->SetFrame(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY,
775 SVG_HEIGHT, SVG_HEIGHT);
776 g_drawingInfo.nodes.emplace_back(mouseIconNode);
777 g_drawingInfo.rootNode->AddChild(pixelMapNode);
778 g_drawingInfo.rootNode->AddChild(dragStyleNode);
779 g_drawingInfo.rootNode->AddChild(mouseIconNode);
780 rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
781 return;
782 }
783 g_drawingInfo.rootNode->AddChild(pixelMapNode);
784 g_drawingInfo.rootNode->AddChild(dragStyleNode);
785 rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
786 }
787
CreateWindow(int32_t displayX,int32_t displayY)788 void DragDrawing::CreateWindow(int32_t displayX, int32_t displayY)
789 {
790 CALL_DEBUG_ENTER;
791 Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
792 surfaceNodeConfig.SurfaceNodeName = "drag window";
793 Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
794 g_drawingInfo.surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
795 CHKPV(g_drawingInfo.surfaceNode);
796 g_drawingInfo.surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
797 g_drawingInfo.surfaceNode->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
798 g_drawingInfo.surfaceNode->SetBounds(displayX, displayY, IMAGE_WIDTH, IMAGE_HEIGHT);
799 g_drawingInfo.surfaceNode->SetBackgroundColor(SK_ColorTRANSPARENT);
800 g_drawingInfo.surfaceNode->AttachToDisplay(g_drawingInfo.displayId);
801 g_drawingInfo.surfaceNode->SetVisible(false);
802 Rosen::RSTransaction::FlushImplicitTransaction();
803 }
804
RemoveModifier()805 void DragDrawing::RemoveModifier()
806 {
807 CALL_DEBUG_ENTER;
808 if ((g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
809 FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
810 return;
811 }
812
813 std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
814 CHKPV(pixelMapNode);
815 if (drawPixelMapModifier_ != nullptr) {
816 pixelMapNode->RemoveModifier(drawPixelMapModifier_);
817 drawPixelMapModifier_ = nullptr;
818 }
819 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
820 CHKPV(dragStyleNode);
821 if (drawSVGModifier_ != nullptr) {
822 dragStyleNode->RemoveModifier(drawSVGModifier_);
823 drawSVGModifier_ = nullptr;
824 }
825 }
826
UpdateSvgNodeInfo(xmlNodePtr curNode,int32_t extendSvgWidth)827 int32_t DragDrawing::UpdateSvgNodeInfo(xmlNodePtr curNode, int32_t extendSvgWidth)
828 {
829 CALL_DEBUG_ENTER;
830 if (xmlStrcmp(curNode->name, BAD_CAST "svg")) {
831 FI_HILOGE("Svg format invalid");
832 return RET_ERR;
833 }
834 std::ostringstream oStrStream;
835 oStrStream << xmlGetProp(curNode, BAD_CAST "width");
836 std::string srcSvgWidth = oStrStream.str();
837 if (srcSvgWidth.length() < STRING_PX_LENGTH) {
838 FI_HILOGE("Svg width invalid, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
839 return RET_ERR;
840 }
841 srcSvgWidth = srcSvgWidth.substr(0, srcSvgWidth.length() - STRING_PX_LENGTH);
842 if (!IsNum(srcSvgWidth)) {
843 FI_HILOGE("srcSvgWidth is not digital, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
844 return RET_ERR;
845 }
846 int32_t number = std::stoi(srcSvgWidth) + extendSvgWidth;
847 std::string tgtSvgWidth = std::to_string(number);
848 tgtSvgWidth.append("px");
849 xmlSetProp(curNode, BAD_CAST "width", BAD_CAST tgtSvgWidth.c_str());
850 oStrStream.str("");
851 oStrStream << xmlGetProp(curNode, BAD_CAST "viewBox");
852 std::string srcViewBox = oStrStream.str();
853 std::istringstream iStrStream(srcViewBox);
854 std::string tmpString;
855 std::string tgtViewBox;
856 int32_t i = 0;
857 while (iStrStream >> tmpString) {
858 if (i == VIEW_BOX_POS) {
859 if (!IsNum(tmpString)) {
860 FI_HILOGE("tmpString is not digital, tmpString:%{public}s", tmpString.c_str());
861 return RET_ERR;
862 }
863 number = std::stoi(tmpString) + extendSvgWidth;
864 tmpString = std::to_string(number);
865 }
866 tgtViewBox.append(tmpString);
867 tgtViewBox += " ";
868 ++i;
869 }
870
871 xmlSetProp(curNode, BAD_CAST "viewBox", BAD_CAST tgtViewBox.c_str());
872 return RET_OK;
873 }
874
GetRectNode(xmlNodePtr curNode)875 xmlNodePtr DragDrawing::GetRectNode(xmlNodePtr curNode)
876 {
877 CALL_DEBUG_ENTER;
878 curNode = curNode->xmlChildrenNode;
879 while (curNode != nullptr) {
880 if (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
881 while (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
882 curNode = curNode->xmlChildrenNode;
883 }
884 break;
885 }
886 curNode = curNode->next;
887 }
888 return curNode;
889 }
890
UpdateRectNode(int32_t extendSvgWidth,xmlNodePtr curNode)891 xmlNodePtr DragDrawing::UpdateRectNode(int32_t extendSvgWidth, xmlNodePtr curNode)
892 {
893 CALL_DEBUG_ENTER;
894 while (curNode != nullptr) {
895 if (!xmlStrcmp(curNode->name, BAD_CAST "rect")) {
896 std::ostringstream oStrStream;
897 oStrStream << xmlGetProp(curNode, BAD_CAST "width");
898 std::string srcRectWidth = oStrStream.str();
899 if (!IsNum(srcRectWidth)) {
900 FI_HILOGE("srcRectWidth is not digital, srcRectWidth:%{public}s", srcRectWidth.c_str());
901 return nullptr;
902 }
903 int32_t number = std::stoi(srcRectWidth) + extendSvgWidth;
904 xmlSetProp(curNode, BAD_CAST "width", BAD_CAST std::to_string(number).c_str());
905 }
906 if (!xmlStrcmp(curNode->name, BAD_CAST "text")) {
907 return curNode->xmlChildrenNode;
908 }
909 curNode = curNode->next;
910 }
911 FI_HILOGE("Empty node of XML");
912 return nullptr;
913 }
914
UpdateTspanNode(xmlNodePtr curNode)915 void DragDrawing::UpdateTspanNode(xmlNodePtr curNode)
916 {
917 CALL_DEBUG_ENTER;
918 while (curNode != nullptr) {
919 if (!xmlStrcmp(curNode->name, BAD_CAST "tspan")) {
920 xmlNodeSetContent(curNode, BAD_CAST std::to_string(g_drawingInfo.currentDragNum).c_str());
921 }
922 curNode = curNode->next;
923 }
924 }
925
ParseAndAdjustSvgInfo(xmlNodePtr curNode)926 int32_t DragDrawing::ParseAndAdjustSvgInfo(xmlNodePtr curNode)
927 {
928 CALL_DEBUG_ENTER;
929 CHKPR(curNode, RET_ERR);
930 std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
931 if (strStyle.empty()) {
932 FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
933 return RET_ERR;
934 }
935 int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
936 xmlKeepBlanksDefault(0);
937 int32_t ret = UpdateSvgNodeInfo(curNode, extendSvgWidth);
938 if (ret != RET_OK) {
939 FI_HILOGE("Update svg node info failed, ret:%{public}d", ret);
940 return RET_ERR;
941 }
942 curNode = GetRectNode(curNode);
943 CHKPR(curNode, RET_ERR);
944 curNode = UpdateRectNode(extendSvgWidth, curNode);
945 CHKPR(curNode, RET_ERR);
946 UpdateTspanNode(curNode);
947 return RET_OK;
948 }
949
DecodeSvgToPixelMap(const std::string & filePath)950 std::shared_ptr<Media::PixelMap> DragDrawing::DecodeSvgToPixelMap(
951 const std::string &filePath)
952 {
953 CALL_DEBUG_ENTER;
954 xmlDocPtr xmlDoc = xmlReadFile(filePath.c_str(), 0, XML_PARSE_NOBLANKS);
955 if (NeedAdjustSvgInfo()) {
956 xmlNodePtr node = xmlDocGetRootElement(xmlDoc);
957 CHKPP(node);
958 int32_t ret = ParseAndAdjustSvgInfo(node);
959 if (ret != RET_OK) {
960 FI_HILOGE("Parse and adjust svg info failed, ret:%{public}d", ret);
961 return nullptr;
962 }
963 }
964 xmlChar *xmlbuff = nullptr;
965 int32_t buffersize = 0;
966 xmlDocDumpFormatMemory(xmlDoc, &xmlbuff, &buffersize, 1);
967 std::ostringstream oStrStream;
968 oStrStream << xmlbuff;
969 std::string content = oStrStream.str();
970 xmlFree(xmlbuff);
971 xmlFreeDoc(xmlDoc);
972 Media::SourceOptions opts;
973 opts.formatHint = "image/svg+xml";
974 uint32_t errCode = 0;
975 auto imageSource = Media::ImageSource::CreateImageSource(reinterpret_cast<const uint8_t*>(content.c_str()),
976 content.size(), opts, errCode);
977 CHKPP(imageSource);
978 Media::DecodeOptions decodeOpts;
979 SetDecodeOptions(decodeOpts);
980 std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
981 return pixelMap;
982 }
983
NeedAdjustSvgInfo()984 bool DragDrawing::NeedAdjustSvgInfo()
985 {
986 CALL_DEBUG_ENTER;
987 if (g_drawingInfo.currentStyle == DragCursorStyle::DEFAULT) {
988 return false;
989 }
990 if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) &&
991 (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
992 return false;
993 }
994 std::string deviceType = system::GetDeviceType();
995 if ((g_drawingInfo.currentStyle == DragCursorStyle::MOVE) &&
996 ((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
997 (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
998 (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
999 return false;
1000 }
1001 if ((g_drawingInfo.currentStyle == DragCursorStyle::FORBIDDEN) &&
1002 (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1003 return false;
1004 }
1005 return true;
1006 }
1007
GetFilePath(std::string & filePath)1008 int32_t DragDrawing::GetFilePath(std::string &filePath)
1009 {
1010 CALL_DEBUG_ENTER;
1011 switch (g_drawingInfo.currentStyle) {
1012 case DragCursorStyle::COPY: {
1013 if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1014 filePath = COPY_ONE_DRAG_PATH;
1015 } else {
1016 filePath = COPY_DRAG_PATH;
1017 }
1018 break;
1019 }
1020 case DragCursorStyle::MOVE: {
1021 std::string deviceType = system::GetDeviceType();
1022 if (((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
1023 (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
1024 (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1025 FI_HILOGD("Device type is phone, not need draw svg style, deviceType:%{public}s", deviceType.c_str());
1026 filePath = DEFAULT_DRAG_PATH;
1027 } else {
1028 filePath = MOVE_DRAG_PATH;
1029 }
1030 break;
1031 }
1032 case DragCursorStyle::FORBIDDEN: {
1033 if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1034 filePath = FORBID_ONE_DRAG_PATH;
1035 } else {
1036 filePath = FORBID_DRAG_PATH;
1037 }
1038 break;
1039 }
1040 case DragCursorStyle::DEFAULT:
1041 default: {
1042 FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
1043 filePath = DEFAULT_DRAG_PATH;
1044 break;
1045 }
1046 }
1047 return RET_OK;
1048 }
1049
SetDecodeOptions(Media::DecodeOptions & decodeOpts)1050 void DragDrawing::SetDecodeOptions(Media::DecodeOptions &decodeOpts)
1051 {
1052 CALL_DEBUG_ENTER;
1053 std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
1054 if (strStyle.empty()) {
1055 FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
1056 return;
1057 }
1058 int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
1059 std::string deviceType = system::GetDeviceType();
1060 if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1061 decodeOpts.desiredSize = {
1062 .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1063 .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1064 };
1065 } else if (((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
1066 (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
1067 (g_drawingInfo.currentStyle == DragCursorStyle::MOVE) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1068 decodeOpts.desiredSize = {
1069 .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1070 .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1071 };
1072 } else {
1073 decodeOpts.desiredSize = {
1074 .width = (DEVICE_INDEPENDENT_PIXEL + extendSvgWidth) * GetScaling(),
1075 .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1076 };
1077 }
1078 }
1079
~DragDrawing()1080 DragDrawing::~DragDrawing()
1081 {
1082 if (dragExtHandle_ != nullptr) {
1083 dlclose(dragExtHandle_);
1084 dragExtHandle_ = nullptr;
1085 }
1086 }
1087
Draw(Rosen::RSDrawingContext & context) const1088 void DrawSVGModifier::Draw(Rosen::RSDrawingContext& context) const
1089 {
1090 CALL_DEBUG_ENTER;
1091 CHKPV(stylePixelMap_);
1092 CHKPV(g_drawingInfo.pixelMap);
1093 float scalingValue = GetScaling();
1094 if ((1.0 * INT_MAX / (SVG_WIDTH + EIGHT_SIZE)) <= scalingValue) {
1095 FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
1096 return;
1097 }
1098 int32_t adjustSize = EIGHT_SIZE * scalingValue;
1099 int32_t svgTouchPositionX = 0;
1100 if ((g_drawingInfo.pixelMap->GetWidth() + adjustSize) > stylePixelMap_->GetWidth()) {
1101 svgTouchPositionX = g_drawingInfo.pixelMap->GetWidth() + adjustSize - stylePixelMap_->GetWidth();
1102 }
1103 if (!CheckNodesValid()) {
1104 FI_HILOGE("Check nodes valid failed");
1105 return;
1106 }
1107 std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1108 CHKPV(dragStyleNode);
1109 dragStyleNode->SetBounds(svgTouchPositionX, (TWELVE_SIZE - EIGHT_SIZE) * scalingValue, stylePixelMap_->GetWidth(),
1110 stylePixelMap_->GetHeight());
1111 dragStyleNode->SetFrame(svgTouchPositionX, (TWELVE_SIZE - EIGHT_SIZE) * scalingValue, stylePixelMap_->GetWidth(),
1112 stylePixelMap_->GetHeight());
1113 dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
1114 dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
1115 dragStyleNode->SetBgImagePositionX(0);
1116 dragStyleNode->SetBgImagePositionY(0);
1117 auto rosenImage = std::make_shared<Rosen::RSImage>();
1118 rosenImage->SetPixelMap(stylePixelMap_);
1119 rosenImage->SetImageRepeat(0);
1120 dragStyleNode->SetBgImage(rosenImage);
1121 adjustSize = (SVG_WIDTH + TWELVE_SIZE) * scalingValue;
1122 g_drawingInfo.rootNodeWidth = g_drawingInfo.pixelMap->GetWidth() + adjustSize;
1123 g_drawingInfo.rootNodeHeight = g_drawingInfo.pixelMap->GetHeight() + adjustSize;
1124 CHKPV(g_drawingInfo.rootNode);
1125 g_drawingInfo.rootNode->SetBounds(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
1126 g_drawingInfo.rootNode->SetFrame(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
1127 CHKPV(g_drawingInfo.surfaceNode);
1128 g_drawingInfo.surfaceNode->SetBoundsWidth(g_drawingInfo.rootNodeWidth);
1129 g_drawingInfo.surfaceNode->SetBoundsHeight(g_drawingInfo.rootNodeHeight);
1130 Rosen::RSTransaction::FlushImplicitTransaction();
1131 }
1132
Draw(Rosen::RSDrawingContext & context) const1133 void DrawPixelMapModifier::Draw(Rosen::RSDrawingContext &context) const
1134 {
1135 CALL_DEBUG_ENTER;
1136 CHKPV(g_drawingInfo.pixelMap);
1137 auto rosenImage = std::make_shared<Rosen::RSImage>();
1138 rosenImage->SetPixelMap(g_drawingInfo.pixelMap);
1139 rosenImage->SetImageRepeat(0);
1140 int32_t pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
1141 int32_t pixelMapHeight = g_drawingInfo.pixelMap->GetHeight();
1142 if (!CheckNodesValid()) {
1143 FI_HILOGE("Check nodes valid failed");
1144 return;
1145 }
1146 std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
1147 CHKPV(pixelMapNode);
1148 pixelMapNode->SetBoundsWidth(pixelMapWidth);
1149 pixelMapNode->SetBoundsHeight(pixelMapHeight);
1150 pixelMapNode->SetBgImageWidth(pixelMapWidth);
1151 pixelMapNode->SetBgImageHeight(pixelMapHeight);
1152 pixelMapNode->SetBgImagePositionX(0);
1153 pixelMapNode->SetBgImagePositionY(0);
1154 pixelMapNode->SetBgImage(rosenImage);
1155 Rosen::RSTransaction::FlushImplicitTransaction();
1156 }
1157
Draw(Rosen::RSDrawingContext & context) const1158 void DrawMouseIconModifier::Draw(Rosen::RSDrawingContext &context) const
1159 {
1160 CALL_DEBUG_ENTER;
1161 std::string imagePath = MOUSE_DRAG_PATH;
1162 Media::SourceOptions opts;
1163 opts.formatHint = "image/svg+xml";
1164 uint32_t errCode = 0;
1165 auto imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errCode);
1166 CHKPV(imageSource);
1167 Media::DecodeOptions decodeOpts;
1168 decodeOpts.desiredSize = {
1169 .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1170 .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1171 };
1172 std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
1173 CHKPV(pixelMap);
1174 if (!CheckNodesValid()) {
1175 FI_HILOGE("Check nodes valid failed");
1176 return;
1177 }
1178 std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
1179 CHKPV(mouseIconNode);
1180 int32_t adjustSize = TWELVE_SIZE * GetScaling();
1181 mouseIconNode->SetBounds(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY + adjustSize,
1182 pixelMap->GetWidth(), pixelMap->GetHeight());
1183 mouseIconNode->SetFrame(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY + adjustSize,
1184 pixelMap->GetWidth(), pixelMap->GetHeight());
1185 mouseIconNode->SetBgImageWidth(decodeOpts.desiredSize.width);
1186 mouseIconNode->SetBgImageHeight(decodeOpts.desiredSize.height);
1187 mouseIconNode->SetBgImagePositionX(0);
1188 mouseIconNode->SetBgImagePositionY(0);
1189 auto rosenImage = std::make_shared<Rosen::RSImage>();
1190 rosenImage->SetPixelMap(pixelMap);
1191 rosenImage->SetImageRepeat(0);
1192 mouseIconNode->SetBgImage(rosenImage);
1193 Rosen::RSTransaction::FlushImplicitTransaction();
1194 }
1195
Draw(Rosen::RSDrawingContext & context) const1196 void DrawDynamicEffectModifier::Draw(Rosen::RSDrawingContext &context) const
1197 {
1198 CALL_DEBUG_ENTER;
1199 CHKPV(alpha_);
1200 CHKPV(g_drawingInfo.rootNode);
1201 g_drawingInfo.rootNode->SetAlpha(alpha_->Get());
1202 CHKPV(scale_);
1203 CHKPV(g_drawingInfo.surfaceNode);
1204 g_drawingInfo.surfaceNode->SetScale(scale_->Get(), scale_->Get());
1205 Rosen::RSTransaction::FlushImplicitTransaction();
1206 }
1207
SetAlpha(float alpha)1208 void DrawDynamicEffectModifier::SetAlpha(float alpha)
1209 {
1210 CALL_DEBUG_ENTER;
1211 if (alpha_ == nullptr) {
1212 alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
1213 Rosen::RSModifier::AttachProperty(alpha_);
1214 return;
1215 }
1216 alpha_->Set(alpha);
1217 }
1218
SetScale(float scale)1219 void DrawDynamicEffectModifier::SetScale(float scale)
1220 {
1221 CALL_DEBUG_ENTER;
1222 if (scale_ == nullptr) {
1223 scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
1224 Rosen::RSModifier::AttachProperty(scale_);
1225 return;
1226 }
1227 scale_->Set(scale);
1228 }
1229 } // namespace DeviceStatus
1230 } // namespace Msdp
1231 } // namespace OHOS