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