1 /*
2 * Copyright (c) 2023-2025 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 "touch_drawing_manager.h"
17
18 #include "bytrace_adapter.h"
19 #include "parameters.h"
20 #include "setting_datashare.h"
21
22 #include <system_ability_definition.h>
23 #include "input_windows_manager.h"
24 #include "table_dump.h"
25 #include "timer_manager.h"
26
27 #undef MMI_LOG_DOMAIN
28 #define MMI_LOG_DOMAIN MMI_LOG_CURSOR
29 #undef MMI_LOG_TAG
30 #define MMI_LOG_TAG "TouchDrawingManager"
31
32 namespace OHOS {
33 namespace MMI {
34 namespace {
35 constexpr int32_t REPEAT_ONCE { 1 };
36 constexpr int32_t REPEAT_THIRTY_TIMES { 30 };
37 constexpr int32_t REPEAT_COOLING_TIME { 1000 }; // ms
38 const std::string SHOW_CURSOR_SWITCH_NAME { "settings.input.show_touch_hint" };
39 const std::string POINTER_POSITION_SWITCH_NAME { "settings.developer.show_touch_track" };
40 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
41 const std::string FOLDABLE_DEVICE_POLICY = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
42 constexpr int32_t WINDOW_ROTATE { 0 };
43 constexpr char ROTATE_WINDOW_ROTATE { '0' };
44 constexpr int32_t FOLDABLE_DEVICE { 2 };
45 constexpr char LIB_TOUCH_DRAWING_HANDLER_PATH[] { "libmmi_touch_drawing_handler.z.so" };
46 constexpr int32_t DEFAULT_VALUE { -1 };
47 } // namespace
48
TouchDrawingManager()49 TouchDrawingManager::TouchDrawingManager() {}
50
~TouchDrawingManager()51 TouchDrawingManager::~TouchDrawingManager() {}
52
Initialize()53 void TouchDrawingManager::Initialize()
54 {
55 SetupSettingObserver();
56 }
57
SetupSettingObserver()58 void TouchDrawingManager::SetupSettingObserver()
59 {
60 CreateObserver();
61 if (hasBubbleObserver_ && hasPointerObserver_) {
62 return;
63 }
64 auto timerId = TimerMgr->AddTimer(REPEAT_COOLING_TIME, REPEAT_ONCE,
65 [this]() {
66 SetupSettingObserver();
67 }, "TouchDrawingManager");
68 if (timerId < 0) {
69 MMI_HILOGE("AddTimer fail");
70 }
71 }
72
TouchDrawHandler(std::shared_ptr<PointerEvent> pointerEvent)73 void TouchDrawingManager::TouchDrawHandler(std::shared_ptr<PointerEvent> pointerEvent)
74 {
75 CALL_DEBUG_ENTER;
76 CHKPV(pointerEvent);
77 auto touchDrawingHandler = GetTouchDrawingHandler();
78 if (touchDrawingHandler != nullptr) {
79 touchDrawingHandler->TouchDrawHandler(pointerEvent);
80 }
81 }
82
UpdateDisplayInfo(const OLD::DisplayInfo & displayInfo)83 void TouchDrawingManager::UpdateDisplayInfo(const OLD::DisplayInfo& displayInfo)
84 {
85 CALL_DEBUG_ENTER;
86 auto touchDrawingHandler = GetTouchDrawingHandler();
87 if (touchDrawingHandler != nullptr) {
88 touchDrawingHandler->UpdateDisplayInfo(displayInfo);
89
90 static std::once_flag flag;
91 std::call_once(flag, [this]() {
92 UpdateLabels();
93 });
94 } else {
95 displayInfo_ = displayInfo;
96 }
97 }
98
GetOriginalTouchScreenCoordinates(Direction direction,int32_t width,int32_t height,int32_t & physicalX,int32_t & physicalY)99 void TouchDrawingManager::GetOriginalTouchScreenCoordinates(Direction direction, int32_t width, int32_t height,
100 int32_t &physicalX, int32_t &physicalY)
101 {
102 MMI_HILOGD("direction:%{public}d", direction);
103 switch (direction) {
104 case DIRECTION0: {
105 break;
106 }
107 case DIRECTION90: {
108 int32_t temp = physicalY;
109 physicalY = width - physicalX;
110 physicalX = temp;
111 break;
112 }
113 case DIRECTION180: {
114 physicalX = width - physicalX;
115 physicalY = height - physicalY;
116 break;
117 }
118 case DIRECTION270: {
119 int32_t temp = physicalX;
120 physicalX = height - physicalY;
121 physicalY = temp;
122 break;
123 }
124 default: {
125 break;
126 }
127 }
128 }
129
UpdateLabels()130 int32_t TouchDrawingManager::UpdateLabels()
131 {
132 CALL_DEBUG_ENTER;
133 if (pointerMode_.isShow) {
134 auto touchDrawingHandler = LoadTouchDrawingHandler();
135 if (touchDrawingHandler == nullptr) {
136 MMI_HILOGW("Failed to load touch drawing handler");
137 return RET_ERR;
138 }
139 if (touchDrawingHandler->IsValidScaleInfo()) {
140 touchDrawingHandler->UpdateLabels(true);
141 return RET_OK;
142 }
143 AddUpdateLabelsTimer();
144 } else {
145 RemoveUpdateLabelsTimer();
146 auto touchDrawingHandler = GetTouchDrawingHandler();
147 if (touchDrawingHandler == nullptr) {
148 MMI_HILOGD("No touch drawing handler");
149 return RET_ERR;
150 }
151 touchDrawingHandler->UpdateLabels(false);
152 UnloadTouchDrawingHandler();
153 }
154 return RET_OK;
155 }
156
RemoveUpdateLabelsTimer()157 void TouchDrawingManager::RemoveUpdateLabelsTimer()
158 {
159 if (timerId_ != DEFAULT_VALUE) {
160 TimerMgr->RemoveTimer(timerId_);
161 timerId_ = DEFAULT_VALUE;
162 }
163 }
164
AddUpdateLabelsTimer()165 void TouchDrawingManager::AddUpdateLabelsTimer()
166 {
167 if (timerId_ != DEFAULT_VALUE) {
168 MMI_HILOGE("The timer is running");
169 return;
170 }
171 timerId_ = TimerMgr->AddTimer(REPEAT_COOLING_TIME, REPEAT_THIRTY_TIMES, [this]() {
172 auto touchDrawingHandler = GetTouchDrawingHandler();
173 CHKPV(touchDrawingHandler);
174 if (!touchDrawingHandler->IsValidScaleInfo()) {
175 MMI_HILOGE("The scale info is invalid, need to retry");
176 return;
177 }
178 touchDrawingHandler->UpdateLabels(true);
179 TimerMgr->RemoveTimer(timerId_);
180 timerId_ = DEFAULT_VALUE;
181 });
182 }
183
UpdateBubbleData()184 int32_t TouchDrawingManager::UpdateBubbleData()
185 {
186 CALL_DEBUG_ENTER;
187 if (bubbleMode_.isShow) {
188 auto touchDrawingHandler = LoadTouchDrawingHandler();
189 if (touchDrawingHandler == nullptr) {
190 MMI_HILOGE("Failed to load touch drawing handler");
191 return RET_ERR;
192 }
193 touchDrawingHandler->UpdateBubbleData(true);
194 } else {
195 auto touchDrawingHandler = GetTouchDrawingHandler();
196 if (touchDrawingHandler == nullptr) {
197 MMI_HILOGD("No touch drawing handler");
198 return RET_ERR;
199 }
200 touchDrawingHandler->UpdateBubbleData(false);
201 UnloadTouchDrawingHandler();
202 }
203 return RET_OK;
204 }
205
RotationScreen()206 void TouchDrawingManager::RotationScreen()
207 {
208 CALL_DEBUG_ENTER;
209 auto touchDrawingHandler = GetTouchDrawingHandler();
210 if (touchDrawingHandler != nullptr) {
211 touchDrawingHandler->RotationScreen();
212 }
213 }
214
CreateObserver()215 void TouchDrawingManager::CreateObserver()
216 {
217 CALL_DEBUG_ENTER;
218 if (!hasBubbleObserver_) {
219 MMI_HILOGI("Setup observer of show-touch-track");
220 bubbleMode_.SwitchName = SHOW_CURSOR_SWITCH_NAME;
221 CreateBubbleObserver(bubbleMode_);
222 }
223 if (!hasPointerObserver_) {
224 MMI_HILOGI("Setup observer of show-touch-position");
225 pointerMode_.SwitchName = POINTER_POSITION_SWITCH_NAME;
226 CreatePointerObserver(pointerMode_);
227 SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).
228 GetBoolValue(POINTER_POSITION_SWITCH_NAME, pointerMode_.isShow);
229 }
230 MMI_HILOGD("The bubbleMode_:%{public}d, pointerMode_:%{public}d", bubbleMode_.isShow, pointerMode_.isShow);
231 }
232
233 template <class T>
CreateBubbleObserver(T & item)234 void TouchDrawingManager::CreateBubbleObserver(T &item)
235 {
236 CALL_DEBUG_ENTER;
237 SettingObserver::UpdateFunc updateFunc = [&item, this](const std::string& key) {
238 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
239 .GetBoolValue(key, item.isShow);
240 if (ret != RET_OK) {
241 MMI_HILOGE("Get value from setting date fail");
242 return;
243 }
244 CHKPV(delegateProxy_);
245 delegateProxy_->OnPostSyncTask(std::bind(&TouchDrawingManager::UpdateBubbleData, this));
246 MMI_HILOGI("The key:%{public}s, statusValue:%{public}d", key.c_str(), item.isShow);
247 };
248 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
249 .CreateObserver(item.SwitchName, updateFunc);
250 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).
251 RegisterObserver(statusObserver);
252 if (ret != ERR_OK) {
253 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
254 statusObserver = nullptr;
255 return;
256 }
257 hasBubbleObserver_ = true;
258 }
259
260 template <class T>
CreatePointerObserver(T & item)261 void TouchDrawingManager::CreatePointerObserver(T &item)
262 {
263 CALL_DEBUG_ENTER;
264 SettingObserver::UpdateFunc updateFunc = [&item, this](const std::string& key) {
265 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
266 .GetBoolValue(key, item.isShow);
267 if (ret != RET_OK) {
268 MMI_HILOGE("Get value from setting date fail");
269 return;
270 }
271 CHKPV(delegateProxy_);
272 delegateProxy_->OnPostSyncTask(std::bind(&TouchDrawingManager::UpdateLabels, this));
273 MMI_HILOGI("The key:%{public}s, statusValue:%{public}d", key.c_str(), item.isShow);
274 };
275 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID)
276 .CreateObserver(item.SwitchName, updateFunc);
277 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
278 if (ret != ERR_OK) {
279 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
280 statusObserver = nullptr;
281 return;
282 }
283 hasPointerObserver_ = true;
284 }
285
Dump(int32_t fd,const std::vector<std::string> & args)286 void TouchDrawingManager::Dump(int32_t fd, const std::vector<std::string> &args)
287 {
288 auto touchDrawingHandler = GetTouchDrawingHandler();
289 if (touchDrawingHandler == nullptr) {
290 MMI_HILOGD("No touch drawing handler");
291 return;
292 }
293 touchDrawingHandler->Dump(fd, args);
294 }
295
IsWindowRotation() const296 bool TouchDrawingManager::IsWindowRotation() const
297 {
298 auto touchDrawingHandler = GetTouchDrawingHandler();
299 if (touchDrawingHandler != nullptr) {
300 return touchDrawingHandler->IsWindowRotation();
301 }
302 MMI_HILOGD("ROTATE_POLICY:%{public}d, FOLDABLE_DEVICE_POLICY:%{public}s",
303 ROTATE_POLICY, FOLDABLE_DEVICE_POLICY.c_str());
304 return (ROTATE_POLICY == WINDOW_ROTATE ||
305 (ROTATE_POLICY == FOLDABLE_DEVICE &&
306 ((displayInfo_.displayMode == DisplayMode::MAIN &&
307 FOLDABLE_DEVICE_POLICY[0] == ROTATE_WINDOW_ROTATE) ||
308 (displayInfo_.displayMode == DisplayMode::FULL &&
309 (FOLDABLE_DEVICE_POLICY.size() > FOLDABLE_DEVICE) &&
310 FOLDABLE_DEVICE_POLICY[FOLDABLE_DEVICE] == ROTATE_WINDOW_ROTATE))));
311 }
312
SetDelegateProxy(std::shared_ptr<DelegateInterface> proxy)313 void TouchDrawingManager::SetDelegateProxy(std::shared_ptr<DelegateInterface> proxy)
314 {
315 delegateProxy_ = proxy;
316 }
317
SetMultiWindowScreenId(uint64_t screenId,uint64_t displayNodeScreenId)318 void TouchDrawingManager::SetMultiWindowScreenId(uint64_t screenId, uint64_t displayNodeScreenId)
319 {
320 auto touchDrawingHandler = GetTouchDrawingHandler();
321 if (touchDrawingHandler != nullptr) {
322 touchDrawingHandler->SetMultiWindowScreenId(screenId, displayNodeScreenId);
323 } else {
324 windowScreenId_ = screenId;
325 displayNodeScreenId_ = displayNodeScreenId;
326 }
327 }
328
LoadTouchDrawingHandler()329 ITouchDrawingHandler* TouchDrawingManager::LoadTouchDrawingHandler()
330 {
331 if (touchDrawingHandler_ == nullptr) {
332 touchDrawingHandler_ = ComponentManager::LoadLibrary<ITouchDrawingHandler>(
333 nullptr, LIB_TOUCH_DRAWING_HANDLER_PATH);
334 if (touchDrawingHandler_ != nullptr) {
335 touchDrawingHandler_->UpdateDisplayInfo(displayInfo_);
336 touchDrawingHandler_->SetMultiWindowScreenId(windowScreenId_, displayNodeScreenId_);
337 }
338 }
339 return touchDrawingHandler_.get();
340 }
341
GetTouchDrawingHandler() const342 ITouchDrawingHandler* TouchDrawingManager::GetTouchDrawingHandler() const
343 {
344 return touchDrawingHandler_.get();
345 }
346
UnloadTouchDrawingHandler()347 void TouchDrawingManager::UnloadTouchDrawingHandler()
348 {
349 if (bubbleMode_.isShow || pointerMode_.isShow) {
350 return;
351 }
352 touchDrawingHandler_ = { nullptr, ComponentManager::Component<ITouchDrawingHandler>(nullptr, nullptr) };
353 }
354
ResetTouchWindow()355 void TouchDrawingManager::ResetTouchWindow()
356 {
357 auto touchDrawingHandler = GetTouchDrawingHandler();
358 if (touchDrawingHandler != nullptr) {
359 touchDrawingHandler->UpdateLabels(false);
360 touchDrawingHandler->UpdateBubbleData(false);
361 UpdateLabels();
362 UpdateBubbleData();
363 MMI_HILOGI("Delete the original node, bubble:%{public}d,Label:%{public}d",
364 bubbleMode_.isShow, pointerMode_.isShow);
365 }
366 }
367 } // namespace MMI
368 } // namespace OHOS