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