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