1 /*
2 * Copyright (c) 2022-2023 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 "core/pipeline/pipeline_base.h"
17
18 #include <fstream>
19
20 #include "base/log/ace_tracker.h"
21 #include "base/log/dump_log.h"
22 #include "base/log/event_report.h"
23 #include "core/common/ace_application_info.h"
24 #include "core/common/container.h"
25 #include "core/common/container_scope.h"
26 #include "core/common/font_manager.h"
27 #include "core/common/frontend.h"
28 #include "core/common/manager_interface.h"
29 #include "core/common/thread_checker.h"
30 #include "core/common/window.h"
31 #include "core/components/custom_paint/render_custom_paint.h"
32 #include "core/components_ng/render/animation_utils.h"
33 #include "core/image/image_provider.h"
34
35 namespace OHOS::Ace {
36
37 constexpr int32_t DEFAULT_VIEW_SCALE = 1;
38
PipelineBase(std::unique_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)39 PipelineBase::PipelineBase(std::unique_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
40 RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
41 : window_(std::move(window)), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
42 weakFrontend_(frontend), instanceId_(instanceId)
43 {
44 CHECK_NULL_VOID(frontend);
45 frontendType_ = frontend->GetType();
46 eventManager_ = AceType::MakeRefPtr<EventManager>();
47 windowManager_ = AceType::MakeRefPtr<WindowManager>();
48 eventManager_->SetInstanceId(instanceId);
49 imageCache_ = ImageCache::Create();
50 fontManager_ = FontManager::Create();
51 auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
52 const uint64_t nanoTimestamp, const uint32_t frameCount) {
53 ContainerScope scope(instanceId);
54 auto context = weak.Upgrade();
55 if (context) {
56 context->OnVsyncEvent(nanoTimestamp, frameCount);
57 }
58 };
59 ACE_DCHECK(window_);
60 window_->SetVsyncCallback(vsyncCallback);
61 }
62
PipelineBase(std::unique_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId,RefPtr<PlatformResRegister> platformResRegister)63 PipelineBase::PipelineBase(std::unique_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
64 RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId,
65 RefPtr<PlatformResRegister> platformResRegister)
66 : window_(std::move(window)), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
67 weakFrontend_(frontend), instanceId_(instanceId), platformResRegister_(std::move(platformResRegister))
68 {
69 CHECK_NULL_VOID(frontend);
70 frontendType_ = frontend->GetType();
71 eventManager_ = AceType::MakeRefPtr<EventManager>();
72 windowManager_ = AceType::MakeRefPtr<WindowManager>();
73 eventManager_->SetInstanceId(instanceId);
74 imageCache_ = ImageCache::Create();
75 fontManager_ = FontManager::Create();
76 auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
77 const uint64_t nanoTimestamp, const uint32_t frameCount) {
78 ContainerScope scope(instanceId);
79 auto context = weak.Upgrade();
80 if (context) {
81 context->OnVsyncEvent(nanoTimestamp, frameCount);
82 }
83 };
84 ACE_DCHECK(window_);
85 window_->SetVsyncCallback(vsyncCallback);
86 }
87
~PipelineBase()88 PipelineBase::~PipelineBase()
89 {
90 LOG_DESTROY();
91 }
92
GetCurrentContext()93 RefPtr<PipelineBase> PipelineBase::GetCurrentContext()
94 {
95 auto currentContainer = Container::Current();
96 CHECK_NULL_RETURN(currentContainer, nullptr);
97 return currentContainer->GetPipelineContext();
98 }
99
GetTimeFromExternalTimer()100 uint64_t PipelineBase::GetTimeFromExternalTimer()
101 {
102 static const int64_t secToNanosec = 1000000000;
103 struct timespec ts;
104 clock_gettime(CLOCK_MONOTONIC, &ts);
105 return (ts.tv_sec * secToNanosec + ts.tv_nsec);
106 }
107
RequestFrame()108 void PipelineBase::RequestFrame()
109 {
110 window_->RequestFrame();
111 }
112
GetFrontend() const113 RefPtr<Frontend> PipelineBase::GetFrontend() const
114 {
115 return weakFrontend_.Upgrade();
116 }
117
ClearImageCache()118 void PipelineBase::ClearImageCache()
119 {
120 if (imageCache_) {
121 imageCache_->Clear();
122 }
123 }
124
SetImageCache(const RefPtr<ImageCache> & imageChache)125 void PipelineBase::SetImageCache(const RefPtr<ImageCache>& imageChache)
126 {
127 std::lock_guard<std::shared_mutex> lock(imageCacheMutex_);
128 if (imageChache) {
129 imageCache_ = imageChache;
130 }
131 }
132
GetImageCache() const133 RefPtr<ImageCache> PipelineBase::GetImageCache() const
134 {
135 std::shared_lock<std::shared_mutex> lock(imageCacheMutex_);
136 return imageCache_;
137 }
138
SetRootSize(double density,int32_t width,int32_t height)139 void PipelineBase::SetRootSize(double density, int32_t width, int32_t height)
140 {
141 ACE_SCOPED_TRACE("SetRootSize(%lf, %d, %d)", density, width, height);
142 density_ = density;
143 taskExecutor_->PostTask(
144 [weak = AceType::WeakClaim(this), density, width, height]() {
145 auto context = weak.Upgrade();
146 if (!context) {
147 return;
148 }
149 context->SetRootRect(width, height);
150 },
151 TaskExecutor::TaskType::UI);
152 }
153
SetFontScale(float fontScale)154 void PipelineBase::SetFontScale(float fontScale)
155 {
156 const static float CARD_MAX_FONT_SCALE = 1.3f;
157 if (!NearEqual(fontScale_, fontScale)) {
158 fontScale_ = fontScale;
159 if (isJsCard_ && GreatOrEqual(fontScale_, CARD_MAX_FONT_SCALE)) {
160 fontScale_ = CARD_MAX_FONT_SCALE;
161 }
162 fontManager_->RebuildFontNode();
163 }
164 }
165
NormalizeToPx(const Dimension & dimension) const166 double PipelineBase::NormalizeToPx(const Dimension& dimension) const
167 {
168 if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
169 return (dimension.Value() * dipScale_);
170 } else if (dimension.Unit() == DimensionUnit::LPX) {
171 return (dimension.Value() * designWidthScale_);
172 }
173 return dimension.Value();
174 }
175
ConvertPxToVp(const Dimension & dimension) const176 double PipelineBase::ConvertPxToVp(const Dimension& dimension) const
177 {
178 if (dimension.Unit() == DimensionUnit::PX) {
179 return dimension.Value() / dipScale_;
180 }
181 return dimension.Value();
182 }
183
UpdateFontWeightScale()184 void PipelineBase::UpdateFontWeightScale()
185 {
186 if (fontManager_) {
187 fontManager_->UpdateFontWeightScale();
188 }
189 }
190
SetTextFieldManager(const RefPtr<ManagerInterface> & manager)191 void PipelineBase::SetTextFieldManager(const RefPtr<ManagerInterface>& manager)
192 {
193 textFieldManager_ = manager;
194 }
195
RegisterFont(const std::string & familyName,const std::string & familySrc)196 void PipelineBase::RegisterFont(const std::string& familyName, const std::string& familySrc)
197 {
198 if (fontManager_) {
199 fontManager_->RegisterFont(familyName, familySrc, AceType::Claim(this));
200 }
201 }
202
HyperlinkStartAbility(const std::string & address) const203 void PipelineBase::HyperlinkStartAbility(const std::string& address) const
204 {
205 CHECK_RUN_ON(UI);
206 if (startAbilityHandler_) {
207 startAbilityHandler_(address);
208 } else {
209 LOGE("Hyperlink fail to start ability due to handler is nullptr");
210 }
211 }
212
NotifyStatusBarBgColor(const Color & color) const213 void PipelineBase::NotifyStatusBarBgColor(const Color& color) const
214 {
215 CHECK_RUN_ON(UI);
216 LOGD("Notify StatusBar BgColor, color: %{public}x", color.GetValue());
217 if (statusBarBgColorEventHandler_) {
218 statusBarBgColorEventHandler_(color);
219 } else {
220 LOGE("fail to finish current context due to handler is nullptr");
221 }
222 }
223
NotifyPopupDismiss() const224 void PipelineBase::NotifyPopupDismiss() const
225 {
226 CHECK_RUN_ON(UI);
227 if (popupEventHandler_) {
228 popupEventHandler_();
229 }
230 }
231
NotifyRouterBackDismiss() const232 void PipelineBase::NotifyRouterBackDismiss() const
233 {
234 CHECK_RUN_ON(UI);
235 if (routerBackEventHandler_) {
236 routerBackEventHandler_();
237 }
238 }
239
NotifyPopPageSuccessDismiss(const std::string & pageUrl,const int32_t pageId) const240 void PipelineBase::NotifyPopPageSuccessDismiss(const std::string& pageUrl, const int32_t pageId) const
241 {
242 CHECK_RUN_ON(UI);
243 for (auto& iterPopSuccessHander : popPageSuccessEventHandler_) {
244 if (iterPopSuccessHander) {
245 iterPopSuccessHander(pageUrl, pageId);
246 }
247 }
248 }
249
NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const250 void PipelineBase::NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const
251 {
252 CHECK_RUN_ON(UI);
253 for (auto& iterPathInvalidHandler : isPagePathInvalidEventHandler_) {
254 if (iterPathInvalidHandler) {
255 iterPathInvalidHandler(isPageInvalid);
256 }
257 }
258 }
259
NotifyDestroyEventDismiss() const260 void PipelineBase::NotifyDestroyEventDismiss() const
261 {
262 CHECK_RUN_ON(UI);
263 for (auto& iterDestroyEventHander : destroyEventHandler_) {
264 if (iterDestroyEventHander) {
265 iterDestroyEventHander();
266 }
267 }
268 }
269
NotifyDispatchTouchEventDismiss(const TouchEvent & event) const270 void PipelineBase::NotifyDispatchTouchEventDismiss(const TouchEvent& event) const
271 {
272 CHECK_RUN_ON(UI);
273 for (auto& iterDispatchTouchEventHander : dispatchTouchEventHandler_) {
274 if (iterDispatchTouchEventHander) {
275 iterDispatchTouchEventHander(event);
276 }
277 }
278 }
279
OnActionEvent(const std::string & action)280 void PipelineBase::OnActionEvent(const std::string& action)
281 {
282 CHECK_RUN_ON(UI);
283 if (actionEventHandler_) {
284 actionEventHandler_(action);
285 } else {
286 LOGE("the action event handler is null");
287 }
288 }
289
onRouterChange(const std::string & url)290 void PipelineBase::onRouterChange(const std::string& url)
291 {
292 if (onRouterChangeCallback_ != nullptr) {
293 onRouterChangeCallback_(url);
294 }
295 }
296
TryLoadImageInfo(const std::string & src,std::function<void (bool,int32_t,int32_t)> && loadCallback)297 void PipelineBase::TryLoadImageInfo(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& loadCallback)
298 {
299 ImageProvider::TryLoadImageInfo(AceType::Claim(this), src, std::move(loadCallback));
300 }
301
CreateOffscreenCanvas(int32_t width,int32_t height)302 RefPtr<OffscreenCanvas> PipelineBase::CreateOffscreenCanvas(int32_t width, int32_t height)
303 {
304 return RenderOffscreenCanvas::Create(AceType::WeakClaim(this), width, height);
305 }
306
PostAsyncEvent(TaskExecutor::Task && task,TaskExecutor::TaskType type)307 void PipelineBase::PostAsyncEvent(TaskExecutor::Task&& task, TaskExecutor::TaskType type)
308 {
309 if (taskExecutor_) {
310 taskExecutor_->PostTask(std::move(task), type);
311 } else {
312 LOGE("the task executor is nullptr");
313 }
314 }
315
PostAsyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)316 void PipelineBase::PostAsyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
317 {
318 if (taskExecutor_) {
319 taskExecutor_->PostTask(task, type);
320 } else {
321 LOGE("the task executor is nullptr");
322 }
323 }
324
PostSyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)325 void PipelineBase::PostSyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
326 {
327 if (taskExecutor_) {
328 taskExecutor_->PostSyncTask(task, type);
329 } else {
330 LOGE("the task executor is nullptr");
331 }
332 }
333
UpdateRootSizeAndScale(int32_t width,int32_t height)334 void PipelineBase::UpdateRootSizeAndScale(int32_t width, int32_t height)
335 {
336 auto frontend = weakFrontend_.Upgrade();
337 CHECK_NULL_VOID(frontend);
338 auto& windowConfig = frontend->GetWindowConfig();
339 if (windowConfig.designWidth <= 0) {
340 LOGE("the frontend design width <= 0");
341 return;
342 }
343 if (GetIsDeclarative()) {
344 viewScale_ = DEFAULT_VIEW_SCALE;
345 designWidthScale_ = static_cast<double>(width) / windowConfig.designWidth;
346 windowConfig.designWidthScale = designWidthScale_;
347 } else {
348 viewScale_ = windowConfig.autoDesignWidth ? density_ : static_cast<double>(width) / windowConfig.designWidth;
349 }
350 if (NearZero(viewScale_)) {
351 LOGW("the view scale is zero");
352 return;
353 }
354 dipScale_ = density_ / viewScale_;
355 rootHeight_ = height / viewScale_;
356 rootWidth_ = width / viewScale_;
357 }
358
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)359 void PipelineBase::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
360 {
361 if (isDumping_.test_and_set()) {
362 LOGI("another dump is still running");
363 return;
364 }
365 auto result = false;
366 if (!SystemProperties::GetDebugEnabled()) {
367 std::unique_ptr<std::ostream> ss = std::make_unique<std::ostringstream>();
368 CHECK_NULL_VOID(ss);
369 DumpLog::GetInstance().SetDumpFile(std::move(ss));
370 result = Dump(params);
371 const auto& infoFile = DumpLog::GetInstance().GetDumpFile();
372 auto* ostringstream = static_cast<std::ostringstream*>(infoFile.get());
373 info.emplace_back(ostringstream->str().substr(0, DumpLog::MAX_DUMP_LENGTH));
374 DumpLog::GetInstance().Reset();
375 } else {
376 auto dumpFilePath = AceApplicationInfo::GetInstance().GetDataFileDirPath() + "/arkui.dump";
377 std::unique_ptr<std::ostream> ss = std::make_unique<std::ofstream>(dumpFilePath);
378 CHECK_NULL_VOID(ss);
379 DumpLog::GetInstance().SetDumpFile(std::move(ss));
380 result = Dump(params);
381 info.emplace_back("dumpFilePath: " + dumpFilePath);
382 DumpLog::GetInstance().Reset();
383 }
384 if (!result) {
385 DumpLog::ShowDumpHelp(info);
386 }
387 isDumping_.clear();
388 }
389
DumpFrontend() const390 void PipelineBase::DumpFrontend() const
391 {
392 auto frontend = weakFrontend_.Upgrade();
393 if (frontend) {
394 frontend->DumpFrontend();
395 }
396 }
397
Dump(const std::vector<std::string> & params) const398 bool PipelineBase::Dump(const std::vector<std::string>& params) const
399 {
400 if (params.empty()) {
401 LOGW("the params is empty");
402 return false;
403 }
404 // the first param is the key word of dump.
405 #ifdef ACE_MEMORY_MONITOR
406 if (params[0] == "-memory") {
407 MemoryMonitor::GetInstance().Dump();
408 return true;
409 }
410 #endif
411 if (params[0] == "-jscrash") {
412 EventReport::JsErrReport(
413 AceApplicationInfo::GetInstance().GetPackageName(), "js crash reason", "js crash summary");
414 return true;
415 }
416 // hiview report dump will provide three params .
417 if (params[0] == "-hiviewreport" && params.size() >= 3) {
418 DumpLog::GetInstance().Print("Report hiview event. EventType: " + params[1] + ", error type: " + params[2]);
419 EventInfo eventInfo = { .eventType = params[1], .errorType = StringUtils::StringToInt(params[2]) };
420 EventReport::SendEvent(eventInfo);
421 return true;
422 }
423 ContainerScope scope(instanceId_);
424 if (params[0] == "-frontend") {
425 DumpFrontend();
426 return true;
427 }
428 return OnDumpInfo(params);
429 }
430
ForceLayoutForImplicitAnimation()431 void PipelineBase::ForceLayoutForImplicitAnimation()
432 {
433 if (!pendingImplicitLayout_.empty()) {
434 pendingImplicitLayout_.top() = true;
435 }
436 }
437
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback,const std::function<void ()> & finishCallback)438 bool PipelineBase::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
439 const std::function<void()>& propertyCallback, const std::function<void()>& finishCallback)
440 {
441 if (!propertyCallback) {
442 LOGE("failed to create animation, property callback is null!");
443 return false;
444 }
445
446 OpenImplicitAnimation(option, curve, finishCallback);
447 propertyCallback();
448 return CloseImplicitAnimation();
449 }
450
PrepareOpenImplicitAnimation()451 void PipelineBase::PrepareOpenImplicitAnimation()
452 {
453 #ifdef ENABLE_ROSEN_BACKEND
454 if (!SystemProperties::GetRosenBackendEnabled()) {
455 LOGE("rosen backend is disabled");
456 return;
457 }
458
459 // initialize false for implicit animation layout pending flag
460 pendingImplicitLayout_.push(false);
461 FlushUITasks();
462 #endif
463 }
464
PrepareCloseImplicitAnimation()465 void PipelineBase::PrepareCloseImplicitAnimation()
466 {
467 #ifdef ENABLE_ROSEN_BACKEND
468 if (!SystemProperties::GetRosenBackendEnabled()) {
469 LOGE("rosen backend is disabled!");
470 return;
471 }
472
473 if (pendingImplicitLayout_.empty()) {
474 LOGE("close implicit animation failed, need to open implicit animation first!");
475 return;
476 }
477
478 // layout the views immediately to animate all related views, if layout updates are pending in the animation closure
479 if (pendingImplicitLayout_.top()) {
480 FlushUITasks();
481 }
482 if (!pendingImplicitLayout_.empty()) {
483 pendingImplicitLayout_.pop();
484 }
485 #endif
486 }
487
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)488 void PipelineBase::OpenImplicitAnimation(
489 const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
490 {
491 #ifdef ENABLE_ROSEN_BACKEND
492 PrepareOpenImplicitAnimation();
493
494 auto wrapFinishCallback = [weak = AceType::WeakClaim(this), finishCallback]() {
495 auto context = weak.Upgrade();
496 if (!context) {
497 return;
498 }
499 context->GetTaskExecutor()->PostTask(
500 [finishCallback]() {
501 if (finishCallback) {
502 finishCallback();
503 }
504 },
505 TaskExecutor::TaskType::UI);
506 };
507 AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
508 #endif
509 }
510
CloseImplicitAnimation()511 bool PipelineBase::CloseImplicitAnimation()
512 {
513 #ifdef ENABLE_ROSEN_BACKEND
514 PrepareCloseImplicitAnimation();
515 return AnimationUtils::CloseImplicitAnimation();
516 #else
517 return false;
518 #endif
519 }
520
OnVsyncEvent(uint64_t nanoTimestamp,uint32_t frameCount)521 void PipelineBase::OnVsyncEvent(uint64_t nanoTimestamp, uint32_t frameCount)
522 {
523 CHECK_RUN_ON(UI);
524 ACE_FUNCTION_TRACE();
525 if (onVsyncProfiler_) {
526 AceTracker::Start();
527 }
528 FlushVsync(nanoTimestamp, frameCount);
529 if (onVsyncProfiler_) {
530 onVsyncProfiler_(AceTracker::Stop());
531 }
532 }
533
SetTouchPipeline(const WeakPtr<PipelineBase> & context)534 void PipelineBase::SetTouchPipeline(const WeakPtr<PipelineBase>& context)
535 {
536 auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
537 if (result == touchPluginPipelineContext_.end()) {
538 touchPluginPipelineContext_.emplace_back(context);
539 }
540 }
541
RemoveTouchPipeline(const WeakPtr<PipelineBase> & context)542 void PipelineBase::RemoveTouchPipeline(const WeakPtr<PipelineBase>& context)
543 {
544 auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
545 if (result != touchPluginPipelineContext_.end()) {
546 touchPluginPipelineContext_.erase(result);
547 }
548 }
549
OnVirtualKeyboardAreaChange(Rect keyboardArea)550 void PipelineBase::OnVirtualKeyboardAreaChange(Rect keyboardArea)
551 {
552 double keyboardHeight = keyboardArea.Height();
553 if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight)) {
554 return;
555 }
556 OnVirtualKeyboardHeightChange(keyboardHeight);
557 }
558
SetGetWindowRectImpl(std::function<Rect ()> && callback)559 void PipelineBase::SetGetWindowRectImpl(std::function<Rect()>&& callback)
560 {
561 if (window_) {
562 window_->SetGetWindowRectImpl(std::move(callback));
563 }
564 }
565
GetCurrentWindowRect() const566 Rect PipelineBase::GetCurrentWindowRect() const
567 {
568 if (window_) {
569 return window_->GetCurrentWindowRect();
570 }
571 return {};
572 }
573
GetAccessibilityManager() const574 RefPtr<AccessibilityManager> PipelineBase::GetAccessibilityManager() const
575 {
576 auto frontend = weakFrontend_.Upgrade();
577 if (!frontend) {
578 LOGE("frontend is nullptr");
579 EventReport::SendAppStartException(AppStartExcepType::PIPELINE_CONTEXT_ERR);
580 return nullptr;
581 }
582 return frontend->GetAccessibilityManager();
583 }
584
SendEventToAccessibility(const AccessibilityEvent & accessibilityEvent)585 void PipelineBase::SendEventToAccessibility(const AccessibilityEvent& accessibilityEvent)
586 {
587 auto accessibilityManager = GetAccessibilityManager();
588 if (!accessibilityManager) {
589 return;
590 }
591 accessibilityManager->SendAccessibilityAsyncEvent(accessibilityEvent);
592 }
593
AddEtsCardTouchEventCallback(int32_t ponitId,EtsCardTouchEventCallback && callback)594 void PipelineBase::AddEtsCardTouchEventCallback(int32_t ponitId, EtsCardTouchEventCallback&& callback)
595 {
596 if (!callback || ponitId < 0) {
597 return;
598 }
599
600 etsCardTouchEventCallback_[ponitId] = std::move(callback);
601 }
602
HandleEtsCardTouchEvent(const TouchEvent & point)603 void PipelineBase::HandleEtsCardTouchEvent(const TouchEvent& point)
604 {
605 if (point.id < 0) {
606 return;
607 }
608
609 auto iter = etsCardTouchEventCallback_.find(point.id);
610 if (iter == etsCardTouchEventCallback_.end()) {
611 return;
612 }
613
614 if (iter->second) {
615 iter->second(point);
616 }
617 }
618
RemoveEtsCardTouchEventCallback(int32_t ponitId)619 void PipelineBase::RemoveEtsCardTouchEventCallback(int32_t ponitId)
620 {
621 if (ponitId < 0) {
622 return;
623 }
624
625 auto iter = etsCardTouchEventCallback_.find(ponitId);
626 if (iter == etsCardTouchEventCallback_.end()) {
627 return;
628 }
629
630 etsCardTouchEventCallback_.erase(iter);
631 }
632
Destroy()633 void PipelineBase::Destroy()
634 {
635 CHECK_RUN_ON(UI);
636 LOGI("PipelineBase::Destroy begin.");
637 ClearImageCache();
638 platformResRegister_.Reset();
639 drawDelegate_.reset();
640 eventManager_->ClearResults();
641 {
642 std::unique_lock<std::shared_mutex> lock(imageCacheMutex_);
643 imageCache_.Reset();
644 }
645 fontManager_.Reset();
646 themeManager_.Reset();
647 window_->Destroy();
648 touchPluginPipelineContext_.clear();
649 virtualKeyBoardCallback_.clear();
650 etsCardTouchEventCallback_.clear();
651 LOGI("PipelineBase::Destroy end.");
652 }
653
654 } // namespace OHOS::Ace
655