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