1 /*
2 * Copyright (C) 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 "cursor_drawing_component.h"
17
18 #include <dlfcn.h>
19 #include <securec.h>
20
21 #include "mmi_log.h"
22 #include "pointer_device_manager.h"
23 #include "timer_manager.h"
24
25 #define MMI_LOG_TAG "CursorDrawingComponent"
26 #define CHK_IS_LOADV(isLoaded, pointerInstance) \
27 if ((!isLoaded) || ((pointerInstance) == nullptr)) { \
28 MMI_HILOGE("libcursor_drawing_adapter.z.so is not loaded or instance does not exist"); \
29 return; \
30 }
31
32 #define CHK_IS_LOADF(isLoaded, pointerInstance) \
33 if ((!isLoaded) || ((pointerInstance) == nullptr)) { \
34 MMI_HILOGE("libcursor_drawing_adapter.z.so is not loaded or instance does not exist"); \
35 return false; \
36 }
37
38 #define CHK_IS_LOADR(isLoaded, pointerInstance) \
39 if ((!isLoaded_) || ((pointerInstance_) == nullptr)) { \
40 MMI_HILOGE("libcursor_drawing_adapter.z.so is not loaded or instance does not exist"); \
41 return RET_ERR; \
42 }
43
44 namespace OHOS::MMI {
45 namespace {
46 static constexpr const char *MULTIMODAL_PATH_NAME = "libcursor_drawing_adapter.z.so";
47 constexpr int32_t UNLOAD_TIME_MS = 2 * 60 * 1000; // 2 minutes
48 constexpr int32_t CHECK_INTERVAL_MS = 20 * 1000; // check every 20 seconds
49 constexpr int32_t CHECK_COUNT = -1;
50 }
51
GetInstance()52 CursorDrawingComponent& CursorDrawingComponent::GetInstance()
53 {
54 static CursorDrawingComponent instance;
55 instance.Load();
56 instance.lastCallTime_ = std::chrono::steady_clock::now();
57 return instance;
58 }
59
CursorDrawingComponent()60 CursorDrawingComponent::CursorDrawingComponent()
61 {
62 MMI_HILOGI("create succeeded");
63 }
64
~CursorDrawingComponent()65 CursorDrawingComponent::~CursorDrawingComponent()
66 {
67 UnLoad();
68 MMI_HILOGI("destroy succeeded");
69 }
70
71
Load()72 void CursorDrawingComponent::Load()
73 {
74 {
75 std::lock_guard<std::mutex> lockGuard(loadSoMutex_);
76 if (isLoaded_ && (soHandle_ != nullptr)) {
77 return;
78 }
79
80 if (!LoadLibrary()) {
81 return;
82 }
83 }
84
85 if (timerId_ > 0) {
86 TimerMgr->RemoveTimer(timerId_);
87 }
88 timerId_ = TimerMgr->AddLongTimer(CHECK_INTERVAL_MS, CHECK_COUNT, [this] {
89 auto idleTime = std::chrono::duration_cast<std::chrono::milliseconds>(
90 std::chrono::steady_clock::now() - lastCallTime_).count();
91 if ((idleTime >= UNLOAD_TIME_MS) && !POINTER_DEV_MGR.isInit) {
92 CursorDrawingComponent::GetInstance().UnLoad();
93 }
94 }, "libcursor_drawing_adapter-Unload");
95 if (timerId_ < 0) {
96 MMI_HILOGE("Add timer for unloading libcursor_drawing_adapter library fail");
97 UnLoad();
98 return;
99 }
100 MMI_HILOGI("Load %{public}s is succeeded", MULTIMODAL_PATH_NAME);
101 }
102
LoadLibrary()103 bool CursorDrawingComponent::LoadLibrary()
104 {
105 soHandle_ = dlopen(MULTIMODAL_PATH_NAME, RTLD_LAZY);
106 if (soHandle_ == nullptr) {
107 const char *errorMsg = dlerror();
108 MMI_HILOGE("dlopen %{public}s failed, err msg:%{public}s", MULTIMODAL_PATH_NAME,
109 (errorMsg != nullptr) ? errorMsg : "");
110 return false;
111 }
112
113 getPointerInstance_ = reinterpret_cast<GetPointerInstanceFunc>(dlsym(soHandle_, "GetPointerInstance"));
114 if (getPointerInstance_ == nullptr) {
115 const char *errorMsg = dlerror();
116 MMI_HILOGE("dlsym GetInstanceFunc failed, err msg:%{public}s", (errorMsg != nullptr) ? errorMsg : "");
117 if (dlclose(soHandle_) != 0) {
118 errorMsg = dlerror();
119 MMI_HILOGE("dlclose %{public}s failed, err msg:%{public}s", MULTIMODAL_PATH_NAME,
120 (errorMsg != nullptr) ? errorMsg : "");
121 }
122 soHandle_ = nullptr;
123 return false;
124 }
125
126 pointerInstance_ = reinterpret_cast<IPointerDrawingManager*>(getPointerInstance_());
127 if (pointerInstance_ == nullptr) {
128 MMI_HILOGE("pointerInstance_ is nullptr");
129 if (dlclose(soHandle_) != 0) {
130 const char *errorMsg = dlerror();
131 MMI_HILOGE("dlclose %{public}s failed, err msg:%{public}s", MULTIMODAL_PATH_NAME,
132 (errorMsg != nullptr) ? errorMsg : "");
133 }
134 soHandle_ = nullptr;
135 getPointerInstance_ = nullptr;
136 return false;
137 }
138 isLoaded_ = true;
139 return true;
140 }
141
UnLoad()142 void CursorDrawingComponent::UnLoad()
143 {
144 std::lock_guard<std::mutex> lockGuard(loadSoMutex_);
145 if (!isLoaded_ || (soHandle_ == nullptr)) {
146 MMI_HILOGI("%{public}s has been UnLoaded", MULTIMODAL_PATH_NAME);
147 return;
148 }
149
150 if (dlclose(soHandle_) != 0) {
151 const char *errorMsg = dlerror();
152 MMI_HILOGE("dlclose %{public}s failed, err msg:%{public}s", MULTIMODAL_PATH_NAME,
153 (errorMsg != nullptr) ? errorMsg : "");
154 return;
155 }
156 if (dlclose(soHandle_) != 0) {
157 const char *errorMsg = dlerror();
158 MMI_HILOGW("%{public}s has been unloaded, err msg:%{public}s", MULTIMODAL_PATH_NAME,
159 (errorMsg != nullptr) ? errorMsg : "");
160 }
161 isLoaded_ = false;
162 soHandle_ = nullptr;
163 getPointerInstance_ = nullptr;
164 pointerInstance_ = nullptr;
165 MMI_HILOGI("UnLoad %{public}s is succeeded", MULTIMODAL_PATH_NAME);
166 }
167
DrawPointer(uint64_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)168 void CursorDrawingComponent::DrawPointer(uint64_t displayId, int32_t physicalX, int32_t physicalY,
169 const PointerStyle pointerStyle, Direction direction)
170 {
171 CHK_IS_LOADV(isLoaded_, pointerInstance_)
172 pointerInstance_->DrawPointer(displayId, physicalX, physicalY, pointerStyle, direction);
173 }
174
UpdateDisplayInfo(const OLD::DisplayInfo & displayInfo)175 void CursorDrawingComponent::UpdateDisplayInfo(const OLD::DisplayInfo &displayInfo)
176 {
177 CHK_IS_LOADV(isLoaded_, pointerInstance_)
178 pointerInstance_->UpdateDisplayInfo(displayInfo);
179 }
180
OnDisplayInfo(const OLD::DisplayGroupInfo & displayGroupInfo)181 void CursorDrawingComponent::OnDisplayInfo(const OLD::DisplayGroupInfo &displayGroupInfo)
182 {
183 CHK_IS_LOADV(isLoaded_, pointerInstance_)
184 pointerInstance_->OnDisplayInfo(displayGroupInfo);
185 }
186
OnWindowInfo(const WinInfo & info)187 void CursorDrawingComponent::OnWindowInfo(const WinInfo &info)
188 {
189 CHK_IS_LOADV(isLoaded_, pointerInstance_)
190 pointerInstance_->OnWindowInfo(info);
191 }
192
Init()193 bool CursorDrawingComponent::Init()
194 {
195 CHK_IS_LOADF(isLoaded_, pointerInstance_)
196 return pointerInstance_->Init();
197 }
198
DeletePointerVisible(int32_t pid)199 void CursorDrawingComponent::DeletePointerVisible(int32_t pid)
200 {
201 CHK_IS_LOADV(isLoaded_, pointerInstance_)
202 pointerInstance_->DeletePointerVisible(pid);
203 }
204
SetPointerVisible(int32_t pid,bool visible,int32_t priority,bool isHap)205 int32_t CursorDrawingComponent::SetPointerVisible(int32_t pid, bool visible, int32_t priority, bool isHap)
206 {
207 CHK_IS_LOADR(isLoaded_, pointerInstance_)
208 return pointerInstance_->SetPointerVisible(pid, visible, priority, isHap);
209 }
210
GetPointerVisible(int32_t pid)211 bool CursorDrawingComponent::GetPointerVisible(int32_t pid)
212 {
213 CHK_IS_LOADF(isLoaded_, pointerInstance_)
214 return pointerInstance_->GetPointerVisible(pid);
215 }
216
SetPointerColor(int32_t color)217 int32_t CursorDrawingComponent::SetPointerColor(int32_t color)
218 {
219 CHK_IS_LOADR(isLoaded_, pointerInstance_)
220 return pointerInstance_->SetPointerColor(color);
221 }
222
GetPointerColor()223 int32_t CursorDrawingComponent::GetPointerColor()
224 {
225 CHK_IS_LOADR(isLoaded_, pointerInstance_)
226 return pointerInstance_->GetPointerColor();
227 }
228
SetPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)229 int32_t CursorDrawingComponent::SetPointerStyle(
230 int32_t pid, int32_t windowId, PointerStyle pointerStyle, bool isUiExtension)
231 {
232 CHK_IS_LOADR(isLoaded_, pointerInstance_)
233 return pointerInstance_->SetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
234 }
235
ClearWindowPointerStyle(int32_t pid,int32_t windowId)236 int32_t CursorDrawingComponent::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
237 {
238 CHK_IS_LOADR(isLoaded_, pointerInstance_)
239 return pointerInstance_->ClearWindowPointerStyle(pid, windowId);
240 }
241
GetPointerStyle(int32_t pid,int32_t windowId,PointerStyle & pointerStyle,bool isUiExtension)242 int32_t CursorDrawingComponent::GetPointerStyle(
243 int32_t pid, int32_t windowId, PointerStyle &pointerStyle, bool isUiExtension)
244 {
245 CHK_IS_LOADR(isLoaded_, pointerInstance_)
246 return pointerInstance_->GetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
247 }
248
DrawPointerStyle(const PointerStyle & pointerStyle)249 void CursorDrawingComponent::DrawPointerStyle(const PointerStyle &pointerStyle)
250 {
251 CHK_IS_LOADV(isLoaded_, pointerInstance_)
252 pointerInstance_->DrawPointerStyle(pointerStyle);
253 }
254
IsPointerVisible()255 bool CursorDrawingComponent::IsPointerVisible()
256 {
257 CHK_IS_LOADF(isLoaded_, pointerInstance_)
258 return pointerInstance_->IsPointerVisible();
259 }
260
SetPointerLocation(int32_t x,int32_t y,uint64_t displayId)261 void CursorDrawingComponent::SetPointerLocation(int32_t x, int32_t y, uint64_t displayId)
262 {
263 CHK_IS_LOADV(isLoaded_, pointerInstance_)
264 pointerInstance_->SetPointerLocation(x, y, displayId);
265 }
266
SetMouseDisplayState(bool state)267 void CursorDrawingComponent::SetMouseDisplayState(bool state)
268 {
269 CHK_IS_LOADV(isLoaded_, pointerInstance_)
270 pointerInstance_->SetMouseDisplayState(state);
271 }
272
GetMouseDisplayState()273 bool CursorDrawingComponent::GetMouseDisplayState()
274 {
275 CHK_IS_LOADF(isLoaded_, pointerInstance_)
276 return pointerInstance_->GetMouseDisplayState();
277 }
278
SetCustomCursor(CursorPixelMap curPixelMap,int32_t pid,int32_t windowId,int32_t focusX,int32_t focusY)279 int32_t CursorDrawingComponent::SetCustomCursor(
280 CursorPixelMap curPixelMap, int32_t pid, int32_t windowId, int32_t focusX, int32_t focusY)
281 {
282 CHK_IS_LOADR(isLoaded_, pointerInstance_)
283 return pointerInstance_->SetCustomCursor(curPixelMap, pid, windowId, focusX, focusY);
284 }
285
SetCustomCursor(int32_t pid,int32_t windowId,CustomCursor cursor,CursorOptions options)286 int32_t CursorDrawingComponent::SetCustomCursor(
287 int32_t pid, int32_t windowId, CustomCursor cursor, CursorOptions options)
288 {
289 CHK_IS_LOADR(isLoaded_, pointerInstance_)
290 return pointerInstance_->SetCustomCursor(pid, windowId, cursor, options);
291 }
292
SetMouseIcon(int32_t pid,int32_t windowId,CursorPixelMap curPixelMap)293 int32_t CursorDrawingComponent::SetMouseIcon(int32_t pid, int32_t windowId, CursorPixelMap curPixelMap)
294 {
295 CHK_IS_LOADR(isLoaded_, pointerInstance_)
296 return pointerInstance_->SetMouseIcon(pid, windowId, curPixelMap);
297 }
298
SetMouseHotSpot(int32_t pid,int32_t windowId,int32_t hotSpotX,int32_t hotSpotY)299 int32_t CursorDrawingComponent::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
300 {
301 CHK_IS_LOADR(isLoaded_, pointerInstance_)
302 return pointerInstance_->SetMouseHotSpot(pid, windowId, hotSpotX, hotSpotY);
303 }
304
SetPointerSize(int32_t size)305 int32_t CursorDrawingComponent::SetPointerSize(int32_t size)
306 {
307 CHK_IS_LOADR(isLoaded_, pointerInstance_)
308 return pointerInstance_->SetPointerSize(size);
309 }
310
GetPointerSize()311 int32_t CursorDrawingComponent::GetPointerSize()
312 {
313 CHK_IS_LOADR(isLoaded_, pointerInstance_)
314 return pointerInstance_->GetPointerSize();
315 }
316
GetPointerImageSize(int32_t & width,int32_t & height)317 void CursorDrawingComponent::GetPointerImageSize(int32_t &width, int32_t &height)
318 {
319 CHK_IS_LOADV(isLoaded_, pointerInstance_)
320 pointerInstance_->GetPointerImageSize(width, height);
321 }
322
GetCursorSurfaceId(uint64_t & surfaceId)323 int32_t CursorDrawingComponent::GetCursorSurfaceId(uint64_t &surfaceId)
324 {
325 CHK_IS_LOADR(isLoaded_, pointerInstance_)
326 return pointerInstance_->GetCursorSurfaceId(surfaceId);
327 }
328
GetLastMouseStyle()329 PointerStyle CursorDrawingComponent::GetLastMouseStyle()
330 {
331 if (!isLoaded_ || (pointerInstance_ == nullptr)) {
332 MMI_HILOGE("%{public}s is closed", MULTIMODAL_PATH_NAME);
333 return PointerStyle();
334 }
335 return pointerInstance_->GetLastMouseStyle();
336 }
337
GetIconStyle(const MOUSE_ICON mouseStyle)338 IconStyle CursorDrawingComponent::GetIconStyle(const MOUSE_ICON mouseStyle)
339 {
340 if (!isLoaded_ || (pointerInstance_ == nullptr)) {
341 MMI_HILOGE("%{public}s is closed", MULTIMODAL_PATH_NAME);
342 return IconStyle();
343 }
344 return pointerInstance_->GetIconStyle(mouseStyle);
345 }
346
GetMouseIconPath()347 const std::map<MOUSE_ICON, IconStyle>& CursorDrawingComponent::GetMouseIconPath()
348 {
349 if (!isLoaded_ || (pointerInstance_ == nullptr)) {
350 MMI_HILOGE("%{public}s is closed", MULTIMODAL_PATH_NAME);
351 static std::map<MOUSE_ICON, IconStyle> emptMap;
352 return emptMap;
353 }
354 return pointerInstance_->GetMouseIconPath();
355 }
356
SwitchPointerStyle()357 int32_t CursorDrawingComponent::SwitchPointerStyle()
358 {
359 CHK_IS_LOADR(isLoaded_, pointerInstance_)
360 return pointerInstance_->SwitchPointerStyle();
361 }
362
DrawMovePointer(uint64_t displayId,int32_t physicalX,int32_t physicalY)363 void CursorDrawingComponent::DrawMovePointer(uint64_t displayId, int32_t physicalX, int32_t physicalY)
364 {
365 CHK_IS_LOADV(isLoaded_, pointerInstance_)
366 pointerInstance_->DrawMovePointer(displayId, physicalX, physicalY);
367 }
368
Dump(int32_t fd,const std::vector<std::string> & args)369 void CursorDrawingComponent::Dump(int32_t fd, const std::vector<std::string> &args)
370 {
371 CHK_IS_LOADV(isLoaded_, pointerInstance_)
372 pointerInstance_->Dump(fd, args);
373 }
374
InitPointerCallback()375 void CursorDrawingComponent::InitPointerCallback()
376 {
377 CHK_IS_LOADV(isLoaded_, pointerInstance_)
378 pointerInstance_->InitPointerCallback();
379 }
380
InitScreenInfo()381 void CursorDrawingComponent::InitScreenInfo()
382 {
383 CHK_IS_LOADV(isLoaded_, pointerInstance_)
384 pointerInstance_->InitScreenInfo();
385 }
386
EnableHardwareCursorStats(int32_t pid,bool enable)387 int32_t CursorDrawingComponent::EnableHardwareCursorStats(int32_t pid, bool enable)
388 {
389 CHK_IS_LOADR(isLoaded_, pointerInstance_)
390 return pointerInstance_->EnableHardwareCursorStats(pid, enable);
391 }
392
GetHardwareCursorStats(int32_t pid,uint32_t & frameCount,uint32_t & vsyncCount)393 int32_t CursorDrawingComponent::GetHardwareCursorStats(int32_t pid, uint32_t &frameCount, uint32_t &vsyncCount)
394 {
395 CHK_IS_LOADR(isLoaded_, pointerInstance_)
396 return pointerInstance_->GetHardwareCursorStats(pid, frameCount, vsyncCount);
397 }
398
GetCurrentDisplayInfo()399 OLD::DisplayInfo CursorDrawingComponent::GetCurrentDisplayInfo()
400 {
401 if (!isLoaded_ || (pointerInstance_ == nullptr)) {
402 MMI_HILOGE("%{public}s is closed", MULTIMODAL_PATH_NAME);
403 return OLD::DisplayInfo();
404 }
405 return pointerInstance_->GetCurrentDisplayInfo();
406 }
407
ForceClearPointerVisiableStatus()408 void CursorDrawingComponent::ForceClearPointerVisiableStatus()
409 {
410 CHK_IS_LOADV(isLoaded_, pointerInstance_)
411 return pointerInstance_->ForceClearPointerVisiableStatus();
412 }
413
InitPointerObserver()414 void CursorDrawingComponent::InitPointerObserver()
415 {
416 CHK_IS_LOADV(isLoaded_, pointerInstance_)
417 pointerInstance_->InitPointerObserver();
418 }
419
OnSessionLost(int32_t pid)420 void CursorDrawingComponent::OnSessionLost(int32_t pid)
421 {
422 CHK_IS_LOADV(isLoaded_, pointerInstance_)
423 pointerInstance_->OnSessionLost(pid);
424 }
425
SkipPointerLayer(bool isSkip)426 int32_t CursorDrawingComponent::SkipPointerLayer(bool isSkip)
427 {
428 CHK_IS_LOADR(isLoaded_, pointerInstance_)
429 return pointerInstance_->SkipPointerLayer(isSkip);
430 }
431
SetDelegateProxy(std::shared_ptr<DelegateInterface> proxy)432 void CursorDrawingComponent::SetDelegateProxy(std::shared_ptr<DelegateInterface> proxy)
433 {
434 CHK_IS_LOADV(isLoaded_, pointerInstance_)
435 pointerInstance_->SetDelegateProxy(proxy);
436 }
437
GetDelegateProxy()438 std::shared_ptr<DelegateInterface> CursorDrawingComponent::GetDelegateProxy()
439 {
440 if (!isLoaded_ || (pointerInstance_ == nullptr)) {
441 MMI_HILOGE("%{public}s is closed", MULTIMODAL_PATH_NAME);
442 return nullptr;
443 }
444 return pointerInstance_->GetDelegateProxy();
445 }
446
DestroyPointerWindow()447 void CursorDrawingComponent::DestroyPointerWindow()
448 {
449 CHK_IS_LOADV(isLoaded_, pointerInstance_)
450 pointerInstance_->DestroyPointerWindow();
451 }
452
DrawScreenCenterPointer(const PointerStyle & pointerStyle)453 void CursorDrawingComponent::DrawScreenCenterPointer(const PointerStyle &pointerStyle)
454 {
455 CHK_IS_LOADV(isLoaded_, pointerInstance_)
456 pointerInstance_->DrawScreenCenterPointer(pointerStyle);
457 }
458
SubscribeScreenModeChange()459 void CursorDrawingComponent::SubscribeScreenModeChange()
460 {
461 CHK_IS_LOADV(isLoaded_, pointerInstance_)
462 pointerInstance_->SubscribeScreenModeChange();
463 }
464
RegisterDisplayStatusReceiver()465 void CursorDrawingComponent::RegisterDisplayStatusReceiver()
466 {
467 CHK_IS_LOADV(isLoaded_, pointerInstance_)
468 pointerInstance_->RegisterDisplayStatusReceiver();
469 }
470
UpdateMouseLayer(const PointerStyle & pointerStyle,uint64_t displayId,int32_t physicalX,int32_t physicalY)471 int32_t CursorDrawingComponent::UpdateMouseLayer(
472 const PointerStyle &pointerStyle, uint64_t displayId, int32_t physicalX, int32_t physicalY)
473 {
474 CHK_IS_LOADR(isLoaded_, pointerInstance_)
475 return pointerInstance_->UpdateMouseLayer(pointerStyle, physicalX, physicalY);
476 }
477
DrawNewDpiPointer()478 int32_t CursorDrawingComponent::DrawNewDpiPointer()
479 {
480 CHK_IS_LOADR(isLoaded_, pointerInstance_)
481 return pointerInstance_->DrawNewDpiPointer();
482 }
483
GetHardCursorEnabled()484 bool CursorDrawingComponent::GetHardCursorEnabled()
485 {
486 CHK_IS_LOADF(isLoaded_, pointerInstance_)
487 return pointerInstance_->GetHardCursorEnabled();
488 }
489
490 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
GetPointerSnapshot(void * pixelMapPtr)491 int32_t CursorDrawingComponent::GetPointerSnapshot(void *pixelMapPtr)
492 {
493 CHK_IS_LOADR(isLoaded_, pointerInstance_)
494 return pointerInstance_->GetPointerSnapshot(pixelMapPtr);
495 }
496 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
497
498 #ifndef OHOS_BUILD_ENABLE_WATCH
NotifyPointerEventToRS(int32_t pointAction,int32_t pointCnt)499 void CursorDrawingComponent::NotifyPointerEventToRS(int32_t pointAction, int32_t pointCnt)
500 {
501 CHK_IS_LOADV(isLoaded_, pointerInstance_)
502 pointerInstance_->NotifyPointerEventToRS(pointAction, pointCnt);
503 }
504 #endif // OHOS_BUILD_ENABLE_WATCH
505 } // namespace OHOS
506