• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "pointer_drawing_manager.h"
17 
18 #include "image/bitmap.h"
19 #include "image_source.h"
20 #include "image_type.h"
21 #include "image_utils.h"
22 
23 #include "define_multimodal.h"
24 #include "input_device_manager.h"
25 #include "input_windows_manager.h"
26 #include "ipc_skeleton.h"
27 #include "mmi_log.h"
28 #include "preferences.h"
29 #include "preferences_impl.h"
30 #include "preferences_errno.h"
31 #include "preferences_helper.h"
32 #include "preferences_xml_utils.h"
33 #include "multimodal_input_preferences_manager.h"
34 #include "util.h"
35 #ifndef USE_ROSEN_DRAWING
36 #include "pipeline/rs_recording_canvas.h"
37 #else
38 #include "recording/recording_canvas.h"
39 #endif
40 
41 namespace OHOS {
42 namespace MMI {
43 namespace {
44 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "PointerDrawingManager" };
45 const std::string IMAGE_POINTER_DEFAULT_PATH = "/system/etc/multimodalinput/mouse_icon/";
46 const std::string DefaultIconPath = IMAGE_POINTER_DEFAULT_PATH + "Default.svg";
47 constexpr int32_t BASELINE_DENSITY = 160;
48 constexpr int32_t CALCULATE_MIDDLE = 2;
49 constexpr int32_t DEVICE_INDEPENDENT_PIXELS = 40;
50 constexpr int32_t POINTER_WINDOW_INIT_SIZE = 64;
51 constexpr int32_t DEFAULT_POINTER_SIZE = 1;
52 constexpr int32_t MIN_POINTER_SIZE = 1;
53 constexpr int32_t MAX_POINTER_SIZE = 7;
54 constexpr int32_t DEFAULT_VALUE = -1;
55 constexpr int32_t ANIMATION_DURATION = 500;
56 constexpr int32_t DEFAULT_POINTER_STYLE = 0;
57 constexpr int32_t CURSOR_CIRCLE_STYLE = 41;
58 constexpr int32_t MOUSE_ICON_BAIS = 5;
59 constexpr int32_t VISIBLE_LIST_MAX_SIZE = 100;
60 constexpr float ROTATION_ANGLE = 360.f;
61 constexpr float LOADING_CENTER_RATIO = 0.5f;
62 constexpr float RUNNING_X_RATIO = 0.3f;
63 constexpr float RUNNING_Y_RATIO = 0.675f;
64 constexpr float INCREASE_RATIO = 1.22;
65 constexpr float ROTATION_ANGLE90 = 90.f;
66 constexpr int32_t MIN_POINTER_COLOR = 0x000000;
67 constexpr int32_t MAX_POINTER_COLOR = 0xffffff;
68 constexpr int32_t MIN_CURSOR_SIZE = 64;
69 const std::string MOUSE_FILE_NAME = "mouse_settings.xml";
70 bool isRsRemoteDied = false;
71 } // namespace
72 } // namespace MMI
73 } // namespace OHOS
74 
75 namespace OHOS {
76 namespace MMI {
PointerDrawingManager()77 PointerDrawingManager::PointerDrawingManager()
78 {
79     InitStyle();
80 }
81 
GetLastMouseStyle()82 PointerStyle PointerDrawingManager::GetLastMouseStyle()
83 {
84     CALL_DEBUG_ENTER;
85     return lastMouseStyle_;
86 }
87 
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)88 void PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
89     const PointerStyle pointerStyle, Direction direction)
90 {
91     MMI_HILOGD("Pointer window move success");
92     if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) {
93         surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
94             surfaceNode_->GetStagingProperties().GetBounds().z_,
95             surfaceNode_->GetStagingProperties().GetBounds().w_);
96         Rosen::RSTransaction::FlushImplicitTransaction();
97         MMI_HILOGD("The lastpointerStyle is equal with pointerStyle,id %{public}d size:%{public}d",
98             pointerStyle.id, pointerStyle.size);
99         return;
100     }
101     if (lastDirection_ != direction) {
102         RotateDegree(direction);
103         lastDirection_ = direction;
104     }
105     lastMouseStyle_ = pointerStyle;
106     surfaceNode_->SetVisible(false);
107     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
108     if (ret != RET_OK) {
109         mouseIconUpdate_ = false;
110         MMI_HILOGE("Init layer failed");
111         return;
112     }
113     surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
114         surfaceNode_->GetStagingProperties().GetBounds().z_,
115         surfaceNode_->GetStagingProperties().GetBounds().w_);
116     surfaceNode_->SetVisible(true);
117     Rosen::RSTransaction::FlushImplicitTransaction();
118     UpdatePointerVisible();
119     mouseIconUpdate_ = false;
120     MMI_HILOGD("Leave, display:%{public}d,physicalX:%{public}d,physicalY:%{public}d",
121         displayId, physicalX, physicalY);
122     return;
123 }
124 
DrawPointer(int32_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)125 void PointerDrawingManager::DrawPointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
126     const PointerStyle pointerStyle, Direction direction)
127 {
128     CALL_DEBUG_ENTER;
129     MMI_HILOGD("Display:%{public}d,physicalX:%{public}d,physicalY:%{public}d,pointerStyle:%{public}d",
130         displayId, physicalX, physicalY, pointerStyle.id);
131     FixCursorPosition(physicalX, physicalY);
132     lastPhysicalX_ = physicalX;
133     lastPhysicalY_ = physicalY;
134     currentMouseStyle_ = pointerStyle;
135     currentDirection_ = direction;
136     AdjustMouseFocus(ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay), physicalX, physicalY);
137 
138     if (surfaceNode_ != nullptr) {
139         DrawMovePointer(displayId, physicalX, physicalY, pointerStyle, direction);
140         return;
141     }
142     CreatePointerWindow(displayId, physicalX, physicalY, direction);
143     CHKPV(surfaceNode_);
144     UpdateMouseStyle();
145     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
146     if (ret != RET_OK) {
147         MMI_HILOGE("Init layer failed");
148         return;
149     }
150     UpdatePointerVisible();
151     MMI_HILOGD("Leave, display:%{public}d,physicalX:%{public}d,physicalY:%{public}d", displayId, physicalX, physicalY);
152 }
153 
UpdateMouseStyle()154 void PointerDrawingManager::UpdateMouseStyle()
155 {
156     CALL_DEBUG_ENTER;
157     PointerStyle curPointerStyle;
158     int result = GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
159     if (result != RET_OK) {
160         MMI_HILOGE("Get current pointer style failed");
161         return;
162     }
163     if (curPointerStyle.id == CURSOR_CIRCLE_STYLE) {
164         lastMouseStyle_.id = curPointerStyle.id;
165         int ret = SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
166         if (ret != RET_OK) {
167             MMI_HILOGE("Set pointer style failed");
168         }
169         return;
170     }
171 }
172 
InitLayer(const MOUSE_ICON mouseStyle)173 int32_t PointerDrawingManager::InitLayer(const MOUSE_ICON mouseStyle)
174 {
175     CALL_DEBUG_ENTER;
176     if (surfaceNode_ == nullptr) {
177         MMI_HILOGD("surfaceNode_ is nullptr");
178         return RET_ERR;
179     }
180     DrawLoadingPointerStyle(mouseStyle);
181     DrawRunningPointerAnimate(mouseStyle);
182     sptr<OHOS::Surface> layer = GetLayer();
183     if (layer == nullptr) {
184         MMI_HILOGE("Init layer is failed, Layer is nullptr");
185         surfaceNode_->DetachToDisplay(screenId_);
186         surfaceNode_ = nullptr;
187         Rosen::RSTransaction::FlushImplicitTransaction();
188         MMI_HILOGD("Pointer window destroy success");
189         return RET_ERR;
190     }
191 
192     sptr<OHOS::SurfaceBuffer> buffer = GetSurfaceBuffer(layer);
193     if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
194         MMI_HILOGE("Init layer is failed, buffer or virAddr is nullptr");
195         surfaceNode_->DetachToDisplay(screenId_);
196         surfaceNode_ = nullptr;
197         Rosen::RSTransaction::FlushImplicitTransaction();
198         MMI_HILOGD("Pointer window destroy success");
199         return RET_ERR;
200     }
201 
202     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
203     DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), mouseStyle);
204     OHOS::BufferFlushConfig flushConfig = {
205         .damage = {
206             .w = buffer->GetWidth(),
207             .h = buffer->GetHeight(),
208         },
209     };
210     OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
211     if (ret != OHOS::SURFACE_ERROR_OK) {
212         MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
213         return RET_ERR;
214     }
215     MMI_HILOGD("Init layer success");
216     return RET_OK;
217 }
218 
DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)219 void PointerDrawingManager::DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)
220 {
221     CALL_DEBUG_ENTER;
222     CHKPV(surfaceNode_);
223     Rosen::RSAnimationTimingProtocol protocol;
224     if (mouseStyle != MOUSE_ICON::LOADING &&
225         (mouseStyle != MOUSE_ICON::DEFAULT ||
226             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"))) {
227         protocol.SetDuration(0);
228         Rosen::RSNode::Animate(
229             protocol,
230             Rosen::RSAnimationTimingCurve::LINEAR,
231             [this]() { RotateDegree(currentDirection_); });
232         MMI_HILOGD("current pointer is not loading");
233         Rosen::RSTransaction::FlushImplicitTransaction();
234         return;
235     }
236     float ratio = imageWidth_ * 1.0 / IMAGE_WIDTH;
237     surfaceNode_->SetPivot({LOADING_CENTER_RATIO * ratio, LOADING_CENTER_RATIO * ratio});
238     protocol.SetDuration(ANIMATION_DURATION);
239     protocol.SetRepeatCount(DEFAULT_VALUE);
240 
241     // create property animation
242     Rosen::RSNode::Animate(
243         protocol,
244         Rosen::RSAnimationTimingCurve::LINEAR,
245         [this]() { surfaceNode_->SetRotation(ROTATION_ANGLE); });
246 
247     Rosen::RSTransaction::FlushImplicitTransaction();
248 }
249 
DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)250 void PointerDrawingManager::DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)
251 {
252     CALL_DEBUG_ENTER;
253     CHKPV(surfaceNode_);
254     if (mouseStyle != MOUSE_ICON::RUNNING &&
255         (mouseStyle != MOUSE_ICON::DEFAULT ||
256             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"))) {
257         if (canvasNode_ != nullptr) {
258             canvasNode_->SetVisible(false);
259         }
260         MMI_HILOGD("current pointer is not running");
261         return;
262     }
263     canvasNode_->SetVisible(true);
264     float ratio = imageWidth_ * 1.0 / IMAGE_WIDTH;
265     canvasNode_->SetPivot({RUNNING_X_RATIO * ratio, RUNNING_Y_RATIO * ratio});
266     std::shared_ptr<OHOS::Media::PixelMap> pixelmap =
267         DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_RIGHT].iconPath);
268     CHKPV(pixelmap);
269     MMI_HILOGD("set mouseicon to OHOS system");
270 
271 #ifndef USE_ROSEN_DRAWING
272     auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
273     canvas->DrawPixelMap(pixelmap, 0, 0, SkSamplingOptions(), nullptr);
274 #else
275     Rosen::Drawing::Brush brush;
276     Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
277     Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(src);
278     auto canvas =
279         static_cast<Rosen::ExtendRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
280     canvas->AttachBrush(brush);
281     canvas->DrawPixelMapRect(pixelmap, src, dst, Rosen::Drawing::SamplingOptions());
282     canvas->DetachBrush();
283 #endif
284 
285     canvasNode_->FinishRecording();
286 
287     Rosen::RSAnimationTimingProtocol protocol;
288     protocol.SetDuration(ANIMATION_DURATION);
289     protocol.SetRepeatCount(DEFAULT_VALUE);
290 
291     // create property animation
292     Rosen::RSNode::Animate(
293         protocol,
294         Rosen::RSAnimationTimingCurve::LINEAR,
295         [this]() { canvasNode_->SetRotation(ROTATION_ANGLE); });
296 
297     Rosen::RSTransaction::FlushImplicitTransaction();
298 }
299 
AdjustMouseFocus(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)300 void PointerDrawingManager::AdjustMouseFocus(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
301 {
302     CALL_DEBUG_ENTER;
303     switch (iconType) {
304         case ANGLE_SW: {
305             physicalY -= imageHeight_;
306             break;
307         }
308         case ANGLE_CENTER: {
309             physicalX -= imageWidth_ / CALCULATE_MIDDLE;
310             physicalY -= imageHeight_ / CALCULATE_MIDDLE;
311             break;
312         }
313         case ANGLE_NW_RIGHT:{
314             physicalX -= MOUSE_ICON_BAIS;
315             [[fallthrough]];
316         }
317         case ANGLE_NW:
318             if (userIcon_ != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
319                 physicalX -= userIconHotSpotX_;
320                 physicalY -= userIconHotSpotY_;
321             }
322             break;
323         default: {
324             MMI_HILOGD("No need adjust mouse focus");
325             break;
326         }
327     }
328 }
329 
SetMouseDisplayState(bool state)330 void PointerDrawingManager::SetMouseDisplayState(bool state)
331 {
332     CALL_DEBUG_ENTER;
333     if (mouseDisplayState_ != state) {
334         mouseDisplayState_ = state;
335         if (mouseDisplayState_) {
336             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
337         }
338         MMI_HILOGI("state:%{public}s", state ? "true" : "false");
339         UpdatePointerVisible();
340     }
341 }
342 
GetMouseDisplayState() const343 bool PointerDrawingManager::GetMouseDisplayState() const
344 {
345     return mouseDisplayState_;
346 }
347 
FixCursorPosition(int32_t & physicalX,int32_t & physicalY)348 void PointerDrawingManager::FixCursorPosition(int32_t &physicalX, int32_t &physicalY)
349 {
350     if (physicalX < 0) {
351         physicalX = 0;
352     }
353 
354     if (physicalY < 0) {
355         physicalY = 0;
356     }
357     const int32_t cursorUnit = 16;
358     if (displayInfo_.displayDirection == DIRECTION0) {
359         if (displayInfo_.direction == DIRECTION0 || displayInfo_.direction == DIRECTION180) {
360             if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
361                 physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
362             }
363             if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
364                 physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
365             }
366         } else {
367             if (physicalX > (displayInfo_.height - imageHeight_ / cursorUnit)) {
368                 physicalX = displayInfo_.height - imageHeight_ / cursorUnit;
369             }
370             if (physicalY > (displayInfo_.width - imageWidth_ / cursorUnit)) {
371                 physicalY = displayInfo_.width - imageWidth_ / cursorUnit;
372             }
373         }
374     } else {
375         if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
376             physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
377         }
378         if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
379             physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
380         }
381     }
382 }
383 
RsRemoteDiedCallback()384 void RsRemoteDiedCallback()
385 {
386     CALL_DEBUG_ENTER;
387     isRsRemoteDied = true;
388 }
389 
CreatePointerWindow(int32_t displayId,int32_t physicalX,int32_t physicalY,Direction direction)390 void PointerDrawingManager::CreatePointerWindow(int32_t displayId, int32_t physicalX, int32_t physicalY,
391     Direction direction)
392 {
393     CALL_DEBUG_ENTER;
394     CALL_INFO_TRACE;
395     isRsRemoteDied = false;
396     Rosen::OnRemoteDiedCallback callback = RsRemoteDiedCallback;
397     Rosen::RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
398     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
399     surfaceNodeConfig.SurfaceNodeName = "pointer window";
400     Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
401     surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
402     CHKPV(surfaceNode_);
403     surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
404     surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
405     surfaceNode_->SetBounds(physicalX, physicalY, IMAGE_WIDTH, IMAGE_HEIGHT);
406 #ifndef USE_ROSEN_DRAWING
407     surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
408 #else
409     surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
410 #endif
411 
412     screenId_ = static_cast<uint64_t>(displayId);
413     std::cout << "ScreenId: " << screenId_ << std::endl;
414     surfaceNode_->AttachToDisplay(screenId_);
415     RotateDegree(direction);
416     lastDirection_ = direction;
417 
418     canvasNode_ = Rosen::RSCanvasNode::Create();
419     canvasNode_->SetBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
420     canvasNode_->SetFrame(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
421 #ifndef USE_ROSEN_DRAWING
422     canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
423 #else
424     canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
425 #endif
426     canvasNode_->SetCornerRadius(1);
427     canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
428     canvasNode_->SetRotation(0);
429     surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
430     Rosen::RSTransaction::FlushImplicitTransaction();
431 }
432 
GetLayer()433 sptr<OHOS::Surface> PointerDrawingManager::GetLayer()
434 {
435     CALL_DEBUG_ENTER;
436     if (surfaceNode_ == nullptr) {
437         MMI_HILOGE("Draw pointer is failed, get node is nullptr");
438         return nullptr;
439     }
440     return surfaceNode_->GetSurface();
441 }
442 
GetSurfaceBuffer(sptr<OHOS::Surface> layer) const443 sptr<OHOS::SurfaceBuffer> PointerDrawingManager::GetSurfaceBuffer(sptr<OHOS::Surface> layer) const
444 {
445     CALL_DEBUG_ENTER;
446     sptr<OHOS::SurfaceBuffer> buffer;
447     int32_t releaseFence = -1;
448     OHOS::BufferRequestConfig config = {
449         .width = IMAGE_WIDTH,
450         .height = IMAGE_HEIGHT,
451         .strideAlignment = 0x8,
452         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
453         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
454     };
455 
456     OHOS::SurfaceError ret = layer->RequestBuffer(buffer, releaseFence, config);
457     close(releaseFence);
458     if (ret != OHOS::SURFACE_ERROR_OK) {
459         MMI_HILOGE("Request buffer ret:%{public}s", SurfaceErrorStr(ret).c_str());
460         return nullptr;
461     }
462     return buffer;
463 }
464 
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,const MOUSE_ICON mouseStyle)465 void PointerDrawingManager::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const MOUSE_ICON mouseStyle)
466 {
467     CALL_DEBUG_ENTER;
468     OHOS::Rosen::Drawing::Bitmap bitmap;
469     OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
470         OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
471     bitmap.Build(width, height, format);
472     OHOS::Rosen::Drawing::Canvas canvas;
473     canvas.Bind(bitmap);
474     canvas.Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
475     DrawPixelmap(canvas, mouseStyle);
476     static constexpr uint32_t stride = 4;
477     uint32_t addrSize = width * height * stride;
478     errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
479     if (ret != EOK) {
480         MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
481         return;
482     }
483 }
484 
DrawPixelmap(OHOS::Rosen::Drawing::Canvas & canvas,const MOUSE_ICON mouseStyle)485 void PointerDrawingManager::DrawPixelmap(OHOS::Rosen::Drawing::Canvas &canvas, const MOUSE_ICON mouseStyle)
486 {
487     CALL_DEBUG_ENTER;
488     OHOS::Rosen::Drawing::Pen pen;
489     pen.SetAntiAlias(true);
490     pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
491     OHOS::Rosen::Drawing::scalar penWidth = 1;
492     pen.SetWidth(penWidth);
493     canvas.AttachPen(pen);
494     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
495         MMI_HILOGD("set mouseicon by userIcon_");
496         canvas.DrawBitmap(*userIcon_, 0, 0);
497     } else {
498         std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
499         if (mouseStyle == MOUSE_ICON::RUNNING) {
500             pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
501         } else {
502             pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
503         }
504         CHKPV(pixelmap);
505         MMI_HILOGD("set mouseicon to OHOS system");
506         canvas.DrawBitmap(*pixelmap, 0, 0);
507     }
508 }
509 
SetCustomCursor(void * pixelMap,int32_t pid,int32_t windowId,int32_t focusX,int32_t focusY)510 int32_t PointerDrawingManager::SetCustomCursor(void* pixelMap, int32_t pid, int32_t windowId, int32_t focusX,
511     int32_t focusY)
512 {
513     CALL_DEBUG_ENTER;
514     CHKPR(pixelMap, RET_ERR);
515     if (pid == -1) {
516         MMI_HILOGE("pid is invalid");
517         return RET_ERR;
518     }
519     if (windowId < 0) {
520         MMI_HILOGE("windowId is invalid, windowId: %{public}d", windowId);
521         return RET_ERR;
522     }
523 
524     int32_t ret = UpdateCursorProperty(pixelMap);
525     if (ret != RET_OK) {
526         MMI_HILOGE("UpdateCursorProperty is failed");
527         return ret;
528     }
529     mouseIconUpdate_ = true;
530     userIconHotSpotX_ = focusX;
531     userIconHotSpotY_ = focusY;
532     PointerStyle style;
533     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
534     lastMouseStyle_ = style;
535 
536     ret = SetPointerStyle(pid, windowId, style);
537     if (ret == RET_ERR) {
538         MMI_HILOGE("SetPointerStyle is failed");
539     }
540     MMI_HILOGD("style.id: %{public}d, userIconHotSpotX_: %{public}d, userIconHotSpotY_: %{public}d",
541         style.id, userIconHotSpotX_, userIconHotSpotY_);
542     return ret;
543 }
544 
UpdateCursorProperty(void * pixelMap)545 int32_t PointerDrawingManager::UpdateCursorProperty(void* pixelMap)
546 {
547     CHKPR(pixelMap, RET_ERR);
548     Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(pixelMap);
549     CHKPR(newPixelMap, RET_ERR);
550     Media::ImageInfo imageInfo;
551     newPixelMap->GetImageInfo(imageInfo);
552     int32_t cursorSize = GetPointerSize();
553     int32_t cursorWidth =
554         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
555     int32_t cursorHeight =
556         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
557     cursorWidth = cursorWidth < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorWidth;
558     cursorHeight = cursorHeight < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorHeight;
559     float xAxis = (float)cursorWidth / (float)imageInfo.size.width;
560     float yAxis = (float)cursorHeight / (float)imageInfo.size.height;
561     newPixelMap->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
562     userIcon_.reset(newPixelMap);
563     MMI_HILOGI("cursorWidth: %{public}d, cursorHeight: %{public}d", cursorWidth, cursorHeight);
564     return RET_OK;
565 }
566 
SetMouseIcon(int32_t pid,int32_t windowId,void * pixelMap)567 int32_t PointerDrawingManager::SetMouseIcon(int32_t pid, int32_t windowId, void* pixelMap)
568 {
569     CALL_DEBUG_ENTER;
570     if (pid == -1) {
571         MMI_HILOGE("pid is invalid return -1");
572         return RET_ERR;
573     }
574     if (pixelMap == nullptr) {
575         MMI_HILOGE("pixelMap is null!");
576         return RET_ERR;
577     }
578     if (windowId < 0) {
579         MMI_HILOGE("get invalid windowId, %{public}d", windowId);
580         return RET_ERR;
581     }
582     OHOS::Media::PixelMap* pixelMapPtr = static_cast<OHOS::Media::PixelMap*>(pixelMap);
583     userIcon_.reset(pixelMapPtr);
584     mouseIconUpdate_ = true;
585     PointerStyle style;
586     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
587     int32_t ret = SetPointerStyle(pid, windowId, style);
588     if (ret == RET_ERR) {
589         MMI_HILOGE("SetPointerStyle return RET_ERR here!");
590     }
591     return ret;
592 }
593 
SetMouseHotSpot(int32_t pid,int32_t windowId,int32_t hotSpotX,int32_t hotSpotY)594 int32_t PointerDrawingManager::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
595 {
596     CALL_DEBUG_ENTER;
597     if (pid == -1) {
598         MMI_HILOGE("pid is invalid return -1");
599         return RET_ERR;
600     }
601     if (windowId < 0) {
602         MMI_HILOGE("invalid windowId, %{public}d", windowId);
603         return RET_ERR;
604     }
605     if (hotSpotX < 0 || hotSpotY < 0 || userIcon_ == nullptr) {
606         MMI_HILOGE("invalid value");
607         return RET_ERR;
608     }
609     PointerStyle pointerStyle;
610     int32_t ret = WinMgr->GetPointerStyle(pid, windowId, pointerStyle);
611     if (ret != RET_OK || pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
612         MMI_HILOGE("Get pointer style failed, pid %{publid}d, pointerStyle %{public}d", pid, pointerStyle.id);
613         return RET_ERR;
614     }
615     userIconHotSpotX_ = hotSpotX;
616     userIconHotSpotY_ = hotSpotY;
617     return RET_OK;
618 }
619 
DecodeImageToPixelMap(const std::string & imagePath)620 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::DecodeImageToPixelMap(const std::string &imagePath)
621 {
622     CALL_DEBUG_ENTER;
623     OHOS::Media::SourceOptions opts;
624     opts.formatHint = "image/svg+xml";
625     uint32_t ret = 0;
626     auto imageSource = OHOS::Media::ImageSource::CreateImageSource(imagePath, opts, ret);
627     CHKPP(imageSource);
628     std::set<std::string> formats;
629     ret = imageSource->GetSupportedFormats(formats);
630     MMI_HILOGD("Get supported format ret:%{public}u", ret);
631 
632     OHOS::Media::DecodeOptions decodeOpts;
633     decodeOpts.desiredSize = {
634         .width = imageWidth_,
635         .height = imageHeight_
636     };
637     int32_t pointerColor = GetPointerColor();
638     if (tempPointerColor_ != DEFAULT_VALUE) {
639         decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
640     }
641 
642     std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, ret);
643     if (pixelMap == nullptr) {
644         MMI_HILOGE("The pixelMap is nullptr");
645     }
646     return pixelMap;
647 }
648 
SetPointerColor(int32_t color)649 int32_t PointerDrawingManager::SetPointerColor(int32_t color)
650 {
651     CALL_DEBUG_ENTER;
652     if (color < MIN_POINTER_COLOR) {
653         color = MIN_POINTER_COLOR;
654     } else if (color > MAX_POINTER_COLOR) {
655         color = MAX_POINTER_COLOR;
656     }
657     std::string name = "pointerColor";
658     int32_t ret = PreferencesMgr->SetIntValue(name, MOUSE_FILE_NAME, color);
659     if (ret == RET_OK) {
660         MMI_HILOGD("Set pointer color successfully, color:%{public}d", color);
661     }
662 
663     ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
664     if (ret != RET_OK) {
665         MMI_HILOGE("Init layer failed");
666         return RET_ERR;
667     }
668     UpdatePointerVisible();
669     return RET_OK;
670 }
671 
GetPointerColor()672 int32_t PointerDrawingManager::GetPointerColor()
673 {
674     CALL_DEBUG_ENTER;
675     std::string name = "pointerColor";
676     int32_t pointerColor = PreferencesMgr->GetIntValue(name, DEFAULT_VALUE);
677     tempPointerColor_ = pointerColor;
678     if (pointerColor == DEFAULT_VALUE) {
679         pointerColor = MIN_POINTER_COLOR;
680     }
681     MMI_HILOGD("Get pointer color successfully, pointerColor:%{public}d", pointerColor);
682     return pointerColor;
683 }
684 
UpdateDisplayInfo(const DisplayInfo & displayInfo)685 void PointerDrawingManager::UpdateDisplayInfo(const DisplayInfo& displayInfo)
686 {
687     CALL_DEBUG_ENTER;
688     hasDisplay_ = true;
689     displayInfo_ = displayInfo;
690     int32_t size = GetPointerSize();
691     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
692     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
693     IMAGE_WIDTH = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
694     IMAGE_HEIGHT = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
695 }
696 
SetPointerSize(int32_t size)697 int32_t PointerDrawingManager::SetPointerSize(int32_t size)
698 {
699     CALL_DEBUG_ENTER;
700     if (size < MIN_POINTER_SIZE) {
701         size = MIN_POINTER_SIZE;
702     } else if (size > MAX_POINTER_SIZE) {
703         size = MAX_POINTER_SIZE;
704     }
705     std::string name = "pointerSize";
706     int32_t ret = PreferencesMgr->SetIntValue(name, MOUSE_FILE_NAME, size);
707     if (ret == RET_OK) {
708         MMI_HILOGD("Set pointer size successfully, size:%{public}d", size);
709     }
710 
711     if (surfaceNode_ == nullptr) {
712         MMI_HILOGI("surfaceNode_ is nullptr");
713         return RET_OK;
714     }
715     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
716     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * DEVICE_INDEPENDENT_PIXELS / BASELINE_DENSITY;
717     IMAGE_WIDTH = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
718     IMAGE_HEIGHT = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
719     int32_t physicalX = lastPhysicalX_;
720     int32_t physicalY = lastPhysicalY_;
721     AdjustMouseFocus(ICON_TYPE(mouseIcons_[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay), physicalX, physicalY);
722     CreatePointerWindow(displayInfo_.id, physicalX, physicalY, displayInfo_.direction);
723     ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
724     if (ret != RET_OK) {
725         MMI_HILOGE("Init layer failed");
726         return RET_ERR;
727     }
728     UpdatePointerVisible();
729     return RET_OK;
730 }
731 
GetPointerSize()732 int32_t PointerDrawingManager::GetPointerSize()
733 {
734     CALL_DEBUG_ENTER;
735     std::string name = "pointerSize";
736     int32_t pointerSize = PreferencesMgr->GetIntValue(name, DEFAULT_POINTER_SIZE);
737     MMI_HILOGD("Get pointer size successfully, pointerSize:%{public}d", pointerSize);
738     return pointerSize;
739 }
740 
OnDisplayInfo(const DisplayGroupInfo & displayGroupInfo)741 void PointerDrawingManager::OnDisplayInfo(const DisplayGroupInfo& displayGroupInfo)
742 {
743     CALL_DEBUG_ENTER;
744     for (const auto& item : displayGroupInfo.displaysInfo) {
745         if (item.id == displayInfo_.id) {
746             UpdateDisplayInfo(item);
747             DrawManager();
748             return;
749         }
750     }
751     UpdateDisplayInfo(displayGroupInfo.displaysInfo[0]);
752     lastPhysicalX_ = displayGroupInfo.displaysInfo[0].width / CALCULATE_MIDDLE;
753     lastPhysicalY_ = displayGroupInfo.displaysInfo[0].height / CALCULATE_MIDDLE;
754     MouseEventHdr->OnDisplayLost(displayInfo_.id);
755     if (surfaceNode_ != nullptr) {
756         surfaceNode_->DetachToDisplay(screenId_);
757         surfaceNode_ = nullptr;
758         Rosen::RSTransaction::FlushImplicitTransaction();
759         MMI_HILOGD("Pointer window destroy success");
760     }
761     MMI_HILOGD("displayId_:%{public}d, displayWidth_:%{public}d, displayHeight_:%{public}d",
762         displayInfo_.id, displayInfo_.width, displayInfo_.height);
763 }
764 
OnWindowInfo(const WinInfo & info)765 void PointerDrawingManager::OnWindowInfo(const WinInfo &info)
766 {
767     CALL_DEBUG_ENTER;
768     windowId_ = info.windowId;
769     pid_ = info.windowPid;
770 }
771 
UpdatePointerDevice(bool hasPointerDevice,bool isPointerVisible)772 void PointerDrawingManager::UpdatePointerDevice(bool hasPointerDevice, bool isPointerVisible)
773 {
774     CALL_DEBUG_ENTER;
775     hasPointerDevice_ = hasPointerDevice;
776     if (hasPointerDevice_) {
777         SetPointerVisible(getpid(), isPointerVisible && IsPointerVisible());
778     } else {
779         DeletePointerVisible(getpid());
780     }
781     DrawManager();
782 }
783 
DrawManager()784 void PointerDrawingManager::DrawManager()
785 {
786     CALL_DEBUG_ENTER;
787     if (hasDisplay_ && hasPointerDevice_ && surfaceNode_ == nullptr) {
788         MMI_HILOGD("Draw pointer begin");
789         PointerStyle pointerStyle;
790         int32_t ret = WinMgr->GetPointerStyle(pid_, windowId_, pointerStyle);
791         MMI_HILOGD("get pid %{publid}d with pointerStyle %{public}d", pid_, pointerStyle.id);
792         if (ret != RET_OK) {
793             MMI_HILOGE("Get pointer style failed, pointerStyleInfo is nullptr");
794             return;
795         }
796         Direction direction = DIRECTION0;
797         if (displayInfo_.displayDirection == DIRECTION0) {
798             direction = displayInfo_.direction;
799         }
800         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
801             DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
802                 pointerStyle, direction);
803             WinMgr->SendPointerEvent(PointerEvent::POINTER_ACTION_MOVE);
804             MMI_HILOGD("Draw manager, mouseStyle:%{public}d, last physical is initial value", pointerStyle.id);
805             return;
806         }
807         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
808         WinMgr->SendPointerEvent(PointerEvent::POINTER_ACTION_MOVE);
809         MMI_HILOGD("Draw manager, mouseStyle:%{public}d", pointerStyle.id);
810         return;
811     }
812     if (!hasPointerDevice_ && surfaceNode_ != nullptr) {
813         MMI_HILOGD("Pointer window destroy start");
814         surfaceNode_->DetachToDisplay(screenId_);
815         surfaceNode_ = nullptr;
816         Rosen::RSTransaction::FlushImplicitTransaction();
817         MMI_HILOGD("Pointer window destroy success");
818     }
819 }
820 
Init()821 bool PointerDrawingManager::Init()
822 {
823     CALL_DEBUG_ENTER;
824     InputDevMgr->Attach(shared_from_this());
825     pidInfos_.clear();
826     return true;
827 }
828 
GetInstance()829 std::shared_ptr<IPointerDrawingManager> IPointerDrawingManager::GetInstance()
830 {
831     if (iPointDrawMgr_ == nullptr) {
832         iPointDrawMgr_ = std::make_shared<PointerDrawingManager>();
833     }
834     return iPointDrawMgr_;
835 }
836 
UpdatePointerVisible()837 void PointerDrawingManager::UpdatePointerVisible()
838 {
839     CALL_DEBUG_ENTER;
840     CHKPV(surfaceNode_);
841     MMI_HILOGI("mouseDisplayState_:%{public}s", mouseDisplayState_ ? "true" : "false");
842     if (IsPointerVisible() && mouseDisplayState_) {
843         surfaceNode_->SetVisible(true);
844         MMI_HILOGI("Pointer window show success");
845     } else {
846         surfaceNode_->SetVisible(false);
847         MMI_HILOGI("Pointer window hide success");
848     }
849     Rosen::RSTransaction::FlushImplicitTransaction();
850 }
851 
IsPointerVisible()852 bool PointerDrawingManager::IsPointerVisible()
853 {
854     CALL_DEBUG_ENTER;
855     if (pidInfos_.empty()) {
856         MMI_HILOGD("Visible property is true");
857         return true;
858     }
859     auto info = pidInfos_.back();
860     MMI_HILOGI("Visible property:%{public}zu.%{public}d-visible:%{public}s",
861         pidInfos_.size(), info.pid, info.visible ? "true" : "false");
862     return info.visible;
863 }
864 
DeletePointerVisible(int32_t pid)865 void PointerDrawingManager::DeletePointerVisible(int32_t pid)
866 {
867     CALL_DEBUG_ENTER;
868     MMI_HILOGI("isRsRemoteDied:%{public}d", isRsRemoteDied ? 1 : 0);
869     if (isRsRemoteDied && surfaceNode_ != nullptr) {
870         isRsRemoteDied = false;
871         surfaceNode_->DetachToDisplay(screenId_);
872         surfaceNode_ = nullptr;
873         Rosen::RSTransaction::FlushImplicitTransaction();
874     }
875     auto it = pidInfos_.begin();
876     for (; it != pidInfos_.end(); ++it) {
877         if (it->pid == pid) {
878             pidInfos_.erase(it);
879             break;
880         }
881     }
882     if (it != pidInfos_.end()) {
883         if (IsPointerVisible()) {
884             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
885         }
886         UpdatePointerVisible();
887     }
888 }
889 
GetPointerVisible(int32_t pid)890 bool PointerDrawingManager::GetPointerVisible(int32_t pid)
891 {
892     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
893         if (it->pid == pid) {
894             return it->visible;
895         }
896     }
897     return true;
898 }
899 
SetPointerVisible(int32_t pid,bool visible)900 int32_t PointerDrawingManager::SetPointerVisible(int32_t pid, bool visible)
901 {
902     MMI_HILOGI("visible:%{public}s", visible ? "true" : "false");
903     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
904         if (it->pid == pid) {
905             pidInfos_.erase(it);
906             break;
907         }
908     }
909     PidInfo info = { .pid = pid, .visible = visible };
910     pidInfos_.push_back(info);
911     if (pidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
912         pidInfos_.pop_front();
913     }
914     UpdatePointerVisible();
915     return RET_OK;
916 }
917 
SetPointerLocation(int32_t x,int32_t y)918 void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y)
919 {
920     CALL_DEBUG_ENTER;
921     FixCursorPosition(x, y);
922     lastPhysicalX_ = x;
923     lastPhysicalY_ = y;
924     MMI_HILOGD("Pointer window move, x:%{public}d, y:%{public}d", lastPhysicalX_, lastPhysicalY_);
925     if (surfaceNode_ != nullptr) {
926         surfaceNode_->SetBounds(x,
927             y,
928             surfaceNode_->GetStagingProperties().GetBounds().z_,
929             surfaceNode_->GetStagingProperties().GetBounds().w_);
930         Rosen::RSTransaction::FlushImplicitTransaction();
931         MMI_HILOGD("Pointer window move success");
932     }
933 }
934 
UpdateDefaultPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle)935 int32_t PointerDrawingManager::UpdateDefaultPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle)
936 {
937     if (windowId != GLOBAL_WINDOW_ID) {
938         MMI_HILOGD("No need to change the default icon style");
939         return RET_OK;
940     }
941     PointerStyle style;
942     int32_t ret = WinMgr->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
943     if (ret != RET_OK) {
944         MMI_HILOGE("Get global pointer style failed!");
945         return RET_ERR;
946     }
947     if (pointerStyle.id != style.id) {
948         auto it = mouseIcons_.find(MOUSE_ICON(MOUSE_ICON::DEFAULT));
949         if (it == mouseIcons_.end()) {
950             MMI_HILOGE("Cannot find the default style in mouseIcons_");
951             return RET_ERR;
952         }
953         std::string newIconPath;
954         if (pointerStyle.id == MOUSE_ICON::DEFAULT) {
955             newIconPath = DefaultIconPath;
956         } else {
957             newIconPath = mouseIcons_[MOUSE_ICON(pointerStyle.id)].iconPath;
958         }
959         MMI_HILOGD("default path has changed from %{public}s to %{public}s",
960             it->second.iconPath.c_str(), newIconPath.c_str());
961         it->second.iconPath = newIconPath;
962     }
963     std::string name = "pointerColor";
964     ret = PreferencesMgr->SetIntValue(name, MOUSE_FILE_NAME, DEFAULT_VALUE);
965     if (ret != RET_OK) {
966         MMI_HILOGD("Set default color failed");
967         return RET_ERR;
968     }
969     return RET_OK;
970 }
971 
GetMouseIconPath()972 std::map<MOUSE_ICON, IconStyle> PointerDrawingManager::GetMouseIconPath()
973 {
974     CALL_DEBUG_ENTER;
975     return mouseIcons_;
976 }
977 
SetPointerStylePreference(PointerStyle pointerStyle)978 int32_t PointerDrawingManager::SetPointerStylePreference(PointerStyle pointerStyle)
979 {
980     CALL_DEBUG_ENTER;
981     std::string name = "pointerStyle";
982     int32_t ret = PreferencesMgr->SetIntValue(name, MOUSE_FILE_NAME, pointerStyle.id);
983     if (ret == RET_OK) {
984         MMI_HILOGD("Set pointer style successfully, style:%{public}d", pointerStyle.id);
985     }
986     return RET_OK;
987 }
988 
SetPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle)989 int32_t PointerDrawingManager::SetPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle)
990 {
991     CALL_DEBUG_ENTER;
992     if (windowId == GLOBAL_WINDOW_ID) {
993         int32_t ret = SetPointerStylePreference(pointerStyle);
994         if (ret != RET_OK) {
995             MMI_HILOGE("Set style preference is failed, ret:%{public}d", ret);
996             return RET_ERR;
997         }
998     }
999     auto it = mouseIcons_.find(MOUSE_ICON(pointerStyle.id));
1000     if (it == mouseIcons_.end()) {
1001         MMI_HILOGE("The param pointerStyle is invalid");
1002         return RET_ERR;
1003     }
1004     int32_t ret = UpdateDefaultPointerStyle(pid, windowId, pointerStyle);
1005     if (ret != RET_OK) {
1006         MMI_HILOGE("Update default pointer iconPath failed!");
1007         return ret;
1008     }
1009 
1010     ret = WinMgr->SetPointerStyle(pid, windowId, pointerStyle);
1011     if (ret != RET_OK) {
1012         MMI_HILOGE("Set pointer style failed");
1013         return ret;
1014     }
1015 
1016     if (!InputDevMgr->HasPointerDevice()) {
1017         MMI_HILOGD("The pointer device is not exist");
1018         return RET_OK;
1019     }
1020 
1021     if (!WinMgr->IsNeedRefreshLayer(windowId)) {
1022         MMI_HILOGD("Not need refresh layer, window type:%{public}d, pointer style:%{public}d",
1023             windowId, pointerStyle.id);
1024         return RET_OK;
1025     }
1026     if (windowId != GLOBAL_WINDOW_ID && (pointerStyle.id == MOUSE_ICON::DEFAULT &&
1027         mouseIcons_[MOUSE_ICON(pointerStyle.id)].iconPath != DefaultIconPath)) {
1028         PointerStyle style;
1029         int32_t ret = WinMgr->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
1030         if (ret != RET_OK) {
1031             MMI_HILOGE("Get global pointer style failed!");
1032             return RET_ERR;
1033         }
1034         pointerStyle = style;
1035     }
1036     DrawPointerStyle(pointerStyle);
1037     MMI_HILOGI("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle.id);
1038     return RET_OK;
1039 }
1040 
GetPointerStyle(int32_t pid,int32_t windowId,PointerStyle & pointerStyle)1041 int32_t PointerDrawingManager::GetPointerStyle(int32_t pid, int32_t windowId, PointerStyle &pointerStyle)
1042 {
1043     CALL_DEBUG_ENTER;
1044     if (windowId == GLOBAL_WINDOW_ID) {
1045         std::string name = "pointerColor";
1046         pointerStyle.color = PreferencesMgr->GetIntValue(name, DEFAULT_VALUE);
1047         name = "pointerSize";
1048         pointerStyle.size = PreferencesMgr->GetIntValue(name, DEFAULT_POINTER_SIZE);
1049         name = "pointerStyle";
1050         int32_t style = PreferencesMgr->GetIntValue(name, DEFAULT_POINTER_STYLE);
1051         MMI_HILOGD("Get pointer style successfully, pointerStyle:%{public}d", style);
1052         if (style == CURSOR_CIRCLE_STYLE) {
1053             pointerStyle.id = style;
1054             return RET_OK;
1055         }
1056     }
1057     int32_t ret = WinMgr->GetPointerStyle(pid, windowId, pointerStyle);
1058     if (ret != RET_OK) {
1059         MMI_HILOGE("Get pointer style failed, pointerStyleInfo is nullptr");
1060         return ret;
1061     }
1062     MMI_HILOGD("Window id:%{public}d get pointer style:%{public}d success", windowId, pointerStyle.id);
1063     return RET_OK;
1064 }
1065 
ClearWindowPointerStyle(int32_t pid,int32_t windowId)1066 int32_t PointerDrawingManager::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
1067 {
1068     CALL_DEBUG_ENTER;
1069     return WinMgr->ClearWindowPointerStyle(pid, windowId);
1070 }
1071 
DrawPointerStyle(const PointerStyle & pointerStyle)1072 void PointerDrawingManager::DrawPointerStyle(const PointerStyle& pointerStyle)
1073 {
1074     CALL_DEBUG_ENTER;
1075     if (hasDisplay_ && hasPointerDevice_) {
1076         if (surfaceNode_ != nullptr) {
1077             surfaceNode_->AttachToDisplay(screenId_);
1078             Rosen::RSTransaction::FlushImplicitTransaction();
1079         }
1080         Direction direction = DIRECTION0;
1081         if (displayInfo_.displayDirection == DIRECTION0) {
1082             direction = displayInfo_.direction;
1083         }
1084         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
1085             DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
1086                 pointerStyle, direction);
1087             MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1088             return;
1089         }
1090 
1091         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
1092         MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1093     }
1094 }
1095 
CheckMouseIconPath()1096 void PointerDrawingManager::CheckMouseIconPath()
1097 {
1098     for (auto iter = mouseIcons_.begin(); iter != mouseIcons_.end();) {
1099         if ((ReadCursorStyleFile(iter->second.iconPath)) != RET_OK) {
1100             iter = mouseIcons_.erase(iter);
1101             continue;
1102         }
1103         ++iter;
1104     }
1105 }
1106 
InitStyle()1107 void PointerDrawingManager::InitStyle()
1108 {
1109     CALL_DEBUG_ENTER;
1110     mouseIcons_ = {
1111         {DEFAULT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
1112         {EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "East.svg"}},
1113         {WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West.svg"}},
1114         {SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South.svg"}},
1115         {NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North.svg"}},
1116         {WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West_East.svg"}},
1117         {NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_South.svg"}},
1118         {NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East.svg"}},
1119         {NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West.svg"}},
1120         {SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_East.svg"}},
1121         {SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_West.svg"}},
1122         {NORTH_EAST_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East_South_West.svg"}},
1123         {NORTH_WEST_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West_South_East.svg"}},
1124         {CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cross.svg"}},
1125         {CURSOR_COPY, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Copy.svg"}},
1126         {CURSOR_FORBID, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Forbid.svg"}},
1127         {COLOR_SUCKER, {ANGLE_SW, IMAGE_POINTER_DEFAULT_PATH + "Colorsucker.svg"}},
1128         {HAND_GRABBING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Grabbing.svg"}},
1129         {HAND_OPEN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Open.svg"}},
1130         {HAND_POINTING, {ANGLE_NW_RIGHT, IMAGE_POINTER_DEFAULT_PATH + "Hand_Pointing.svg"}},
1131         {HELP, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Help.svg"}},
1132         {CURSOR_MOVE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Move.svg"}},
1133         {RESIZE_LEFT_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Left_Right.svg"}},
1134         {RESIZE_UP_DOWN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Up_Down.svg"}},
1135         {SCREENSHOT_CHOOSE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cross.svg"}},
1136         {SCREENSHOT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cursor.png"}},
1137         {TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Text_Cursor.svg"}},
1138         {ZOOM_IN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_In.svg"}},
1139         {ZOOM_OUT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_Out.svg"}},
1140         {MIDDLE_BTN_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_East.svg"}},
1141         {MIDDLE_BTN_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_West.svg"}},
1142         {MIDDLE_BTN_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South.svg"}},
1143         {MIDDLE_BTN_NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North.svg"}},
1144         {MIDDLE_BTN_NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_South.svg"}},
1145         {MIDDLE_BTN_NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_East.svg"}},
1146         {MIDDLE_BTN_NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_West.svg"}},
1147         {MIDDLE_BTN_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_East.svg"}},
1148         {MIDDLE_BTN_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_West.svg"}},
1149         {MIDDLE_BTN_NORTH_SOUTH_WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH +
1150             "MID_Btn_North_South_West_East.svg"}},
1151         {HORIZONTAL_TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Horizontal_Text_Cursor.svg"}},
1152         {CURSOR_CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Cross.svg"}},
1153         {CURSOR_CIRCLE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png"}},
1154         {LOADING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"}},
1155         {RUNNING, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
1156         {RUNNING_LEFT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
1157         {RUNNING_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg"}},
1158         {DEVELOPER_DEFINED_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
1159     };
1160     CheckMouseIconPath();
1161 }
1162 
RotateDegree(Direction direction)1163 void PointerDrawingManager::RotateDegree(Direction direction)
1164 {
1165     float degree = (static_cast<int>(DIRECTION0) - static_cast<int>(direction)) * ROTATION_ANGLE90;
1166     surfaceNode_->SetPivot(0, 0);
1167     surfaceNode_->SetRotation(degree);
1168 }
1169 } // namespace MMI
1170 } // namespace OHOS
1171