• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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