• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 #include "table_dump.h"
23 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
24 #include "magic_pointer_drawing_manager.h"
25 #include "magic_pointer_velocity_tracker.h"
26 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
27 
28 #include "define_multimodal.h"
29 #include "event_log_helper.h"
30 #include "i_multimodal_input_connect.h"
31 #include "input_device_manager.h"
32 #include "i_input_windows_manager.h"
33 #include "ipc_skeleton.h"
34 #include "mmi_log.h"
35 #include "i_preference_manager.h"
36 #include "parameters.h"
37 #include "pipeline/rs_recording_canvas.h"
38 #include "preferences.h"
39 #include "preferences_errno.h"
40 #include "preferences_helper.h"
41 #include "render/rs_pixel_map_util.h"
42 #include "scene_board_judgement.h"
43 #include "setting_datashare.h"
44 #include "util.h"
45 #include "timer_manager.h"
46 #include "system_ability_definition.h"
47 
48 #undef MMI_LOG_DOMAIN
49 #define MMI_LOG_DOMAIN MMI_LOG_CURSOR
50 #undef MMI_LOG_TAG
51 #define MMI_LOG_TAG "PointerDrawingManager"
52 
53 namespace OHOS {
54 namespace MMI {
55 namespace {
56 const std::string FOLD_SCREEN_FLAG = system::GetParameter("const.window.foldscreen.type", "");
57 const std::string IMAGE_POINTER_DEFAULT_PATH = "/system/etc/multimodalinput/mouse_icon/";
58 const std::string DefaultIconPath = IMAGE_POINTER_DEFAULT_PATH + "Default.svg";
59 const std::string CursorIconPath = IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png";
60 const std::string POINTER_COLOR { "pointerColor" };
61 const std::string POINTER_SIZE { "pointerSize" };
62 const std::string MAGIC_POINTER_COLOR { "magicPointerColor" };
63 const std::string MAGIC_POINTER_SIZE { "magicPointerSize"};
64 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
65 const std::string FOLDABLE_DEVICE_POLICY = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
66 constexpr int32_t WINDOW_ROTATE { 0 };
67 constexpr char ROTATE_WINDOW_ROTATE { '0' };
68 constexpr int32_t FOLDABLE_DEVICE { 2 };
69 constexpr int32_t BASELINE_DENSITY { 160 };
70 constexpr int32_t CALCULATE_MIDDLE { 2 };
71 constexpr int32_t MAGIC_INDEPENDENT_PIXELS { 30 };
72 constexpr int32_t DEVICE_INDEPENDENT_PIXELS { 40 };
73 constexpr int32_t POINTER_WINDOW_INIT_SIZE { 64 };
74 constexpr int32_t DEFAULT_POINTER_SIZE { 1 };
75 constexpr int32_t MIN_POINTER_SIZE { 1 };
76 constexpr int32_t MAX_POINTER_SIZE { 7 };
77 constexpr int32_t DEFAULT_VALUE { -1 };
78 constexpr int32_t ANIMATION_DURATION { 500 };
79 constexpr int32_t DEFAULT_POINTER_STYLE { 0 };
80 constexpr int32_t CURSOR_CIRCLE_STYLE { 41 };
81 constexpr int32_t MOUSE_ICON_BAIS { 5 };
82 constexpr int32_t VISIBLE_LIST_MAX_SIZE { 100 };
83 constexpr int32_t WAIT_TIME_FOR_MAGIC_CURSOR { 6000 };
84 constexpr float ROTATION_ANGLE { 360.f };
85 constexpr float LOADING_CENTER_RATIO { 0.5f };
86 constexpr float RUNNING_X_RATIO { 0.3f };
87 constexpr float RUNNING_Y_RATIO { 0.675f };
88 constexpr float INCREASE_RATIO { 1.22f };
89 constexpr float ROTATION_ANGLE90 { 90.f };
90 constexpr int32_t MIN_POINTER_COLOR { 0x000000 };
91 constexpr int32_t MAX_POINTER_COLOR { 0xffffff };
92 constexpr int32_t MIN_CURSOR_SIZE { 64 };
93 constexpr uint32_t RGB_CHANNEL_BITS_LENGTH { 24 };
94 constexpr float MAX_ALPHA_VALUE { 255.f };
95 constexpr int32_t MOUSE_STYLE_OPT { 0 };
96 constexpr int32_t MAGIC_STYLE_OPT { 1 };
97 constexpr int32_t MAX_TRY_TIMES { 10 };
98 const std::string MOUSE_FILE_NAME { "mouse_settings.xml" };
99 bool g_isRsRemoteDied { false };
100 constexpr uint64_t FOLD_SCREEN_ID_FULL { 0 };
101 constexpr uint64_t FOLD_SCREEN_ID_MAIN { 5 };
102 constexpr int32_t CANVAS_SIZE { 256 };
103 constexpr float IMAGE_PIXEL { 0.0f };
104 constexpr int32_t QUEUE_SIZE { 5 };
105 constexpr int32_t MAX_CUSTOM_CURSOR_SIZE { 256 };
106 constexpr float MAX_CUSTOM_CURSOR_DIMENSION { 256.0f };
107 const int32_t ERROR_WINDOW_ID_PERMISSION_DENIED = 26500001;
108 std::mutex mutex_;
109 } // namespace
110 } // namespace MMI
111 } // namespace OHOS
112 
113 namespace OHOS {
114 namespace MMI {
115 
IsSingleDisplayFoldDevice()116 static bool IsSingleDisplayFoldDevice()
117 {
118     return (!FOLD_SCREEN_FLAG.empty() && FOLD_SCREEN_FLAG[0] == '1');
119 }
120 
RsRemoteDiedCallback()121 void RsRemoteDiedCallback()
122 {
123     CALL_INFO_TRACE;
124     g_isRsRemoteDied = true;
125     MMI_HILOGI("Death callback for RS");
126 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
127     MAGIC_CURSOR->RsRemoteDiedCallbackForMagicCursor();
128 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
129     IPointerDrawingManager::GetInstance()->DestroyPointerWindow();
130 }
131 
InitPointerCallback()132 void PointerDrawingManager::InitPointerCallback()
133 {
134     MMI_HILOGI("Init RS observer start");
135     g_isRsRemoteDied = false;
136     Rosen::OnRemoteDiedCallback callback = RsRemoteDiedCallback;
137     Rosen::RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
138 }
139 
DestroyPointerWindow()140 void PointerDrawingManager::DestroyPointerWindow()
141 {
142     CALL_INFO_TRACE;
143     CHKPV(delegateProxy_);
144     delegateProxy_->OnPostSyncTask([this] {
145         if (surfaceNode_ != nullptr) {
146             MMI_HILOGI("Pointer window destroy start");
147             g_isRsRemoteDied = false;
148             surfaceNode_->DetachToDisplay(screenId_);
149             surfaceNode_ = nullptr;
150             Rosen::RSTransaction::FlushImplicitTransaction();
151             MMI_HILOGI("Pointer window destroy success");
152         }
153         return RET_OK;
154     });
155 }
156 
PointerDrawingManager()157 PointerDrawingManager::PointerDrawingManager()
158 {
159 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
160     MMI_HILOGI("magiccurosr InitStyle");
161     int32_t counter_ = 0;
162     hasMagicCursor_.name = "isMagicCursor";
163     MAGIC_CURSOR->InitStyle();
164 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
165     InitStyle();
166 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
167     hardwareCursorPointerManager_ = std::make_shared<HardwareCursorPointerManager>();
168 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
169 }
170 
GetLastMouseStyle()171 PointerStyle PointerDrawingManager::GetLastMouseStyle()
172 {
173     CALL_DEBUG_ENTER;
174     return lastMouseStyle_;
175 }
176 
ForceClearPointerVisiableStatus()177 void PointerDrawingManager::ForceClearPointerVisiableStatus()
178 {
179     MMI_HILOGI("force clear all pointer visiable status");
180     pidInfos_.clear();
181     if (!WIN_MGR->HasMouseHideFlag() || INPUT_DEV_MGR->HasPointerDevice() || INPUT_DEV_MGR->HasVirtualPointerDevice()) {
182         UpdatePointerVisible();
183     }
184 }
185 
SetHardWareLocation(int32_t displayId,int32_t physicalX,int32_t physicalY)186 bool PointerDrawingManager::SetHardWareLocation(int32_t displayId, int32_t physicalX, int32_t physicalY)
187 {
188 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
189     CHKPF(hardwareCursorPointerManager_);
190     hardwareCursorPointerManager_->SetTargetDevice(displayId);
191     if (hardwareCursorPointerManager_->IsSupported()) {
192         if (hardwareCursorPointerManager_->SetPosition(physicalX, physicalY) != RET_OK) {
193             MMI_HILOGE("Set hardware cursor position error");
194             return false;
195         }
196     }
197 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
198     return true;
199 }
200 
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY,PointerStyle pointerStyle,Direction direction)201 int32_t PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
202     PointerStyle pointerStyle, Direction direction)
203 {
204     if (surfaceNode_ == nullptr) {
205         return RET_ERR;
206     }
207     MMI_HILOGD("Pointer window move success, pointerStyle id: %{public}d", pointerStyle.id);
208     if (!SetHardWareLocation(displayId, physicalX, physicalY)) {
209         return RET_ERR;
210     }
211 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
212     bool cursorEnlarged = MAGIC_POINTER_VELOCITY_TRACKER->GetCursorEnlargedStatus();
213     if (cursorEnlarged) {
214         MAGIC_POINTER_VELOCITY_TRACKER->SetLastPointerStyle(pointerStyle);
215         MAGIC_POINTER_VELOCITY_TRACKER->SetDirection(direction);
216         if (pointerStyle.id != MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::CROSS) {
217             pointerStyle.id = MOUSE_ICON::DEFAULT;
218         }
219     }
220 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
221     if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) {
222         UpdateSurfaceNodeBounds(physicalX, physicalY);
223         Rosen::RSTransaction::FlushImplicitTransaction();
224         MMI_HILOGD("The lastpointerStyle is equal with pointerStyle, id:%{public}d, size:%{public}d",
225             pointerStyle.id, pointerStyle.size);
226         return RET_OK;
227     }
228     if (lastDirection_ != direction) {
229         RotateDegree(direction);
230         lastDirection_ = direction;
231     }
232     lastMouseStyle_ = pointerStyle;
233     surfaceNode_->SetVisible(false);
234     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
235     if (ret != RET_OK) {
236         mouseIconUpdate_ = false;
237         MMI_HILOGE("Init layer failed");
238         return RET_ERR;
239     }
240     UpdateSurfaceNodeBounds(physicalX, physicalY);
241     surfaceNode_->SetVisible(true);
242     Rosen::RSTransaction::FlushImplicitTransaction();
243     UpdatePointerVisible();
244     mouseIconUpdate_ = false;
245     MMI_HILOGD("Leave, display:%{public}d, physicalX:%{private}d, physicalY:%{private}d",
246         displayId, physicalX, physicalY);
247     return RET_OK;
248 }
249 
UpdateSurfaceNodeBounds(int32_t physicalX,int32_t physicalY)250 void PointerDrawingManager::UpdateSurfaceNodeBounds(int32_t physicalX, int32_t physicalY)
251 {
252 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
253     if (HasMagicCursor()) {
254         if (currentMouseStyle_.id == DEVELOPER_DEFINED_ICON) {
255             surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
256                 canvasWidth_, canvasHeight_);
257         } else {
258             surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
259                 imageWidth_, imageHeight_);
260         }
261     } else {
262         surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
263             surfaceNode_->GetStagingProperties().GetBounds().z_,
264             surfaceNode_->GetStagingProperties().GetBounds().w_);
265     }
266 #else
267     surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
268         surfaceNode_->GetStagingProperties().GetBounds().z_,
269         surfaceNode_->GetStagingProperties().GetBounds().w_);
270 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
271 }
272 
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY)273 void PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY)
274 {
275     CALL_DEBUG_ENTER;
276     if (surfaceNode_ != nullptr) {
277         surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
278             surfaceNode_->GetStagingProperties().GetBounds().z_,
279             surfaceNode_->GetStagingProperties().GetBounds().w_);
280         Rosen::RSTransaction::FlushImplicitTransaction();
281         MMI_HILOGD("Move pointer, physicalX:%d, physicalY:%d", physicalX, physicalY);
282     }
283 }
284 
DrawPointer(int32_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)285 void PointerDrawingManager::DrawPointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
286     const PointerStyle pointerStyle, Direction direction)
287 {
288     CALL_DEBUG_ENTER;
289     MMI_HILOGD("Display:%{public}d, physicalX:%{private}d, physicalY:%{private}d, pointerStyle:%{public}d",
290         displayId, physicalX, physicalY, pointerStyle.id);
291     FixCursorPosition(physicalX, physicalY);
292     lastPhysicalX_ = physicalX;
293     lastPhysicalY_ = physicalY;
294     currentMouseStyle_ = pointerStyle;
295     currentDirection_ = direction;
296     std::map<MOUSE_ICON, IconStyle> iconPath = GetMouseIconPath();
297     if (pointerStyle.id == MOUSE_ICON::DEFAULT && iconPath[MOUSE_ICON(pointerStyle.id)].iconPath == CursorIconPath) {
298         AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(MOUSE_ICON::CURSOR_CIRCLE)].alignmentWay),
299             physicalX, physicalY);
300     } else {
301         AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(pointerStyle.id)].alignmentWay),
302             physicalX, physicalY);
303     }
304     // Log printing only occurs when the mouse style changes
305     if (currentMouseStyle_.id != lastMouseStyle_.id) {
306         MMI_HILOGD("MagicCursor AdjustMouseFocus:%{public}d",
307             ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(pointerStyle.id)].alignmentWay));
308     }
309     if (DrawMovePointer(displayId, physicalX, physicalY, pointerStyle, direction) == RET_OK) {
310         return;
311     }
312 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
313     if (HasMagicCursor() && currentMouseStyle_.id != DEVELOPER_DEFINED_ICON) {
314         MMI_HILOGD("magicCursor DrawPointer enter CreatePointerWindow");
315         MAGIC_CURSOR->CreatePointerWindow(displayId, physicalX, physicalY, direction, surfaceNode_);
316     } else {
317         CreatePointerWindow(displayId, physicalX, physicalY, direction);
318     }
319 #else
320     CreatePointerWindow(displayId, physicalX, physicalY, direction);
321 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
322     CHKPV(surfaceNode_);
323     UpdateMouseStyle();
324     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
325     if (ret != RET_OK) {
326         MMI_HILOGE("Init layer failed");
327         return;
328     }
329     UpdatePointerVisible();
330     MMI_HILOGI("Leave, display:%{public}d, physicalX:%d, physicalY:%d", displayId, physicalX, physicalY);
331 }
332 
UpdateMouseStyle()333 void PointerDrawingManager::UpdateMouseStyle()
334 {
335     CALL_DEBUG_ENTER;
336     PointerStyle curPointerStyle;
337     GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
338     if (curPointerStyle.id == CURSOR_CIRCLE_STYLE) {
339         lastMouseStyle_.id = curPointerStyle.id;
340         int ret = SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
341         if (ret != RET_OK) {
342             MMI_HILOGE("Set pointer style failed");
343         }
344         return;
345     }
346 }
347 
SwitchPointerStyle()348 int32_t PointerDrawingManager::SwitchPointerStyle()
349 {
350     CALL_DEBUG_ENTER;
351     int32_t size = GetPointerSize();
352     if (size < MIN_POINTER_SIZE) {
353         size = MIN_POINTER_SIZE;
354     } else if (size > MAX_POINTER_SIZE) {
355         size = MAX_POINTER_SIZE;
356     }
357     MMI_HILOGD("imageWidth_: %{public}d before", imageWidth_);
358     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
359     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
360     MMI_HILOGD("imageWidth_: %{public}d after", imageWidth_);
361     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
362     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
363 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
364     MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
365 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
366     Direction direction = DIRECTION0;
367     int32_t physicalX = lastPhysicalX_;
368     int32_t physicalY = lastPhysicalY_;
369     AdjustMouseFocus(
370         direction, ICON_TYPE(GetIconStyle(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay), physicalX, physicalY);
371 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
372     if (HasMagicCursor()) {
373         MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
374     } else {
375         CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
376     }
377 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
378     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
379     if (ret != RET_OK) {
380         MMI_HILOGE("Init layer failed");
381         return ret;
382     }
383     UpdatePointerVisible();
384     return RET_OK;
385 }
386 
CreateMagicCursorChangeObserver()387 void PointerDrawingManager::CreateMagicCursorChangeObserver()
388 {
389     // Listening enabling cursor deformation and color inversion
390     SettingObserver::UpdateFunc func = [](const std::string& key) {
391         bool statusValue = false;
392         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
393         if (ret != RET_OK) {
394             MMI_HILOGE("Get value from setting date fail");
395             return;
396         }
397 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
398         MAGIC_CURSOR->UpdateMagicCursorChangeState(statusValue);
399 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
400     };
401     std::string dynamicallyKey = "smartChange";
402     sptr<SettingObserver> magicCursorChangeObserver = SettingDataShare::GetInstance(
403         MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(dynamicallyKey, func);
404     ErrCode ret =
405         SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(magicCursorChangeObserver);
406     if (ret != ERR_OK) {
407         MMI_HILOGE("Register magic cursor change observer failed, ret:%{public}d", ret);
408         magicCursorChangeObserver = nullptr;
409     }
410 }
411 
UpdateStyleOptions()412 void PointerDrawingManager::UpdateStyleOptions()
413 {
414     CALL_DEBUG_ENTER;
415     PointerStyle curPointerStyle;
416     WIN_MGR->GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
417     curPointerStyle.options = HasMagicCursor() ? MAGIC_STYLE_OPT : MOUSE_STYLE_OPT;
418     int ret = WIN_MGR->SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
419     if (ret != RET_OK) {
420         MMI_HILOGE("Set pointer style failed");
421     }
422 }
423 
InitPointerObserver()424 void PointerDrawingManager::InitPointerObserver()
425 {
426     CALL_INFO_TRACE;
427     if (hasInitObserver_) {
428         MMI_HILOGI("Settingdata observer has init");
429         return;
430     }
431 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
432     int32_t ret = CreatePointerSwitchObserver(hasMagicCursor_);
433     if (ret == RET_OK) {
434         hasInitObserver_ = true;
435         MMI_HILOGD("Create pointer switch observer success");
436     }
437 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
438 }
439 
CreatePointerSwitchObserver(isMagicCursor & item)440 int32_t PointerDrawingManager::CreatePointerSwitchObserver(isMagicCursor& item)
441 {
442     CALL_DEBUG_ENTER;
443     SettingObserver::UpdateFunc updateFunc = [this, &item](const std::string& key) {
444         bool statusValue = false;
445         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
446         if (ret != RET_OK) {
447             MMI_HILOGE("Get value from setting date fail");
448             return;
449         }
450         bool tmp = item.isShow;
451         item.isShow = statusValue;
452         this->UpdateStyleOptions();
453         if (item.isShow != tmp) {
454             if (surfaceNode_ == nullptr) {
455                 MMI_HILOGE("surfaceNode_ is nullptr, no need detach");
456                 return;
457             }
458 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
459             MMI_HILOGI("switch pointer style");
460             int64_t nodeId = surfaceNode_->GetId();
461             if (nodeId != MAGIC_CURSOR->GetSurfaceNodeId(nodeId)) {
462                 surfaceNode_->DetachToDisplay(screenId_);
463                 Rosen::RSTransaction::FlushImplicitTransaction();
464             }
465             MAGIC_CURSOR->DetachDisplayNode();
466             this->SwitchPointerStyle();
467 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
468         }
469     };
470     sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(
471         MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(item.name, updateFunc);
472     ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
473     if (ret != ERR_OK) {
474         MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
475         statusObserver = nullptr;
476         return RET_ERR;
477     }
478     CreateMagicCursorChangeObserver();
479     return RET_OK;
480 }
481 
HasMagicCursor()482 bool PointerDrawingManager::HasMagicCursor()
483 {
484 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
485     if (!MAGIC_CURSOR->isExistDefaultStyle) {
486         MMI_HILOGE("MagicCursor default icon file is not exist");
487         return false;
488     }
489 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
490     return hasMagicCursor_.isShow;
491 }
492 
InitLayer(const MOUSE_ICON mouseStyle)493 int32_t PointerDrawingManager::InitLayer(const MOUSE_ICON mouseStyle)
494 {
495 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
496     if (HasMagicCursor() && mouseStyle != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
497         MMI_HILOGD("magiccursor enter MAGIC_CURSOR->Initlayer");
498         return MAGIC_CURSOR->InitLayer(mouseStyle);
499     } else {
500         MMI_HILOGD("magiccursor not enter MAGIC_CURSOR->Initlayer");
501         return DrawCursor(mouseStyle);
502     }
503 #else
504     return DrawCursor(mouseStyle);
505 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
506 }
507 
DrawCursor(const MOUSE_ICON mouseStyle)508 int32_t PointerDrawingManager::DrawCursor(const MOUSE_ICON mouseStyle)
509 {
510     CALL_DEBUG_ENTER;
511     CHKPR(surfaceNode_, RET_ERR);
512     DrawLoadingPointerStyle(mouseStyle);
513     DrawRunningPointerAnimate(mouseStyle);
514     sptr<OHOS::Surface> layer = GetLayer();
515     if (layer == nullptr) {
516         MMI_HILOGE("Init layer is failed, Layer is nullptr");
517         surfaceNode_->DetachToDisplay(screenId_);
518         surfaceNode_ = nullptr;
519         Rosen::RSTransaction::FlushImplicitTransaction();
520         MMI_HILOGE("Pointer window destroy success");
521         return RET_ERR;
522     }
523     if (!isInit_) {
524         layer->SetQueueSize(QUEUE_SIZE);
525         isInit_ = true;
526     }
527     sptr<OHOS::SurfaceBuffer> buffer = GetSurfaceBuffer(layer);
528     if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
529         MMI_HILOGE("Init layer is failed, buffer or virAddr is nullptr");
530         surfaceNode_->DetachToDisplay(screenId_);
531         surfaceNode_ = nullptr;
532         Rosen::RSTransaction::FlushImplicitTransaction();
533         MMI_HILOGE("Pointer window destroy success");
534         return RET_ERR;
535     }
536 
537     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
538     DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), mouseStyle);
539     OHOS::BufferFlushConfig flushConfig = {
540         .damage = {
541             .w = buffer->GetWidth(),
542             .h = buffer->GetHeight(),
543         },
544     };
545     OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
546     if (ret != OHOS::SURFACE_ERROR_OK) {
547         MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
548         return RET_ERR;
549     }
550     MMI_HILOGD("Init layer success");
551     return RET_OK;
552 }
553 
DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)554 void PointerDrawingManager::DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)
555 {
556     CALL_DEBUG_ENTER;
557     CHKPV(surfaceNode_);
558     Rosen::RSAnimationTimingProtocol protocol;
559     if (mouseStyle != MOUSE_ICON::LOADING &&
560         (mouseStyle != MOUSE_ICON::DEFAULT ||
561             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"))) {
562         protocol.SetDuration(0);
563         Rosen::RSNode::Animate(
564             protocol,
565             Rosen::RSAnimationTimingCurve::LINEAR,
566             [this]() {
567                 if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
568                     RotateDegree(DIRECTION0);
569                     return;
570                 }
571                 RotateDegree(currentDirection_);
572             });
573         MMI_HILOGE("current pointer is not loading");
574         Rosen::RSTransaction::FlushImplicitTransaction();
575         return;
576     }
577     float ratio = imageWidth_ * 1.0 / canvasWidth_;
578     surfaceNode_->SetPivot({LOADING_CENTER_RATIO * ratio, LOADING_CENTER_RATIO * ratio});
579     protocol.SetDuration(ANIMATION_DURATION);
580     protocol.SetRepeatCount(DEFAULT_VALUE);
581 
582     // create property animation
583     Rosen::RSNode::Animate(
584         protocol,
585         Rosen::RSAnimationTimingCurve::LINEAR,
586         [this]() { surfaceNode_->SetRotation(ROTATION_ANGLE); });
587 
588     Rosen::RSTransaction::FlushImplicitTransaction();
589 }
590 
ConvertToColorSpace(Media::ColorSpace colorSpace)591 std::shared_ptr<Rosen::Drawing::ColorSpace> PointerDrawingManager::ConvertToColorSpace(
592     Media::ColorSpace colorSpace)
593 {
594     switch (colorSpace) {
595         case Media::ColorSpace::DISPLAY_P3:
596             return Rosen::Drawing::ColorSpace::CreateRGB(
597                 Rosen::Drawing::CMSTransferFuncType::SRGB, Rosen::Drawing::CMSMatrixType::DCIP3);
598         case Media::ColorSpace::LINEAR_SRGB:
599             return Rosen::Drawing::ColorSpace::CreateSRGBLinear();
600         case Media::ColorSpace::SRGB:
601             return Rosen::Drawing::ColorSpace::CreateSRGB();
602         default:
603             return Rosen::Drawing::ColorSpace::CreateSRGB();
604     }
605 }
606 
PixelFormatToColorType(Media::PixelFormat pixelFormat)607 Rosen::Drawing::ColorType PointerDrawingManager::PixelFormatToColorType(Media::PixelFormat pixelFormat)
608 {
609     switch (pixelFormat) {
610         case Media::PixelFormat::RGB_565:
611             return Rosen::Drawing::ColorType::COLORTYPE_RGB_565;
612         case Media::PixelFormat::RGBA_8888:
613             return Rosen::Drawing::ColorType::COLORTYPE_RGBA_8888;
614         case Media::PixelFormat::BGRA_8888:
615             return Rosen::Drawing::ColorType::COLORTYPE_BGRA_8888;
616         case Media::PixelFormat::ALPHA_8:
617             return Rosen::Drawing::ColorType::COLORTYPE_ALPHA_8;
618         case Media::PixelFormat::RGBA_F16:
619             return Rosen::Drawing::ColorType::COLORTYPE_RGBA_F16;
620         case Media::PixelFormat::UNKNOWN:
621         case Media::PixelFormat::ARGB_8888:
622         case Media::PixelFormat::RGB_888:
623         case Media::PixelFormat::NV21:
624         case Media::PixelFormat::NV12:
625         case Media::PixelFormat::CMYK:
626         default:
627             return Rosen::Drawing::ColorType::COLORTYPE_UNKNOWN;
628     }
629 }
630 
AlphaTypeToAlphaType(Media::AlphaType alphaType)631 Rosen::Drawing::AlphaType PointerDrawingManager::AlphaTypeToAlphaType(Media::AlphaType alphaType)
632 {
633     switch (alphaType) {
634         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
635             return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
636         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
637             return Rosen::Drawing::AlphaType::ALPHATYPE_OPAQUE;
638         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
639             return Rosen::Drawing::AlphaType::ALPHATYPE_PREMUL;
640         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
641             return Rosen::Drawing::AlphaType::ALPHATYPE_UNPREMUL;
642         default:
643             return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
644     }
645 }
646 
PixelMapReleaseProc(const void *,void * context)647 static void PixelMapReleaseProc(const void* /* pixels */, void* context)
648 {
649     PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
650     if (ctx != nullptr) {
651         delete ctx;
652     }
653 }
654 
ExtractDrawingImage(std::shared_ptr<Media::PixelMap> pixelMap)655 std::shared_ptr<Rosen::Drawing::Image> PointerDrawingManager::ExtractDrawingImage(
656     std::shared_ptr<Media::PixelMap> pixelMap)
657 {
658     CHKPP(pixelMap);
659     Media::ImageInfo imageInfo;
660     pixelMap->GetImageInfo(imageInfo);
661     Rosen::Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
662         PixelFormatToColorType(imageInfo.pixelFormat),
663         AlphaTypeToAlphaType(imageInfo.alphaType),
664         ConvertToColorSpace(imageInfo.colorSpace) };
665     Rosen::Drawing::Pixmap imagePixmap(drawingImageInfo,
666         reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowBytes());
667     PixelMapReleaseContext* releaseContext = new (std::nothrow) PixelMapReleaseContext(pixelMap);
668     CHKPP(releaseContext);
669     auto image = Rosen::Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
670     if (image == nullptr) {
671         MMI_HILOGE("ExtractDrawingImage image fail");
672         delete releaseContext;
673     }
674     return image;
675 }
676 
DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)677 void PointerDrawingManager::DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)
678 {
679     CALL_DEBUG_ENTER;
680     CHKPV(surfaceNode_);
681     CHKPV(canvasNode_);
682     if (mouseStyle != MOUSE_ICON::RUNNING &&
683         (mouseStyle != MOUSE_ICON::DEFAULT ||
684             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"))) {
685         if (canvasNode_ != nullptr) {
686             canvasNode_->SetVisible(false);
687         }
688         MMI_HILOGE("current pointer is not running");
689         return;
690     }
691     canvasNode_->SetVisible(true);
692     float ratio = imageWidth_ * 1.0 / canvasWidth_;
693     canvasNode_->SetPivot({RUNNING_X_RATIO * ratio, RUNNING_Y_RATIO * ratio});
694     std::shared_ptr<OHOS::Media::PixelMap> pixelmap =
695         DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_RIGHT].iconPath);
696     CHKPV(pixelmap);
697     MMI_HILOGD("Set mouseicon to OHOS system");
698 
699 #ifndef USE_ROSEN_DRAWING
700     auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(CANVAS_SIZE, CANVAS_SIZE));
701     OHOS::Rosen::Drawing::Brush brush;
702     brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
703     canvas->DrawBackground(brush);
704     canvas->DrawPixelMap(pixelmap, 0, 0, SkSamplingOptions(), nullptr);
705 #else
706     Rosen::Drawing::Brush brush;
707     Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
708     Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(src);
709     auto canvas =
710         static_cast<Rosen::ExtendRecordingCanvas *>(canvasNode_->BeginRecording(CANVAS_SIZE, CANVAS_SIZE));
711     OHOS::Rosen::Drawing::Brush brushBackGround;
712     brushBackGround.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
713     canvas->AttachBrush(brush);
714     canvas->DrawBackground(brushBackGround);
715     canvas->DrawPixelMapRect(pixelmap, src, dst, Rosen::Drawing::SamplingOptions());
716     canvas->DetachBrush();
717 #endif // USE_ROSEN_DRAWING
718 
719     canvasNode_->FinishRecording();
720 
721     Rosen::RSAnimationTimingProtocol protocol;
722     protocol.SetDuration(ANIMATION_DURATION);
723     protocol.SetRepeatCount(DEFAULT_VALUE);
724 
725     // create property animation
726     Rosen::RSNode::Animate(
727         protocol,
728         Rosen::RSAnimationTimingCurve::LINEAR,
729         [this]() { canvasNode_->SetRotation(ROTATION_ANGLE); });
730 
731     Rosen::RSTransaction::FlushImplicitTransaction();
732 }
733 
AdjustMouseFocus(Direction direction,ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)734 void PointerDrawingManager::AdjustMouseFocus(Direction direction, ICON_TYPE iconType,
735     int32_t &physicalX, int32_t &physicalY)
736 {
737     CALL_DEBUG_ENTER;
738     switch (direction) {
739         case DIRECTION0: {
740             AdjustMouseFocusByDirection0(iconType, physicalX, physicalY);
741             break;
742         }
743         case DIRECTION90: {
744             AdjustMouseFocusByDirection90(iconType, physicalX, physicalY);
745             break;
746         }
747         case DIRECTION180: {
748             AdjustMouseFocusByDirection180(iconType, physicalX, physicalY);
749             break;
750         }
751         case DIRECTION270: {
752             AdjustMouseFocusByDirection270(iconType, physicalX, physicalY);
753             break;
754         }
755         default: {
756             MMI_HILOGW("direction is invalid,direction:%{public}d", direction);
757             break;
758         }
759     }
760 }
761 
AdjustMouseFocusByDirection0(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)762 void PointerDrawingManager::AdjustMouseFocusByDirection0(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
763 {
764     CALL_DEBUG_ENTER;
765     switch (iconType) {
766         case ANGLE_SW: {
767             physicalY -= imageHeight_;
768             break;
769         }
770         case ANGLE_CENTER: {
771             physicalX -= imageWidth_ / CALCULATE_MIDDLE;
772             physicalY -= imageHeight_ / CALCULATE_MIDDLE;
773             break;
774         }
775         case ANGLE_NW_RIGHT: {
776             physicalX -= MOUSE_ICON_BAIS;
777             [[fallthrough]];
778         }
779         case ANGLE_NW: {
780             if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
781                 physicalX -= userIconHotSpotX_;
782                 physicalY -= userIconHotSpotY_;
783             }
784             break;
785         }
786         default: {
787             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
788             break;
789         }
790     }
791 }
792 
AdjustMouseFocusByDirection90(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)793 void PointerDrawingManager::AdjustMouseFocusByDirection90(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
794 {
795     CALL_DEBUG_ENTER;
796     switch (iconType) {
797         case ANGLE_SW: {
798             physicalY += imageHeight_;
799             break;
800         }
801         case ANGLE_CENTER: {
802             physicalX -= imageWidth_ / CALCULATE_MIDDLE;
803             physicalY += imageHeight_ / CALCULATE_MIDDLE;
804             break;
805         }
806         case ANGLE_NW_RIGHT: {
807             physicalX -= MOUSE_ICON_BAIS;
808             [[fallthrough]];
809         }
810         case ANGLE_NW: {
811             if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
812                 physicalX -= userIconHotSpotX_;
813                 physicalY += userIconHotSpotY_;
814             }
815             break;
816         }
817         default: {
818             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
819             break;
820         }
821     }
822 }
823 
AdjustMouseFocusByDirection180(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)824 void PointerDrawingManager::AdjustMouseFocusByDirection180(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
825 {
826     CALL_DEBUG_ENTER;
827     switch (iconType) {
828         case ANGLE_SW: {
829             physicalY += imageHeight_;
830             break;
831         }
832         case ANGLE_CENTER: {
833             physicalX += imageWidth_ / CALCULATE_MIDDLE;
834             physicalY += imageHeight_ / CALCULATE_MIDDLE;
835             break;
836         }
837         case ANGLE_NW_RIGHT: {
838             physicalX += MOUSE_ICON_BAIS;
839             [[fallthrough]];
840         }
841         case ANGLE_NW: {
842             if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
843                 physicalX += userIconHotSpotX_;
844                 physicalY += userIconHotSpotY_;
845             }
846             break;
847         }
848         default: {
849             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
850             break;
851         }
852     }
853 }
854 
AdjustMouseFocusByDirection270(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)855 void PointerDrawingManager::AdjustMouseFocusByDirection270(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
856 {
857     CALL_DEBUG_ENTER;
858     switch (iconType) {
859         case ANGLE_SW: {
860             physicalY -= imageHeight_;
861             break;
862         }
863         case ANGLE_CENTER: {
864             physicalX += imageWidth_ / CALCULATE_MIDDLE;
865             physicalY -= imageHeight_ / CALCULATE_MIDDLE;
866             break;
867         }
868         case ANGLE_NW_RIGHT: {
869             physicalX += MOUSE_ICON_BAIS;
870             [[fallthrough]];
871         }
872         case ANGLE_NW: {
873             if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
874                 physicalX += userIconHotSpotX_;
875                 physicalY -= userIconHotSpotY_;
876             }
877             break;
878         }
879         default: {
880             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
881             break;
882         }
883     }
884 }
885 
SetMouseDisplayState(bool state)886 void PointerDrawingManager::SetMouseDisplayState(bool state)
887 {
888     CALL_DEBUG_ENTER;
889     if (mouseDisplayState_ != state) {
890         mouseDisplayState_ = state;
891         if (mouseDisplayState_) {
892             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
893         }
894         MMI_HILOGI("state:%{public}s", state ? "true" : "false");
895         UpdatePointerVisible();
896     }
897 }
898 
GetMouseDisplayState() const899 bool PointerDrawingManager::GetMouseDisplayState() const
900 {
901     return mouseDisplayState_;
902 }
903 
IsWindowRotation()904 bool PointerDrawingManager::IsWindowRotation()
905 {
906     MMI_HILOGD("ROTATE_POLICY: %{public}d, FOLDABLE_DEVICE_POLICY:%{public}s",
907         ROTATE_POLICY, FOLDABLE_DEVICE_POLICY.c_str());
908     return (ROTATE_POLICY == WINDOW_ROTATE ||
909         (ROTATE_POLICY == FOLDABLE_DEVICE &&
910         ((displayInfo_.displayMode == DisplayMode::MAIN &&
911         FOLDABLE_DEVICE_POLICY[0] == ROTATE_WINDOW_ROTATE) ||
912         (displayInfo_.displayMode == DisplayMode::FULL &&
913         FOLDABLE_DEVICE_POLICY[FOLDABLE_DEVICE] == ROTATE_WINDOW_ROTATE))));
914 }
915 
FixCursorPosition(int32_t & physicalX,int32_t & physicalY)916 void PointerDrawingManager::FixCursorPosition(int32_t &physicalX, int32_t &physicalY)
917 {
918     if (physicalX < 0) {
919         physicalX = 0;
920     }
921 
922     if (physicalY < 0) {
923         physicalY = 0;
924     }
925     const int32_t cursorUnit = 16;
926     if (IsWindowRotation()) {
927         if (displayInfo_.direction == DIRECTION0 || displayInfo_.direction == DIRECTION180) {
928             if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
929                 physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
930             }
931             if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
932                 physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
933             }
934         } else {
935             if (physicalX > (displayInfo_.height - imageHeight_ / cursorUnit)) {
936                 physicalX = displayInfo_.height - imageHeight_ / cursorUnit;
937             }
938             if (physicalY > (displayInfo_.width - imageWidth_ / cursorUnit)) {
939                 physicalY = displayInfo_.width - imageWidth_ / cursorUnit;
940             }
941         }
942     } else {
943         if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
944             physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
945         }
946         if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
947             physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
948         }
949     }
950 }
951 
AttachToDisplay()952 void PointerDrawingManager::AttachToDisplay()
953 {
954     CALL_DEBUG_ENTER;
955     CHKPV(surfaceNode_);
956     if (IsSingleDisplayFoldDevice() && (WIN_MGR->GetDisplayMode() == DisplayMode::MAIN)
957         && (screenId_ == FOLD_SCREEN_ID_FULL)) {
958         screenId_ = FOLD_SCREEN_ID_MAIN;
959     }
960     MMI_HILOGI("screenId_: %{public}" PRIu64"", screenId_);
961     surfaceNode_->AttachToDisplay(screenId_);
962 }
963 
CreatePointerWindow(int32_t displayId,int32_t physicalX,int32_t physicalY,Direction direction)964 void PointerDrawingManager::CreatePointerWindow(int32_t displayId, int32_t physicalX, int32_t physicalY,
965     Direction direction)
966 {
967     CALL_DEBUG_ENTER;
968     CALL_INFO_TRACE;
969     std::lock_guard<std::mutex> guard(mutex_);
970     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
971     surfaceNodeConfig.SurfaceNodeName = "pointer window";
972     Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
973     surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
974     CHKPV(surfaceNode_);
975     surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
976     surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
977     surfaceNode_->SetBounds(physicalX, physicalY, canvasWidth_, canvasHeight_);
978 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
979     CHKPV(hardwareCursorPointerManager_);
980     hardwareCursorPointerManager_->SetTargetDevice(displayId);
981     if (hardwareCursorPointerManager_->IsSupported()) {
982         if (hardwareCursorPointerManager_->SetPosition(physicalX, physicalY) != RET_OK) {
983             MMI_HILOGE("Set hardware cursor position error");
984             return;
985         }
986     }
987 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
988 #ifndef USE_ROSEN_DRAWING
989     surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
990 #else
991     surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
992 #endif
993 
994     screenId_ = static_cast<uint64_t>(displayId);
995     std::cout << "ScreenId: " << screenId_ << std::endl;
996     AttachToDisplay();
997     RotateDegree(direction);
998     lastDirection_ = direction;
999 
1000     canvasNode_ = Rosen::RSCanvasNode::Create();
1001     canvasNode_->SetBounds(0, 0, canvasWidth_, canvasHeight_);
1002     canvasNode_->SetFrame(0, 0, canvasWidth_, canvasHeight_);
1003 #ifndef USE_ROSEN_DRAWING
1004     canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1005 #else
1006     canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1007 #endif
1008     canvasNode_->SetCornerRadius(1);
1009     canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1010     canvasNode_->SetRotation(0);
1011     surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
1012     Rosen::RSTransaction::FlushImplicitTransaction();
1013 }
1014 
GetLayer()1015 sptr<OHOS::Surface> PointerDrawingManager::GetLayer()
1016 {
1017     CALL_DEBUG_ENTER;
1018     CHKPP(surfaceNode_);
1019     return surfaceNode_->GetSurface();
1020 }
1021 
GetSurfaceBuffer(sptr<OHOS::Surface> layer) const1022 sptr<OHOS::SurfaceBuffer> PointerDrawingManager::GetSurfaceBuffer(sptr<OHOS::Surface> layer) const
1023 {
1024     CALL_DEBUG_ENTER;
1025     sptr<OHOS::SurfaceBuffer> buffer;
1026     int32_t releaseFence = -1;
1027     OHOS::BufferRequestConfig config = {
1028         .width = canvasWidth_,
1029         .height = canvasHeight_,
1030         .strideAlignment = 0x8,
1031         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
1032         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
1033         .timeout = 100,
1034     };
1035 
1036     OHOS::SurfaceError ret = layer->RequestBuffer(buffer, releaseFence, config);
1037     close(releaseFence);
1038     if (ret != OHOS::SURFACE_ERROR_OK) {
1039         MMI_HILOGE("Request buffer ret:%{public}s", SurfaceErrorStr(ret).c_str());
1040         return nullptr;
1041     }
1042     return buffer;
1043 }
1044 
DrawImage(OHOS::Rosen::Drawing::Canvas & canvas,MOUSE_ICON mouseStyle)1045 void PointerDrawingManager::DrawImage(OHOS::Rosen::Drawing::Canvas &canvas, MOUSE_ICON mouseStyle)
1046 {
1047     MMI_HILOGI("Draw mouse icon of style(%{public}d)", static_cast<int32_t>(mouseStyle));
1048     OHOS::Rosen::Drawing::Pen pen;
1049     pen.SetAntiAlias(true);
1050     pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1051     OHOS::Rosen::Drawing::scalar penWidth = 1;
1052     pen.SetWidth(penWidth);
1053     canvas.AttachPen(pen);
1054     std::shared_ptr<Rosen::Drawing::Image> image;
1055     std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1056     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1057         MMI_HILOGD("Set mouseicon by userIcon_");
1058         auto userIconCopy = GetUserIconCopy();
1059         image = ExtractDrawingImage(userIconCopy);
1060 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1061         SetPixelMap(userIconCopy);
1062 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1063     } else {
1064         if (mouseStyle == MOUSE_ICON::RUNNING) {
1065             pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1066         } else {
1067             pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1068         }
1069         CHKPV(pixelmap);
1070         image = ExtractDrawingImage(pixelmap);
1071 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1072         if ((mouseStyle == MOUSE_ICON::DEFAULT) || (mouseStyle == MOUSE_ICON::CURSOR_CIRCLE)) {
1073             SetPixelMap(pixelmap);
1074         }
1075 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1076         MMI_HILOGI("Set mouseicon to system");
1077     }
1078     CHKPV(image);
1079     OHOS::Rosen::Drawing::Brush brush;
1080     brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1081     canvas.DrawBackground(brush);
1082     canvas.DrawImage(*image, IMAGE_PIXEL, IMAGE_PIXEL, Rosen::Drawing::SamplingOptions());
1083     MMI_HILOGD("Canvas draw image, success");
1084 }
1085 
1086 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)1087 void PointerDrawingManager::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
1088 {
1089     MMI_HILOGI("Set pointer snapshot");
1090     pixelMap_ = pixelMap;
1091 }
1092 
GetPointerSnapshot(void * pixelMapPtr)1093 int32_t PointerDrawingManager::GetPointerSnapshot(void *pixelMapPtr)
1094 {
1095     CALL_DEBUG_ENTER;
1096     std::shared_ptr<Media::PixelMap> *newPixelMapPtr = static_cast<std::shared_ptr<Media::PixelMap> *>(pixelMapPtr);
1097     MMI_HILOGI("Get pointer snapshot");
1098     *newPixelMapPtr = pixelMap_;
1099     if (HasMagicCursor()) {
1100         MMI_HILOGE("magic pixelmap");
1101         *newPixelMapPtr = MAGIC_CURSOR->GetPixelMap();
1102     }
1103     CHKPR(*newPixelMapPtr, ERROR_NULL_POINTER);
1104     return RET_OK;
1105 }
1106 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1107 
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,const MOUSE_ICON mouseStyle)1108 void PointerDrawingManager::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const MOUSE_ICON mouseStyle)
1109 {
1110     CALL_DEBUG_ENTER;
1111     OHOS::Rosen::Drawing::Bitmap bitmap;
1112     OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
1113         OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
1114     bitmap.Build(width, height, format);
1115     OHOS::Rosen::Drawing::Canvas canvas(CANVAS_SIZE, CANVAS_SIZE);
1116     canvas.Bind(bitmap);
1117     canvas.Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
1118     DrawImage(canvas, mouseStyle);
1119     static constexpr uint32_t stride = 4;
1120     uint32_t addrSize = width * height * stride;
1121     errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
1122     if (ret != EOK) {
1123         MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
1124         return;
1125     }
1126 }
1127 
DrawPixelmap(OHOS::Rosen::Drawing::Canvas & canvas,const MOUSE_ICON mouseStyle)1128 void PointerDrawingManager::DrawPixelmap(OHOS::Rosen::Drawing::Canvas &canvas, const MOUSE_ICON mouseStyle)
1129 {
1130     CALL_DEBUG_ENTER;
1131     OHOS::Rosen::Drawing::Pen pen;
1132     pen.SetAntiAlias(true);
1133     pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1134     OHOS::Rosen::Drawing::scalar penWidth = 1;
1135     pen.SetWidth(penWidth);
1136     canvas.AttachPen(pen);
1137     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1138         MMI_HILOGD("set mouseicon by userIcon_");
1139         auto userIconCopy = GetUserIconCopy();
1140         CHKPV(userIconCopy);
1141         OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *userIconCopy, 0, 0);
1142     } else {
1143         std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1144         if (mouseStyle == MOUSE_ICON::RUNNING) {
1145             pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1146         } else {
1147             pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1148         }
1149         CHKPV(pixelmap);
1150         MMI_HILOGD("Set mouseicon to OHOS system");
1151         OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *pixelmap, 0, 0);
1152     }
1153 }
1154 
SetCustomCursor(void * pixelMap,int32_t pid,int32_t windowId,int32_t focusX,int32_t focusY)1155 int32_t PointerDrawingManager::SetCustomCursor(void* pixelMap, int32_t pid, int32_t windowId, int32_t focusX,
1156     int32_t focusY)
1157 {
1158     CALL_DEBUG_ENTER;
1159     followSystem_ = false;
1160     CHKPR(pixelMap, RET_ERR);
1161     if (pid == -1) {
1162         MMI_HILOGE("pid is invalid");
1163         return RET_ERR;
1164     }
1165     if (windowId < 0) {
1166         MMI_HILOGE("windowId is invalid, windowId:%{public}d", windowId);
1167         return RET_ERR;
1168     }
1169     if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1170         MMI_HILOGE("windowId not in right pid");
1171         return RET_ERR;
1172     }
1173     int32_t ret = UpdateCursorProperty(pixelMap, focusX, focusY);
1174     if (ret != RET_OK) {
1175         MMI_HILOGE("UpdateCursorProperty is failed");
1176         return ret;
1177     }
1178     mouseIconUpdate_ = true;
1179     PointerStyle style;
1180     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1181     lastMouseStyle_ = style;
1182 
1183     ret = SetPointerStyle(pid, windowId, style);
1184     if (ret == RET_ERR) {
1185         MMI_HILOGE("SetPointerStyle is failed");
1186     }
1187     MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
1188         style.id, userIconHotSpotX_, userIconHotSpotY_);
1189     return ret;
1190 }
1191 
UpdateCursorProperty(void * pixelMap,const int32_t & focusX,const int32_t & focusY)1192 int32_t PointerDrawingManager::UpdateCursorProperty(void* pixelMap, const int32_t &focusX, const int32_t &focusY)
1193 {
1194     CHKPR(pixelMap, RET_ERR);
1195     Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(pixelMap);
1196     CHKPR(newPixelMap, RET_ERR);
1197     Media::ImageInfo imageInfo;
1198     newPixelMap->GetImageInfo(imageInfo);
1199     int32_t cursorSize = GetPointerSize();
1200     int32_t cursorWidth =
1201         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1202     int32_t cursorHeight =
1203         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1204     cursorWidth = cursorWidth < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorWidth;
1205     cursorHeight = cursorHeight < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorHeight;
1206     float xAxis = (float)cursorWidth / (float)imageInfo.size.width;
1207     float yAxis = (float)cursorHeight / (float)imageInfo.size.height;
1208     newPixelMap->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
1209     userIcon_.reset(newPixelMap);
1210     userIconHotSpotX_ = static_cast<int32_t>((float)focusX * xAxis);
1211     userIconHotSpotY_ = static_cast<int32_t>((float)focusY * yAxis);
1212     if (EventLogHelper::IsBetaVersion()) {
1213         MMI_HILOGI("cursorWidth:%{private}d, cursorHeight:%{private}d, imageWidth:%{public}d, imageHeight:%{public}d,"
1214             "focusX:%{private}d, focuxY:%{private}d, xAxis:%{public}f, yAxis:%{public}f, userIconHotSpotX_:%{private}d,"
1215             "userIconHotSpotY_:%{private}d", cursorWidth, cursorHeight, imageInfo.size.width, imageInfo.size.height,
1216             focusX, focusY, xAxis, yAxis, userIconHotSpotX_, userIconHotSpotY_);
1217     }
1218     return RET_OK;
1219 }
1220 
SetMouseIcon(int32_t pid,int32_t windowId,void * pixelMap)1221 int32_t PointerDrawingManager::SetMouseIcon(int32_t pid, int32_t windowId, void* pixelMap)
1222     __attribute__((no_sanitize("cfi")))
1223 {
1224     CALL_DEBUG_ENTER;
1225     if (pid == -1) {
1226         MMI_HILOGE("pid is invalid return -1");
1227         return RET_ERR;
1228     }
1229     CHKPR(pixelMap, RET_ERR);
1230     if (windowId < 0) {
1231         MMI_HILOGE("get invalid windowId, %{public}d", windowId);
1232         return RET_ERR;
1233     }
1234     if (!WIN_MGR->CheckPidInSession(pid)) {
1235         MMI_HILOGE("The pid not exists in current session");
1236         return RET_ERR;
1237     }
1238     OHOS::Media::PixelMap* pixelMapPtr = static_cast<OHOS::Media::PixelMap*>(pixelMap);
1239     userIcon_.reset(pixelMapPtr);
1240     mouseIconUpdate_ = true;
1241     PointerStyle style;
1242     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1243     int32_t ret = SetPointerStyle(pid, windowId, style);
1244     if (ret == RET_ERR) {
1245         MMI_HILOGE("SetPointerStyle return RET_ERR here");
1246     }
1247     return ret;
1248 }
1249 
SetMouseHotSpot(int32_t pid,int32_t windowId,int32_t hotSpotX,int32_t hotSpotY)1250 int32_t PointerDrawingManager::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
1251 {
1252     CALL_DEBUG_ENTER;
1253     if (pid == -1) {
1254         MMI_HILOGE("pid is invalid return -1");
1255         return RET_ERR;
1256     }
1257     if (windowId < 0) {
1258         MMI_HILOGE("invalid windowId, %{public}d", windowId);
1259         return RET_ERR;
1260     }
1261     if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1262         MMI_HILOGE("windowId not in right pid");
1263         return RET_ERR;
1264     }
1265     auto userIconCopy = GetUserIconCopy();
1266     if (hotSpotX < 0 || hotSpotY < 0 || userIconCopy == nullptr) {
1267         MMI_HILOGE("invalid value");
1268         return RET_ERR;
1269     }
1270     PointerStyle pointerStyle;
1271     WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle);
1272     if (pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1273         MMI_HILOGE("Get pointer style failed, pid %{publid}d, pointerStyle %{public}d", pid, pointerStyle.id);
1274         return RET_ERR;
1275     }
1276     userIconHotSpotX_ = hotSpotX;
1277     userIconHotSpotY_ = hotSpotY;
1278     return RET_OK;
1279 }
1280 
DecodeImageToPixelMap(const std::string & imagePath)1281 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::DecodeImageToPixelMap(const std::string &imagePath)
1282 {
1283     CALL_DEBUG_ENTER;
1284     OHOS::Media::SourceOptions opts;
1285     uint32_t ret = 0;
1286     auto imageSource = OHOS::Media::ImageSource::CreateImageSource(imagePath, opts, ret);
1287     CHKPP(imageSource);
1288     std::set<std::string> formats;
1289     ret = imageSource->GetSupportedFormats(formats);
1290     MMI_HILOGD("Get supported format ret:%{public}u", ret);
1291 
1292     OHOS::Media::DecodeOptions decodeOpts;
1293     decodeOpts.desiredSize = {
1294         .width = imageWidth_,
1295         .height = imageHeight_
1296     };
1297     int32_t pointerColor = GetPointerColor();
1298     if (tempPointerColor_ != DEFAULT_VALUE) {
1299         decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
1300         if (pointerColor == MAX_POINTER_COLOR) {
1301             decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MIN_POINTER_COLOR};
1302         } else {
1303             decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MAX_POINTER_COLOR};
1304         }
1305     }
1306 
1307     std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, ret);
1308     CHKPL(pixelMap);
1309     return pixelMap;
1310 }
1311 
GetPreferenceKey(std::string & name)1312 void PointerDrawingManager::GetPreferenceKey(std::string &name)
1313 {
1314 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1315     if (HasMagicCursor()) {
1316         if (name == POINTER_COLOR) {
1317             name = MAGIC_POINTER_COLOR;
1318         } else if (name == POINTER_SIZE) {
1319             name = MAGIC_POINTER_SIZE;
1320         }
1321     }
1322 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1323 }
1324 
SetPointerColor(int32_t color)1325 int32_t PointerDrawingManager::SetPointerColor(int32_t color)
1326 {
1327     CALL_DEBUG_ENTER;
1328     if (surfaceNode_ != nullptr) {
1329         float alphaRatio = (static_cast<uint32_t>(color) >> RGB_CHANNEL_BITS_LENGTH) / MAX_ALPHA_VALUE;
1330         if (alphaRatio > 1) {
1331             MMI_HILOGW("Invalid alphaRatio:%{public}f", alphaRatio);
1332         } else {
1333             surfaceNode_->SetAlpha(1 - alphaRatio);
1334         }
1335     }
1336     MMI_HILOGI("PointerColor:%{public}x", color);
1337     // ARGB从表面看比RGB多了个A,也是一种色彩模式,是在RGB的基础上添加了Alpha(透明度)通道。
1338     // 透明度也是以0到255表示的,所以也是总共有256级,透明是0,不透明是255。
1339     // 这个color每8位代表一个通道值,分别是alpha和rgb,总共32位。
1340     color = static_cast<int32_t>(static_cast<uint32_t>(color) & static_cast<uint32_t>(MAX_POINTER_COLOR));
1341     std::string name = POINTER_COLOR;
1342     GetPreferenceKey(name);
1343     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, color);
1344     if (ret != RET_OK) {
1345         MMI_HILOGE("Set pointer color failed, color:%{public}d", color);
1346         return ret;
1347     }
1348     MMI_HILOGD("Set pointer color successfully, color:%{public}d", color);
1349 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1350     if (HasMagicCursor()) {
1351         ret = MAGIC_CURSOR->SetPointerColor(color);
1352     } else {
1353         ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1354     }
1355 #else
1356     ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1357 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1358     if (ret != RET_OK) {
1359         MMI_HILOGE("Init layer failed");
1360         return RET_ERR;
1361     }
1362     UpdatePointerVisible();
1363     return RET_OK;
1364 }
1365 
GetPointerColor()1366 int32_t PointerDrawingManager::GetPointerColor()
1367 {
1368     CALL_DEBUG_ENTER;
1369     std::string name = POINTER_COLOR;
1370     GetPreferenceKey(name);
1371     int32_t pointerColor = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
1372     tempPointerColor_ = pointerColor;
1373     if (pointerColor == DEFAULT_VALUE) {
1374         pointerColor = MIN_POINTER_COLOR;
1375     }
1376     MMI_HILOGD("Get pointer color successfully, pointerColor:%{public}d", pointerColor);
1377     return pointerColor;
1378 }
1379 
UpdateDisplayInfo(const DisplayInfo & displayInfo)1380 void PointerDrawingManager::UpdateDisplayInfo(const DisplayInfo &displayInfo)
1381 {
1382     CALL_DEBUG_ENTER;
1383 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1384     CHKPV(hardwareCursorPointerManager_);
1385     hardwareCursorPointerManager_->SetTargetDevice(displayInfo.id);
1386 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1387     hasDisplay_ = true;
1388     displayInfo_ = displayInfo;
1389     int32_t size = GetPointerSize();
1390     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1391     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1392     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1393     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1394 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1395     MAGIC_CURSOR->SetDisplayInfo(displayInfo);
1396 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1397 }
1398 
GetIndependentPixels()1399 int32_t PointerDrawingManager::GetIndependentPixels()
1400 {
1401     CALL_DEBUG_ENTER;
1402 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1403     if (HasMagicCursor()) {
1404         return MAGIC_INDEPENDENT_PIXELS;
1405     } else {
1406         return DEVICE_INDEPENDENT_PIXELS;
1407     }
1408 #else
1409     return DEVICE_INDEPENDENT_PIXELS;
1410 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1411 }
1412 
SetPointerSize(int32_t size)1413 int32_t PointerDrawingManager::SetPointerSize(int32_t size)
1414 {
1415     CALL_DEBUG_ENTER;
1416     if (size < MIN_POINTER_SIZE) {
1417         size = MIN_POINTER_SIZE;
1418     } else if (size > MAX_POINTER_SIZE) {
1419         size = MAX_POINTER_SIZE;
1420     }
1421     std::string name = POINTER_SIZE;
1422     GetPreferenceKey(name);
1423     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, size);
1424     if (ret != RET_OK) {
1425         MMI_HILOGD("Set pointer size failed, code:%{public}d", ret);
1426         return ret;
1427     }
1428     MMI_HILOGD("Set pointer size successfully, size:%{public}d", size);
1429 
1430     if (surfaceNode_ == nullptr) {
1431         MMI_HILOGI("surfaceNode_ is nullptr");
1432         return RET_OK;
1433     }
1434     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1435     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1436     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1437     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1438     int32_t physicalX = lastPhysicalX_;
1439     int32_t physicalY = lastPhysicalY_;
1440 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1441     MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
1442 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1443     Direction direction = DIRECTION0;
1444     if (IsWindowRotation()) {
1445         direction = displayInfo_.direction;
1446     }
1447     AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay),
1448         physicalX, physicalY);
1449 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1450     if (HasMagicCursor()) {
1451         MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
1452     } else {
1453         CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
1454     }
1455 #else
1456     CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
1457 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1458     if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
1459         MMI_HILOGE("Init layer failed");
1460         return RET_ERR;
1461     }
1462     UpdatePointerVisible();
1463     return RET_OK;
1464 }
1465 
GetPointerSize()1466 int32_t PointerDrawingManager::GetPointerSize()
1467 {
1468     CALL_DEBUG_ENTER;
1469     std::string name = POINTER_SIZE;
1470     GetPreferenceKey(name);
1471     int32_t pointerSize = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
1472     MMI_HILOGD("Get pointer size successfully, pointerSize:%{public}d", pointerSize);
1473     return pointerSize;
1474 }
1475 
GetCursorSurfaceId(uint64_t & surfaceId)1476 int32_t PointerDrawingManager::GetCursorSurfaceId(uint64_t &surfaceId)
1477 {
1478     surfaceId = (surfaceNode_ != nullptr ? surfaceNode_->GetId() : Rosen::INVALID_NODEID);
1479     MMI_HILOGI("CursorSurfaceId:%{public}" PRIu64, surfaceId);
1480     return RET_OK;
1481 }
1482 
OnDisplayInfo(const DisplayGroupInfo & displayGroupInfo)1483 void PointerDrawingManager::OnDisplayInfo(const DisplayGroupInfo &displayGroupInfo)
1484 {
1485     CALL_DEBUG_ENTER;
1486     for (const auto& item : displayGroupInfo.displaysInfo) {
1487         if (item.id == displayInfo_.id) {
1488             UpdateDisplayInfo(item);
1489             DrawManager();
1490             return;
1491         }
1492     }
1493     UpdateDisplayInfo(displayGroupInfo.displaysInfo[0]);
1494     lastPhysicalX_ = displayGroupInfo.displaysInfo[0].width / CALCULATE_MIDDLE;
1495     lastPhysicalY_ = displayGroupInfo.displaysInfo[0].height / CALCULATE_MIDDLE;
1496     MouseEventHdr->OnDisplayLost(displayInfo_.id);
1497     if (surfaceNode_ != nullptr) {
1498         surfaceNode_->DetachToDisplay(screenId_);
1499         surfaceNode_ = nullptr;
1500         Rosen::RSTransaction::FlushImplicitTransaction();
1501         MMI_HILOGD("Pointer window destroy success");
1502     }
1503     MMI_HILOGD("displayId_:%{public}d, displayWidth_:%{public}d, displayHeight_:%{public}d",
1504         displayInfo_.id, displayInfo_.width, displayInfo_.height);
1505 }
1506 
OnWindowInfo(const WinInfo & info)1507 void PointerDrawingManager::OnWindowInfo(const WinInfo &info)
1508 {
1509     CALL_DEBUG_ENTER;
1510     if (pid_ != info.windowPid) {
1511         windowId_ = info.windowId;
1512         pid_ = info.windowPid;
1513         UpdatePointerVisible();
1514     }
1515 }
1516 
UpdatePointerDevice(bool hasPointerDevice,bool isPointerVisible,bool isHotPlug)1517 void PointerDrawingManager::UpdatePointerDevice(bool hasPointerDevice, bool isPointerVisible,
1518     bool isHotPlug)
1519 {
1520     CALL_DEBUG_ENTER;
1521     MMI_HILOGD("hasPointerDevice:%{public}s, isPointerVisible:%{public}s",
1522         hasPointerDevice ? "true" : "false", isPointerVisible? "true" : "false");
1523     hasPointerDevice_ = hasPointerDevice;
1524     if (hasPointerDevice_) {
1525         bool pointerVisible = isPointerVisible;
1526         if (!isHotPlug) {
1527             pointerVisible = (pointerVisible && IsPointerVisible());
1528         }
1529         SetPointerVisible(getpid(), pointerVisible, 0, false);
1530     } else {
1531         DeletePointerVisible(getpid());
1532     }
1533     DrawManager();
1534     if (!hasPointerDevice_ && surfaceNode_ != nullptr) {
1535         MMI_HILOGD("Pointer window destroy start");
1536         surfaceNode_->DetachToDisplay(screenId_);
1537         surfaceNode_ = nullptr;
1538         Rosen::RSTransaction::FlushImplicitTransaction();
1539         MMI_HILOGD("Pointer window destroy success");
1540     }
1541 }
1542 
DrawManager()1543 void PointerDrawingManager::DrawManager()
1544 {
1545     CALL_DEBUG_ENTER;
1546 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1547     if (HasMagicCursor() && lastDrawPointerStyle_.id != currentMouseStyle_.id) {
1548         if (surfaceNode_ != nullptr) {
1549             surfaceNode_->DetachToDisplay(screenId_);
1550             surfaceNode_ = nullptr;
1551             Rosen::RSTransaction::FlushImplicitTransaction();
1552         }
1553     }
1554 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1555     if (hasDisplay_ && hasPointerDevice_ && surfaceNode_ == nullptr) {
1556         MMI_HILOGD("Draw pointer begin");
1557         PointerStyle pointerStyle;
1558         WIN_MGR->GetPointerStyle(pid_, windowId_, pointerStyle);
1559         MMI_HILOGD("get pid %{publid}d with pointerStyle %{public}d", pid_, pointerStyle.id);
1560         Direction direction = DIRECTION0;
1561         if (IsWindowRotation()) {
1562             direction = displayInfo_.direction;
1563         }
1564         lastDrawPointerStyle_ = pointerStyle;
1565         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
1566             DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
1567                 pointerStyle, direction);
1568             MMI_HILOGD("Draw manager, mouseStyle:%{public}d, last physical is initial value", pointerStyle.id);
1569             return;
1570         }
1571         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
1572         MMI_HILOGD("Draw manager, mouseStyle:%{public}d", pointerStyle.id);
1573         return;
1574     }
1575 }
1576 
Init()1577 bool PointerDrawingManager::Init()
1578 {
1579     CALL_DEBUG_ENTER;
1580     INPUT_DEV_MGR->Attach(shared_from_this());
1581     pidInfos_.clear();
1582     hapPidInfos_.clear();
1583     return true;
1584 }
1585 
GetInstance()1586 std::shared_ptr<IPointerDrawingManager> IPointerDrawingManager::GetInstance()
1587 {
1588     if (iPointDrawMgr_ == nullptr) {
1589         iPointDrawMgr_ = std::make_shared<PointerDrawingManager>();
1590     }
1591     return iPointDrawMgr_;
1592 }
1593 
UpdatePointerVisible()1594 void PointerDrawingManager::UpdatePointerVisible()
1595 {
1596     CALL_DEBUG_ENTER;
1597     CHKPV(surfaceNode_);
1598     if (IsPointerVisible() && mouseDisplayState_) {
1599         surfaceNode_->SetVisible(true);
1600         MMI_HILOGI("Pointer window show success, mouseDisplayState_:%{public}s",
1601             mouseDisplayState_ ? "true" : "false");
1602     } else {
1603         surfaceNode_->SetVisible(false);
1604         MMI_HILOGI("Pointer window hide success, mouseDisplayState_:%{public}s",
1605             mouseDisplayState_ ? "true" : "false");
1606     }
1607     Rosen::RSTransaction::FlushImplicitTransaction();
1608 }
1609 
IsPointerVisible()1610 bool PointerDrawingManager::IsPointerVisible()
1611 {
1612     CALL_DEBUG_ENTER;
1613     if (!pidInfos_.empty()) {
1614         auto info = pidInfos_.back();
1615         if (!info.visible) {
1616             MMI_HILOGI("High priority visible property:%{public}zu.%{public}d-visible:%{public}s",
1617                 pidInfos_.size(), info.pid, info.visible?"true":"false");
1618             return info.visible;
1619         }
1620     }
1621     if (!hapPidInfos_.empty()) {
1622         for (auto& item : hapPidInfos_) {
1623             if (item.pid == pid_) {
1624                 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
1625                     item.pid, item.visible ? "true" : "false");
1626                 return item.visible;
1627             }
1628         }
1629         if (!(INPUT_DEV_MGR->HasPointerDevice() || WIN_MGR->IsMouseSimulate()) || pid_ == 0) {
1630             auto info = hapPidInfos_.back();
1631             MMI_HILOGI("Only hap visible pid:%{public}d-visible:%{public}s",
1632                 info.pid, info.visible ? "true" : "false");
1633             return info.visible;
1634         }
1635     }
1636     if (pidInfos_.empty()) {
1637         MMI_HILOGD("Visible property is true");
1638         return true;
1639     }
1640     auto info = pidInfos_.back();
1641     MMI_HILOGI("Visible property:%{public}zu.%{public}d-visible:%{public}s",
1642         pidInfos_.size(), info.pid, info.visible ? "true" : "false");
1643     return info.visible;
1644 }
1645 
DeletePointerVisible(int32_t pid)1646 void PointerDrawingManager::DeletePointerVisible(int32_t pid)
1647 {
1648     CALL_DEBUG_ENTER;
1649     std::lock_guard<std::mutex> guard(mutex_);
1650     MMI_HILOGI("isRsRemoteDied:%{public}d", g_isRsRemoteDied ? 1 : 0);
1651     if (g_isRsRemoteDied && surfaceNode_ != nullptr) {
1652         g_isRsRemoteDied = false;
1653         surfaceNode_->DetachToDisplay(screenId_);
1654         surfaceNode_ = nullptr;
1655         Rosen::RSTransaction::FlushImplicitTransaction();
1656     }
1657     if (pidInfos_.empty()) {
1658         return;
1659     }
1660     auto it = pidInfos_.begin();
1661     for (; it != pidInfos_.end(); ++it) {
1662         if (it->pid == pid) {
1663             pidInfos_.erase(it);
1664             break;
1665         }
1666     }
1667     if (it != pidInfos_.end()) {
1668         if (IsPointerVisible()) {
1669             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1670         }
1671         UpdatePointerVisible();
1672     }
1673 }
1674 
GetPointerVisible(int32_t pid)1675 bool PointerDrawingManager::GetPointerVisible(int32_t pid)
1676 {
1677     bool ret = true;
1678     int32_t count = 0;
1679     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
1680         if (it->pid == pid) {
1681             count++;
1682             ret = it->visible;
1683             break;
1684         }
1685     }
1686     if (count == 0 && !hapPidInfos_.empty()) {
1687         for (auto& item : hapPidInfos_) {
1688             if (item.pid == pid_) {
1689                 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
1690                     item.pid, item.visible ? "true" : "false");
1691                 count++;
1692                 ret = item.visible;
1693                 break;
1694             }
1695         }
1696     }
1697     return ret;
1698 }
1699 
OnSessionLost(int32_t pid)1700 void PointerDrawingManager::OnSessionLost(int32_t pid)
1701 {
1702     for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
1703         if (it->pid == pid) {
1704             hapPidInfos_.erase(it);
1705             break;
1706         }
1707     }
1708 }
1709 
SetPointerVisible(int32_t pid,bool visible,int32_t priority,bool isHap)1710 int32_t PointerDrawingManager::SetPointerVisible(int32_t pid, bool visible, int32_t priority, bool isHap)
1711 {
1712     MMI_HILOGI("pid:%{public}d,visible:%{public}s,priority:%{public}d,isHap:%{public}s", pid,
1713         visible ? "true" : "false", priority, isHap ? "true" : "false");
1714     if (isHap) {
1715         for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
1716             if (it->pid == pid) {
1717                 hapPidInfos_.erase(it);
1718                 break;
1719             }
1720         }
1721         PidInfo info = { .pid = pid, .visible = visible };
1722         hapPidInfos_.push_back(info);
1723         if (hapPidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
1724             hapPidInfos_.pop_front();
1725         }
1726         UpdatePointerVisible();
1727         return RET_OK;
1728     }
1729     if (WIN_MGR->GetExtraData().appended && visible && priority == 0) {
1730         MMI_HILOGE("current is drag state, can not set pointer visible");
1731         return RET_ERR;
1732     }
1733     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
1734         if (it->pid == pid) {
1735             pidInfos_.erase(it);
1736             break;
1737         }
1738     }
1739     PidInfo info = { .pid = pid, .visible = visible };
1740     pidInfos_.push_back(info);
1741     if (pidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
1742         pidInfos_.pop_front();
1743     }
1744     if (!WIN_MGR->HasMouseHideFlag() || INPUT_DEV_MGR->HasPointerDevice() || INPUT_DEV_MGR->HasVirtualPointerDevice()) {
1745         UpdatePointerVisible();
1746     }
1747     return RET_OK;
1748 }
1749 
SetPointerLocation(int32_t x,int32_t y)1750 void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y)
1751 {
1752     CALL_DEBUG_ENTER;
1753     FixCursorPosition(x, y);
1754     lastPhysicalX_ = x;
1755     lastPhysicalY_ = y;
1756     MMI_HILOGD("Pointer window move, x:%{private}d, y:%{private}d", lastPhysicalX_, lastPhysicalY_);
1757     if (surfaceNode_ != nullptr) {
1758         surfaceNode_->SetBounds(x,
1759             y,
1760             surfaceNode_->GetStagingProperties().GetBounds().z_,
1761             surfaceNode_->GetStagingProperties().GetBounds().w_);
1762 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1763         CHKPV(hardwareCursorPointerManager_);
1764         if (hardwareCursorPointerManager_->IsSupported()) {
1765             if (hardwareCursorPointerManager_->SetPosition(lastPhysicalX_, lastPhysicalY_) != RET_OK) {
1766                 MMI_HILOGE("Set hardware cursor position error.");
1767                 return;
1768             }
1769         }
1770 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1771         Rosen::RSTransaction::FlushImplicitTransaction();
1772         MMI_HILOGD("Pointer window move success");
1773     }
1774 }
1775 
UpdateDefaultPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)1776 int32_t PointerDrawingManager::UpdateDefaultPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
1777     bool isUiExtension)
1778 {
1779     if (windowId != GLOBAL_WINDOW_ID) {
1780         MMI_HILOGD("No need to change the default icon style");
1781         return RET_OK;
1782     }
1783     PointerStyle style;
1784     WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style, isUiExtension);
1785     if (pointerStyle.id != style.id) {
1786         auto iconPath = GetMouseIconPath();
1787         auto it = iconPath.find(MOUSE_ICON(MOUSE_ICON::DEFAULT));
1788         if (it == iconPath.end()) {
1789             MMI_HILOGE("Cannot find the default style");
1790             return RET_ERR;
1791         }
1792         std::string newIconPath;
1793         if (pointerStyle.id == MOUSE_ICON::DEFAULT) {
1794             newIconPath = DefaultIconPath;
1795         } else {
1796             newIconPath = iconPath[MOUSE_ICON(pointerStyle.id)].iconPath;
1797         }
1798         MMI_HILOGD("default path has changed from %{public}s to %{public}s",
1799             it->second.iconPath.c_str(), newIconPath.c_str());
1800         it->second.iconPath = newIconPath;
1801         UpdateIconPath(MOUSE_ICON(MOUSE_ICON::DEFAULT), newIconPath);
1802     }
1803     lastMouseStyle_ = style;
1804     return RET_OK;
1805 }
1806 
GetMouseIconPath()1807 std::map<MOUSE_ICON, IconStyle> PointerDrawingManager::GetMouseIconPath()
1808 {
1809     CALL_DEBUG_ENTER;
1810 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1811     if (HasMagicCursor()) {
1812         MMI_HILOGD("Magiccurosr get magic mouse map");
1813         return MAGIC_CURSOR->magicMouseIcons_;
1814     } else {
1815         MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
1816         return mouseIcons_;
1817     }
1818 #else
1819     return mouseIcons_;
1820 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1821 }
1822 
GetIconStyle(const MOUSE_ICON mouseStyle)1823 IconStyle PointerDrawingManager::GetIconStyle(const MOUSE_ICON mouseStyle)
1824 {
1825     std::map<MOUSE_ICON, IconStyle> mouseIcons = GetMouseIcons();
1826     auto iter = mouseIcons.find(mouseStyle);
1827     if (iter == mouseIcons.end()) {
1828         MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
1829         return IconStyle();
1830     }
1831     return iter->second;
1832 }
1833 
GetMouseIcons()1834 std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIcons()
1835 {
1836 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1837     if (HasMagicCursor()) {
1838         MMI_HILOGD("Magiccurosr get magic mouse map");
1839         return MAGIC_CURSOR->magicMouseIcons_;
1840     } else {
1841         MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
1842         return mouseIcons_;
1843     }
1844 #else
1845     return mouseIcons_;
1846 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1847 }
1848 
UpdateIconPath(const MOUSE_ICON mouseStyle,std::string iconPath)1849 void PointerDrawingManager::UpdateIconPath(const MOUSE_ICON mouseStyle, std::string iconPath)
1850 {
1851     CALL_DEBUG_ENTER;
1852     std::map<MOUSE_ICON, IconStyle> &mouseIcons = GetMouseIcons();
1853     auto iter = mouseIcons.find(mouseStyle);
1854     if (iter == mouseIcons.end()) {
1855         MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
1856         return;
1857     }
1858     iter->second.iconPath = iconPath;
1859 }
1860 
SetPointerStylePreference(PointerStyle pointerStyle)1861 int32_t PointerDrawingManager::SetPointerStylePreference(PointerStyle pointerStyle)
1862 {
1863     CALL_DEBUG_ENTER;
1864     std::string name = "pointerStyle";
1865     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, pointerStyle.id);
1866     if (ret != RET_OK) {
1867         MMI_HILOGD("Set pointer style failed, code:%{public}d", ret);
1868         return ret;
1869     }
1870     MMI_HILOGD("Set pointer style successfully, style:%{public}d", pointerStyle.id);
1871     return RET_OK;
1872 }
1873 
CheckPointerStyleParam(int32_t windowId,PointerStyle pointerStyle)1874 bool PointerDrawingManager::CheckPointerStyleParam(int32_t windowId, PointerStyle pointerStyle)
1875 {
1876     CALL_DEBUG_ENTER;
1877     if (windowId < -1) {
1878         return false;
1879     }
1880     if ((pointerStyle.id < MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) ||
1881         pointerStyle.id > MOUSE_ICON::RUNNING_RIGHT) {
1882         return false;
1883     }
1884     return true;
1885 }
1886 
SetPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)1887 int32_t PointerDrawingManager::SetPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
1888     bool isUiExtension)
1889 {
1890     CALL_DEBUG_ENTER;
1891     if (!CheckPointerStyleParam(windowId, pointerStyle)) {
1892         MMI_HILOGE("PointerStyle param is invalid");
1893         return RET_ERR;
1894     }
1895     if (windowId == GLOBAL_WINDOW_ID) {
1896         int32_t ret = SetPointerStylePreference(pointerStyle);
1897         if (ret != RET_OK) {
1898             MMI_HILOGE("Set style preference is failed, ret:%{public}d", ret);
1899             return RET_ERR;
1900         }
1901     }
1902     auto iconPath = GetMouseIconPath();
1903     if (iconPath.find(MOUSE_ICON(pointerStyle.id)) == iconPath.end()) {
1904         MMI_HILOGE("The param pointerStyle is invalid");
1905         return RET_ERR;
1906     }
1907     if (UpdateDefaultPointerStyle(pid, windowId, pointerStyle) != RET_OK) {
1908         MMI_HILOGE("Update default pointer iconPath failed");
1909         return RET_ERR;
1910     }
1911     if (WIN_MGR->SetPointerStyle(pid, windowId, pointerStyle, isUiExtension) != RET_OK) {
1912         MMI_HILOGE("Set pointer style failed");
1913         return RET_ERR;
1914     }
1915     if (!INPUT_DEV_MGR->HasPointerDevice() && !WIN_MGR->IsMouseSimulate()) {
1916         MMI_HILOGD("The pointer device is not exist");
1917         return RET_OK;
1918     }
1919     if (!WIN_MGR->IsNeedRefreshLayer(windowId)) {
1920         MMI_HILOGD("Not need refresh layer, window type:%{public}d, pointer style:%{public}d",
1921             windowId, pointerStyle.id);
1922         return RET_OK;
1923     }
1924     if (windowId != GLOBAL_WINDOW_ID && (pointerStyle.id == MOUSE_ICON::DEFAULT &&
1925         iconPath[MOUSE_ICON(pointerStyle.id)].iconPath != DefaultIconPath)) {
1926         PointerStyle style;
1927         WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
1928         pointerStyle = style;
1929     }
1930     if (windowId == windowId_ || windowId == GLOBAL_WINDOW_ID) {
1931         // Draw mouse style only when the current window is the top-level window
1932         DrawPointerStyle(pointerStyle);
1933     } else {
1934         MMI_HILOGW("set windowid:%{public}d, top windowid:%{public}d, dont draw pointer", windowId, windowId_);
1935     }
1936     MMI_HILOGI("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle.id);
1937     return RET_OK;
1938 }
1939 
GetPointerStyle(int32_t pid,int32_t windowId,PointerStyle & pointerStyle,bool isUiExtension)1940 int32_t PointerDrawingManager::GetPointerStyle(int32_t pid, int32_t windowId, PointerStyle &pointerStyle,
1941     bool isUiExtension)
1942 {
1943     CALL_DEBUG_ENTER;
1944     if (windowId == GLOBAL_WINDOW_ID) {
1945         std::string name = POINTER_COLOR;
1946         pointerStyle.color = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
1947         name = POINTER_SIZE;
1948         pointerStyle.size = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
1949         name = "pointerStyle";
1950         int32_t style = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_STYLE);
1951         MMI_HILOGD("Get pointer style successfully, pointerStyle:%{public}d", style);
1952         if (style == CURSOR_CIRCLE_STYLE) {
1953             pointerStyle.id = style;
1954             return RET_OK;
1955         }
1956     }
1957     WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
1958     MMI_HILOGD("Window id:%{public}d get pointer style:%{public}d success", windowId, pointerStyle.id);
1959     return RET_OK;
1960 }
1961 
ClearWindowPointerStyle(int32_t pid,int32_t windowId)1962 int32_t PointerDrawingManager::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
1963 {
1964     CALL_DEBUG_ENTER;
1965     return WIN_MGR->ClearWindowPointerStyle(pid, windowId);
1966 }
1967 
DrawPointerStyle(const PointerStyle & pointerStyle)1968 void PointerDrawingManager::DrawPointerStyle(const PointerStyle& pointerStyle)
1969 {
1970     CALL_DEBUG_ENTER;
1971     bool simulate = WIN_MGR->IsMouseSimulate();
1972     if (hasDisplay_ && (hasPointerDevice_ || simulate)) {
1973         if (surfaceNode_ != nullptr) {
1974             AttachToDisplay();
1975             Rosen::RSTransaction::FlushImplicitTransaction();
1976         }
1977         Direction direction = DIRECTION0;
1978         if (IsWindowRotation()) {
1979             direction = displayInfo_.direction;
1980         }
1981         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
1982             DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
1983                 pointerStyle, direction);
1984             MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1985             return;
1986         }
1987 
1988         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
1989         MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1990     }
1991 }
1992 
CheckMouseIconPath()1993 void PointerDrawingManager::CheckMouseIconPath()
1994 {
1995     for (auto iter = mouseIcons_.begin(); iter != mouseIcons_.end();) {
1996         if ((ReadCursorStyleFile(iter->second.iconPath)) != RET_OK) {
1997             iter = mouseIcons_.erase(iter);
1998             continue;
1999         }
2000         ++iter;
2001     }
2002 }
2003 
EnableHardwareCursorStats(int32_t pid,bool enable)2004 int32_t PointerDrawingManager::EnableHardwareCursorStats(int32_t pid, bool enable)
2005 {
2006     CALL_DEBUG_ENTER;
2007 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2008     CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2009     if ((hardwareCursorPointerManager_->EnableStats(enable)) != RET_OK) {
2010         MMI_HILOGE("Enable stats failed");
2011         return RET_ERR;
2012     }
2013 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2014     MMI_HILOGI("EnableHardwareCursorStats, enable:%{private}d", enable);
2015     return RET_OK;
2016 }
2017 
GetHardwareCursorStats(int32_t pid,uint32_t & frameCount,uint32_t & vsyncCount)2018 int32_t PointerDrawingManager::GetHardwareCursorStats(int32_t pid, uint32_t &frameCount, uint32_t &vsyncCount)
2019 {
2020     CALL_DEBUG_ENTER;
2021 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2022     CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2023     if ((hardwareCursorPointerManager_->GetCursorStats(frameCount, vsyncCount)) != RET_OK) {
2024         MMI_HILOGE("Query stats failed");
2025         return RET_ERR;
2026     }
2027 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2028     MMI_HILOGI("GetHardwareCursorStats, frameCount:%{private}d, vsyncCount:%{private}d", frameCount, vsyncCount);
2029     return RET_OK;
2030 }
2031 
InitStyle()2032 void PointerDrawingManager::InitStyle()
2033 {
2034     CALL_DEBUG_ENTER;
2035     mouseIcons_ = {
2036         {DEFAULT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2037         {EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "East.svg"}},
2038         {WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West.svg"}},
2039         {SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South.svg"}},
2040         {NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North.svg"}},
2041         {WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West_East.svg"}},
2042         {NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_South.svg"}},
2043         {NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East.svg"}},
2044         {NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West.svg"}},
2045         {SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_East.svg"}},
2046         {SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_West.svg"}},
2047         {NORTH_EAST_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East_South_West.svg"}},
2048         {NORTH_WEST_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West_South_East.svg"}},
2049         {CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cross.svg"}},
2050         {CURSOR_COPY, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Copy.svg"}},
2051         {CURSOR_FORBID, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Forbid.svg"}},
2052         {COLOR_SUCKER, {ANGLE_SW, IMAGE_POINTER_DEFAULT_PATH + "Colorsucker.svg"}},
2053         {HAND_GRABBING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Grabbing.svg"}},
2054         {HAND_OPEN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Open.svg"}},
2055         {HAND_POINTING, {ANGLE_NW_RIGHT, IMAGE_POINTER_DEFAULT_PATH + "Hand_Pointing.svg"}},
2056         {HELP, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Help.svg"}},
2057         {CURSOR_MOVE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Move.svg"}},
2058         {RESIZE_LEFT_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Left_Right.svg"}},
2059         {RESIZE_UP_DOWN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Up_Down.svg"}},
2060         {SCREENSHOT_CHOOSE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cross.svg"}},
2061         {SCREENSHOT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cursor.png"}},
2062         {TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Text_Cursor.svg"}},
2063         {ZOOM_IN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_In.svg"}},
2064         {ZOOM_OUT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_Out.svg"}},
2065         {MIDDLE_BTN_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_East.svg"}},
2066         {MIDDLE_BTN_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_West.svg"}},
2067         {MIDDLE_BTN_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South.svg"}},
2068         {MIDDLE_BTN_NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North.svg"}},
2069         {MIDDLE_BTN_NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_South.svg"}},
2070         {MIDDLE_BTN_NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_East.svg"}},
2071         {MIDDLE_BTN_NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_West.svg"}},
2072         {MIDDLE_BTN_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_East.svg"}},
2073         {MIDDLE_BTN_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_West.svg"}},
2074         {MIDDLE_BTN_NORTH_SOUTH_WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH +
2075             "MID_Btn_North_South_West_East.svg"}},
2076         {HORIZONTAL_TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Horizontal_Text_Cursor.svg"}},
2077         {CURSOR_CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Cross.svg"}},
2078         {CURSOR_CIRCLE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png"}},
2079         {LOADING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"}},
2080         {RUNNING, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2081         {RUNNING_LEFT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2082         {RUNNING_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg"}},
2083         {DEVELOPER_DEFINED_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2084     };
2085     CheckMouseIconPath();
2086 }
2087 
RotateDegree(Direction direction)2088 void PointerDrawingManager::RotateDegree(Direction direction)
2089 {
2090     CHKPV(surfaceNode_);
2091     surfaceNode_->SetPivot(0, 0);
2092     float degree = (static_cast<int>(DIRECTION0) - static_cast<int>(direction)) * ROTATION_ANGLE90;
2093     surfaceNode_->SetRotation(degree);
2094 }
2095 
SkipPointerLayer(bool isSkip)2096 int32_t PointerDrawingManager::SkipPointerLayer(bool isSkip)
2097 {
2098     CALL_INFO_TRACE;
2099     if (surfaceNode_ != nullptr) {
2100         surfaceNode_->SetSkipLayer(isSkip);
2101     }
2102     return RET_OK;
2103 }
2104 
Dump(int32_t fd,const std::vector<std::string> & args)2105 void PointerDrawingManager::Dump(int32_t fd, const std::vector<std::string> &args)
2106 {
2107     CALL_DEBUG_ENTER;
2108     std::ostringstream oss;
2109     oss << std::endl;
2110 
2111     auto displayTitles = std::make_tuple("ID", "X", "Y", "Width", "Height", "DPI", "Name", "Uniq",
2112                                          "Direction", "Display Direction", "Display Mode");
2113     DisplayInfo &di = displayInfo_;
2114     auto displayInfo = std::vector{std::make_tuple(di.id, di.x, di.y, di.width, di.height, di.dpi, di.name, di.uniq,
2115                                                    di.direction, di.displayDirection,
2116                                                    static_cast<int32_t>(di.displayMode))};
2117     DumpFullTable(oss, "Display Info", displayTitles, displayInfo);
2118     oss << std::endl;
2119 
2120     auto titles1 = std::make_tuple("hasDisplay", "hasPointerDevice", "lastPhysicalX", "lastPhysicalY",
2121                                    "pid", "windowId", "imageWidth", "imageHeight", "canvasWidth", "canvasHeight");
2122     auto data1 = std::vector{std::make_tuple(hasDisplay_, hasPointerDevice_, lastPhysicalX_, lastPhysicalY_,
2123                                              pid_, windowId_, imageWidth_, imageHeight_, canvasWidth_, canvasHeight_)};
2124     DumpFullTable(oss, "Cursor Info", titles1, data1);
2125     oss << std::endl;
2126 
2127     auto titles2 = std::make_tuple("mouseDisplayState", "mouseIconUpdate", "screenId", "userIconHotSpotX",
2128                                    "userIconHotSpotY", "tempPointerColor", "lastDirection", "currentDirection");
2129     auto data2 = std::vector{std::make_tuple(mouseDisplayState_, mouseIconUpdate_, screenId_, userIconHotSpotX_,
2130                                              userIconHotSpotY_, tempPointerColor_, lastDirection_, currentDirection_)};
2131 
2132     DumpFullTable(oss, "Cursor Info", titles2, data2);
2133     oss << std::endl;
2134 
2135     auto styleTitles = std::make_tuple("name", "Size", "Color", "ID");
2136     auto styleData = std::vector{
2137             std::make_tuple("lastMouseStyle", lastMouseStyle_.size, lastMouseStyle_.color, lastMouseStyle_.id),
2138             std::make_tuple("currentMouseStyle", currentMouseStyle_.size, currentMouseStyle_.color,
2139                             currentMouseStyle_.id)};
2140     DumpFullTable(oss, "Cursor Style Info", styleTitles, styleData);
2141     oss << std::endl;
2142 
2143     auto pidTitles = std::make_tuple("pid", "visible");
2144     std::vector<std::tuple<int32_t, bool>> pidInfos;
2145     for (const auto &pidInfo: pidInfos_) {
2146         pidInfos.emplace_back(pidInfo.pid, pidInfo.visible);
2147     }
2148     DumpFullTable(oss, "Visible Info", pidTitles, pidInfos);
2149     oss << std::endl;
2150 
2151     std::string dumpInfo = oss.str();
2152     dprintf(fd, dumpInfo.c_str());
2153 }
2154 
GetUserIconCopy()2155 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::GetUserIconCopy()
2156 {
2157     std::lock_guard<std::mutex> guard(mtx_);
2158     if (userIcon_ == nullptr) {
2159         MMI_HILOGI("userIcon_ is nullptr");
2160         return nullptr;
2161     }
2162     if (followSystem_) {
2163         Parcel data;
2164         userIcon_->Marshalling(data);
2165         std::shared_ptr<OHOS::Media::PixelMap> pixelMapPtr(OHOS::Media::PixelMap::Unmarshalling(data));
2166         if (pixelMapPtr == nullptr) {
2167             MMI_HILOGE("pixelMapPtr is nullptr");
2168             return nullptr;
2169         }
2170         Media::ImageInfo imageInfo;
2171         pixelMapPtr->GetImageInfo(imageInfo);
2172         int32_t cursorSize = GetPointerSize();
2173         float axis = 1.0f;
2174         cursorWidth_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.width;
2175         cursorHeight_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.height;
2176         int32_t maxValue = imageInfo.size.width > imageInfo.size.height ? cursorWidth_ : cursorHeight_;
2177         if (maxValue > MAX_CUSTOM_CURSOR_DIMENSION) {
2178             axis = (float)MAX_CUSTOM_CURSOR_DIMENSION / (float)std::max(imageInfo.size.width, imageInfo.size.height);
2179         } else {
2180             axis = (float)std::max(cursorWidth_, cursorHeight_) /
2181                 (float)std::max(imageInfo.size.width, imageInfo.size.height);
2182         }
2183         pixelMapPtr->scale(axis, axis, Media::AntiAliasingOption::LOW);
2184         cursorWidth_ = static_cast<int32_t>((float)imageInfo.size.width * axis);
2185         cursorHeight_ = static_cast<int32_t>((float)imageInfo.size.height * axis);
2186         userIconHotSpotX_ = static_cast<int32_t>((float)focusX_ * axis);
2187         userIconHotSpotY_ = static_cast<int32_t>((float)focusY_ * axis);
2188         MMI_HILOGI("cursorWidth:%{public}d, cursorHeight:%{public}d, imageWidth:%{public}d,"
2189             "imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d, axis:%{public}f,"
2190             "userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
2191             cursorWidth_, cursorHeight_, imageInfo.size.width, imageInfo.size.height,
2192             focusX_, focusY_, axis, userIconHotSpotX_, userIconHotSpotY_);
2193         return pixelMapPtr;
2194     }
2195     return userIcon_;
2196 }
2197 
SetCustomCursor(int32_t pid,int32_t windowId,CustomCursor cursor,CursorOptions options)2198 int32_t PointerDrawingManager::SetCustomCursor(int32_t pid, int32_t windowId, CustomCursor cursor,
2199     CursorOptions options)
2200 {
2201     CALL_DEBUG_ENTER;
2202     if (windowId < 0 || WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
2203         MMI_HILOGE("The windowId not in right pid");
2204         return ERROR_WINDOW_ID_PERMISSION_DENIED;
2205     }
2206     followSystem_ = options.followSystem;
2207     int32_t ret = UpdateCursorProperty(cursor);
2208     if (ret != RET_OK) {
2209         MMI_HILOGE("UpdateCursorProperty is failed");
2210         return ret;
2211     }
2212     mouseIconUpdate_ = true;
2213     PointerStyle style;
2214     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
2215     lastMouseStyle_ = style;
2216     ret = SetPointerStyle(pid, windowId, style);
2217     if (ret == RET_ERR) {
2218         MMI_HILOGE("SetPointerStyle is failed");
2219     }
2220     MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
2221         style.id, userIconHotSpotX_, userIconHotSpotY_);
2222     return ret;
2223 }
2224 
UpdateCursorProperty(CustomCursor cursor)2225 int32_t PointerDrawingManager::UpdateCursorProperty(CustomCursor cursor)
2226 {
2227     CHKPR(cursor.pixelMap, RET_ERR);
2228     Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(cursor.pixelMap);
2229     CHKPR(newPixelMap, RET_ERR);
2230     Media::ImageInfo imageInfo;
2231     newPixelMap->GetImageInfo(imageInfo);
2232     if (imageInfo.size.width < cursor.focusX || imageInfo.size.width < cursor.focusY) {
2233         MMI_HILOGE("focus is invalid");
2234         return RET_ERR;
2235     }
2236     if (imageInfo.size.width > MAX_CUSTOM_CURSOR_SIZE || imageInfo.size.height > MAX_CUSTOM_CURSOR_SIZE ||
2237         imageInfo.size.width <= 0 || imageInfo.size.height <= 0) {
2238         MMI_HILOGE("PixelMap is invalid");
2239         return RET_ERR;
2240     }
2241     cursorWidth_ = imageInfo.size.width;
2242     cursorHeight_ = imageInfo.size.height;
2243     {
2244         std::lock_guard<std::mutex> guard(mtx_);
2245         userIcon_.reset(newPixelMap);
2246     }
2247     focusX_ = cursor.focusX;
2248     focusY_ = cursor.focusY;
2249     userIconHotSpotX_ = cursor.focusX;
2250     userIconHotSpotY_ = cursor.focusY;
2251     MMI_HILOGI("imageWidth:%{public}d, imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d",
2252         imageInfo.size.width, imageInfo.size.height, cursor.focusX, cursor.focusY);
2253     return RET_OK;
2254 }
2255 } // namespace MMI
2256 } // namespace OHOS
2257