• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cinttypes>
19 
20 #include "base/log/ace_tracker.h"
21 #include "base/log/dump_log.h"
22 #include "base/log/event_report.h"
23 #include "base/subwindow/subwindow_manager.h"
24 #include "base/utils/system_properties.h"
25 #include "base/utils/utils.h"
26 #include "core/common/ace_application_info.h"
27 #include "core/common/container.h"
28 #include "core/common/container_scope.h"
29 #include "core/common/font_manager.h"
30 #include "core/common/frontend.h"
31 #include "core/common/manager_interface.h"
32 #include "core/common/thread_checker.h"
33 #include "core/common/window.h"
34 #include "core/components/common/layout/constants.h"
35 #include "core/components/custom_paint/render_custom_paint.h"
36 #include "core/components_ng/render/animation_utils.h"
37 #include "core/image/image_provider.h"
38 
39 #ifdef PLUGIN_COMPONENT_SUPPORTED
40 #include "core/common/plugin_manager.h"
41 #endif
42 
43 namespace OHOS::Ace {
44 
45 constexpr int32_t DEFAULT_VIEW_SCALE = 1;
46 
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)47 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
48     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
49     : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
50       weakFrontend_(frontend), instanceId_(instanceId)
51 {
52     CHECK_NULL_VOID(frontend);
53     frontendType_ = frontend->GetType();
54     eventManager_ = AceType::MakeRefPtr<EventManager>();
55     windowManager_ = AceType::MakeRefPtr<WindowManager>();
56     eventManager_->SetInstanceId(instanceId);
57     imageCache_ = ImageCache::Create();
58     fontManager_ = FontManager::Create();
59     auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
60                                const uint64_t nanoTimestamp, const uint32_t frameCount) {
61         ContainerScope scope(instanceId);
62         auto context = weak.Upgrade();
63         if (context) {
64             context->OnVsyncEvent(nanoTimestamp, frameCount);
65         }
66     };
67     ACE_DCHECK(window_);
68     window_->SetVsyncCallback(vsyncCallback);
69 }
70 
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId,RefPtr<PlatformResRegister> platformResRegister)71 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
72     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId,
73     RefPtr<PlatformResRegister> platformResRegister)
74     : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
75       weakFrontend_(frontend), instanceId_(instanceId), platformResRegister_(std::move(platformResRegister))
76 {
77     CHECK_NULL_VOID(frontend);
78     frontendType_ = frontend->GetType();
79     eventManager_ = AceType::MakeRefPtr<EventManager>();
80     windowManager_ = AceType::MakeRefPtr<WindowManager>();
81     eventManager_->SetInstanceId(instanceId);
82     imageCache_ = ImageCache::Create();
83     fontManager_ = FontManager::Create();
84     auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
85                                const uint64_t nanoTimestamp, const uint32_t frameCount) {
86         ContainerScope scope(instanceId);
87         auto context = weak.Upgrade();
88         if (context) {
89             context->OnVsyncEvent(nanoTimestamp, frameCount);
90         }
91     };
92     ACE_DCHECK(window_);
93     window_->SetVsyncCallback(vsyncCallback);
94 }
95 
~PipelineBase()96 PipelineBase::~PipelineBase()
97 {
98     LOG_DESTROY();
99 }
100 
GetCurrentContext()101 RefPtr<PipelineBase> PipelineBase::GetCurrentContext()
102 {
103     auto currentContainer = Container::Current();
104     CHECK_NULL_RETURN(currentContainer, nullptr);
105     return currentContainer->GetPipelineContext();
106 }
107 
CurrentThemeManager()108 RefPtr<ThemeManager> PipelineBase::CurrentThemeManager()
109 {
110     auto pipelineContext = OHOS::Ace::PipelineBase::GetCurrentContext();
111 #ifdef PLUGIN_COMPONENT_SUPPORTED
112     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
113         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
114         CHECK_NULL_RETURN(pluginContainer, nullptr);
115         pipelineContext = pluginContainer->GetPipelineContext();
116     }
117 #endif
118     CHECK_NULL_RETURN(pipelineContext, nullptr);
119     return pipelineContext->GetThemeManager();
120 }
121 
GetTimeFromExternalTimer()122 uint64_t PipelineBase::GetTimeFromExternalTimer()
123 {
124     static const int64_t secToNanosec = 1000000000;
125     struct timespec ts;
126     clock_gettime(CLOCK_MONOTONIC, &ts);
127     return (ts.tv_sec * secToNanosec + ts.tv_nsec);
128 }
129 
RequestFrame()130 void PipelineBase::RequestFrame()
131 {
132     window_->RequestFrame();
133 }
134 
GetFrontend() const135 RefPtr<Frontend> PipelineBase::GetFrontend() const
136 {
137     return weakFrontend_.Upgrade();
138 }
139 
ClearImageCache()140 void PipelineBase::ClearImageCache()
141 {
142     std::lock_guard<std::shared_mutex> lock(imageMtx_);
143     if (imageCache_) {
144         imageCache_->Clear();
145     }
146 }
147 
SetImageCache(const RefPtr<ImageCache> & imageCache)148 void PipelineBase::SetImageCache(const RefPtr<ImageCache>& imageCache)
149 {
150     std::lock_guard<std::shared_mutex> lock(imageMtx_);
151     if (imageCache) {
152         imageCache_ = imageCache;
153     }
154 }
155 
GetImageCache() const156 RefPtr<ImageCache> PipelineBase::GetImageCache() const
157 {
158     std::shared_lock<std::shared_mutex> lock(imageMtx_);
159     return imageCache_;
160 }
161 
SetRootSize(double density,int32_t width,int32_t height)162 void PipelineBase::SetRootSize(double density, int32_t width, int32_t height)
163 {
164     ACE_SCOPED_TRACE("SetRootSize(%lf, %d, %d)", density, width, height);
165     density_ = density;
166     auto task = [weak = AceType::WeakClaim(this), density, width, height]() {
167         auto context = weak.Upgrade();
168         if (!context) {
169             return;
170         }
171         context->SetRootRect(width, height);
172     };
173 #ifdef NG_BUILD
174     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
175         task();
176     } else {
177         taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
178     }
179 #else
180     taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
181 #endif
182 }
183 
SetFontScale(float fontScale)184 void PipelineBase::SetFontScale(float fontScale)
185 {
186     const static float CARD_MAX_FONT_SCALE = 1.3f;
187     if (!NearEqual(fontScale_, fontScale)) {
188         fontScale_ = fontScale;
189         if (isJsCard_ && GreatOrEqual(fontScale_, CARD_MAX_FONT_SCALE)) {
190             fontScale_ = CARD_MAX_FONT_SCALE;
191         }
192         fontManager_->RebuildFontNode();
193     }
194 }
195 
NormalizeToPx(const Dimension & dimension) const196 double PipelineBase::NormalizeToPx(const Dimension& dimension) const
197 {
198     if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
199         return (dimension.Value() * dipScale_);
200     } else if (dimension.Unit() == DimensionUnit::LPX) {
201         return (dimension.Value() * designWidthScale_);
202     }
203     return dimension.Value();
204 }
205 
ConvertPxToVp(const Dimension & dimension) const206 double PipelineBase::ConvertPxToVp(const Dimension& dimension) const
207 {
208     if (dimension.Unit() == DimensionUnit::PX) {
209         return dimension.Value() / dipScale_;
210     }
211     return dimension.Value();
212 }
213 
UpdateFontWeightScale()214 void PipelineBase::UpdateFontWeightScale()
215 {
216     if (fontManager_) {
217         fontManager_->UpdateFontWeightScale();
218     }
219 }
220 
SetTextFieldManager(const RefPtr<ManagerInterface> & manager)221 void PipelineBase::SetTextFieldManager(const RefPtr<ManagerInterface>& manager)
222 {
223     textFieldManager_ = manager;
224 }
225 
RegisterFont(const std::string & familyName,const std::string & familySrc)226 void PipelineBase::RegisterFont(const std::string& familyName, const std::string& familySrc)
227 {
228     if (fontManager_) {
229         fontManager_->RegisterFont(familyName, familySrc, AceType::Claim(this));
230     }
231 }
232 
GetSystemFontList(std::vector<std::string> & fontList)233 void PipelineBase::GetSystemFontList(std::vector<std::string>& fontList)
234 {
235     if (fontManager_) {
236         fontManager_->GetSystemFontList(fontList);
237     }
238 }
239 
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)240 bool PipelineBase::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
241 {
242     if (fontManager_) {
243         return fontManager_->GetSystemFont(fontName, fontInfo);
244     }
245     return false;
246 }
247 
HyperlinkStartAbility(const std::string & address) const248 void PipelineBase::HyperlinkStartAbility(const std::string& address) const
249 {
250     CHECK_RUN_ON(UI);
251     if (startAbilityHandler_) {
252         startAbilityHandler_(address);
253     } else {
254         LOGE("Hyperlink fail to start ability due to handler is nullptr");
255     }
256 }
257 
NotifyStatusBarBgColor(const Color & color) const258 void PipelineBase::NotifyStatusBarBgColor(const Color& color) const
259 {
260     CHECK_RUN_ON(UI);
261     LOGD("Notify StatusBar BgColor, color: %{public}x", color.GetValue());
262     if (statusBarBgColorEventHandler_) {
263         statusBarBgColorEventHandler_(color);
264     } else {
265         LOGE("fail to finish current context due to handler is nullptr");
266     }
267 }
268 
NotifyPopupDismiss() const269 void PipelineBase::NotifyPopupDismiss() const
270 {
271     CHECK_RUN_ON(UI);
272     if (popupEventHandler_) {
273         popupEventHandler_();
274     }
275 }
276 
NotifyMenuDismiss() const277 void PipelineBase::NotifyMenuDismiss() const
278 {
279     CHECK_RUN_ON(UI);
280     if (menuEventHandler_) {
281         menuEventHandler_();
282     }
283 }
284 
NotifyContextMenuDismiss() const285 void PipelineBase::NotifyContextMenuDismiss() const
286 {
287     CHECK_RUN_ON(UI);
288     if (contextMenuEventHandler_) {
289         contextMenuEventHandler_();
290     }
291 }
292 
NotifyRouterBackDismiss() const293 void PipelineBase::NotifyRouterBackDismiss() const
294 {
295     CHECK_RUN_ON(UI);
296     if (routerBackEventHandler_) {
297         routerBackEventHandler_();
298     }
299 }
300 
NotifyPopPageSuccessDismiss(const std::string & pageUrl,const int32_t pageId) const301 void PipelineBase::NotifyPopPageSuccessDismiss(const std::string& pageUrl, const int32_t pageId) const
302 {
303     CHECK_RUN_ON(UI);
304     for (auto& iterPopSuccessHander : popPageSuccessEventHandler_) {
305         if (iterPopSuccessHander) {
306             iterPopSuccessHander(pageUrl, pageId);
307         }
308     }
309 }
310 
NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const311 void PipelineBase::NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const
312 {
313     CHECK_RUN_ON(UI);
314     for (auto& iterPathInvalidHandler : isPagePathInvalidEventHandler_) {
315         if (iterPathInvalidHandler) {
316             iterPathInvalidHandler(isPageInvalid);
317         }
318     }
319 }
320 
NotifyDestroyEventDismiss() const321 void PipelineBase::NotifyDestroyEventDismiss() const
322 {
323     CHECK_RUN_ON(UI);
324     for (auto& iterDestroyEventHander : destroyEventHandler_) {
325         if (iterDestroyEventHander) {
326             iterDestroyEventHander();
327         }
328     }
329 }
330 
NotifyDispatchTouchEventDismiss(const TouchEvent & event) const331 void PipelineBase::NotifyDispatchTouchEventDismiss(const TouchEvent& event) const
332 {
333     CHECK_RUN_ON(UI);
334     for (auto& iterDispatchTouchEventHandler : dispatchTouchEventHandler_) {
335         if (iterDispatchTouchEventHandler) {
336             iterDispatchTouchEventHandler(event);
337         }
338     }
339 }
340 
OnActionEvent(const std::string & action)341 void PipelineBase::OnActionEvent(const std::string& action)
342 {
343     CHECK_RUN_ON(UI);
344     if (actionEventHandler_) {
345         actionEventHandler_(action);
346     } else {
347         LOGE("the action event handler is null");
348     }
349 }
350 
onRouterChange(const std::string & url)351 void PipelineBase::onRouterChange(const std::string& url)
352 {
353     if (onRouterChangeCallback_ != nullptr) {
354         onRouterChangeCallback_(url);
355     }
356 }
357 
TryLoadImageInfo(const std::string & src,std::function<void (bool,int32_t,int32_t)> && loadCallback)358 void PipelineBase::TryLoadImageInfo(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& loadCallback)
359 {
360     ImageProvider::TryLoadImageInfo(AceType::Claim(this), src, std::move(loadCallback));
361 }
362 
CreateOffscreenCanvas(int32_t width,int32_t height)363 RefPtr<OffscreenCanvas> PipelineBase::CreateOffscreenCanvas(int32_t width, int32_t height)
364 {
365     return RenderOffscreenCanvas::Create(AceType::WeakClaim(this), width, height);
366 }
367 
PostAsyncEvent(TaskExecutor::Task && task,TaskExecutor::TaskType type)368 void PipelineBase::PostAsyncEvent(TaskExecutor::Task&& task, TaskExecutor::TaskType type)
369 {
370     if (taskExecutor_) {
371         taskExecutor_->PostTask(std::move(task), type);
372     } else {
373         LOGE("the task executor is nullptr");
374     }
375 }
376 
PostAsyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)377 void PipelineBase::PostAsyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
378 {
379     if (taskExecutor_) {
380         taskExecutor_->PostTask(task, type);
381     } else {
382         LOGE("the task executor is nullptr");
383     }
384 }
385 
PostSyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)386 void PipelineBase::PostSyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
387 {
388     if (taskExecutor_) {
389         taskExecutor_->PostSyncTask(task, type);
390     } else {
391         LOGE("the task executor is nullptr");
392     }
393 }
394 
UpdateRootSizeAndScale(int32_t width,int32_t height)395 void PipelineBase::UpdateRootSizeAndScale(int32_t width, int32_t height)
396 {
397     auto frontend = weakFrontend_.Upgrade();
398     CHECK_NULL_VOID(frontend);
399     auto lock = frontend->GetLock();
400     auto& windowConfig = frontend->GetWindowConfig();
401     if (windowConfig.designWidth <= 0) {
402         LOGE("the frontend design width <= 0");
403         return;
404     }
405     if (GetIsDeclarative()) {
406         viewScale_ = DEFAULT_VIEW_SCALE;
407         designWidthScale_ = static_cast<double>(width) / windowConfig.designWidth;
408         windowConfig.designWidthScale = designWidthScale_;
409     } else {
410         viewScale_ = windowConfig.autoDesignWidth ? density_ : static_cast<double>(width) / windowConfig.designWidth;
411     }
412     if (NearZero(viewScale_)) {
413         LOGW("the view scale is zero");
414         return;
415     }
416     dipScale_ = density_ / viewScale_;
417     rootHeight_ = height / viewScale_;
418     rootWidth_ = width / viewScale_;
419 }
420 
DumpFrontend() const421 void PipelineBase::DumpFrontend() const
422 {
423     auto frontend = weakFrontend_.Upgrade();
424     CHECK_NULL_VOID(frontend);
425     auto lock = frontend->GetLock();
426     frontend->DumpFrontend();
427 }
428 
Dump(const std::vector<std::string> & params) const429 bool PipelineBase::Dump(const std::vector<std::string>& params) const
430 {
431     if (params.empty()) {
432         LOGW("the params is empty");
433         return false;
434     }
435     // the first param is the key word of dump.
436     if (params[0] == "-memory") {
437         MemoryMonitor::GetInstance().Dump();
438         return true;
439     }
440     if (params[0] == "-jscrash") {
441         EventReport::JsErrReport(
442             AceApplicationInfo::GetInstance().GetPackageName(), "js crash reason", "js crash summary");
443         return true;
444     }
445     // hiview report dump will provide three params .
446     if (params[0] == "-hiviewreport" && params.size() >= 3) {
447         DumpLog::GetInstance().Print("Report hiview event. EventType: " + params[1] + ", error type: " + params[2]);
448         EventInfo eventInfo = { .eventType = params[1], .errorType = StringUtils::StringToInt(params[2]) };
449         EventReport::SendEvent(eventInfo);
450         return true;
451     }
452     ContainerScope scope(instanceId_);
453     if (params[0] == "-frontend") {
454         DumpFrontend();
455         return true;
456     }
457     return OnDumpInfo(params);
458 }
459 
ForceLayoutForImplicitAnimation()460 void PipelineBase::ForceLayoutForImplicitAnimation()
461 {
462     if (!pendingImplicitLayout_.empty()) {
463         pendingImplicitLayout_.top() = true;
464     }
465 }
466 
ForceRenderForImplicitAnimation()467 void PipelineBase::ForceRenderForImplicitAnimation()
468 {
469     if (!pendingImplicitRender_.empty()) {
470         pendingImplicitRender_.top() = true;
471     }
472 }
473 
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback,const std::function<void ()> & finishCallback)474 bool PipelineBase::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
475     const std::function<void()>& propertyCallback, const std::function<void()>& finishCallback)
476 {
477     if (!propertyCallback) {
478         LOGE("failed to create animation, property callback is null!");
479         return false;
480     }
481 
482     OpenImplicitAnimation(option, curve, finishCallback);
483     propertyCallback();
484     return CloseImplicitAnimation();
485 }
486 
PrepareOpenImplicitAnimation()487 void PipelineBase::PrepareOpenImplicitAnimation()
488 {
489 #ifdef ENABLE_ROSEN_BACKEND
490     // initialize false for implicit animation layout and render pending flag
491     pendingImplicitLayout_.push(false);
492     pendingImplicitRender_.push(false);
493 
494     // flush ui tasks before open implicit animation
495     if (!isReloading_ && !IsLayouting()) {
496         FlushUITasks();
497     }
498 #endif
499 }
500 
PrepareCloseImplicitAnimation()501 void PipelineBase::PrepareCloseImplicitAnimation()
502 {
503 #ifdef ENABLE_ROSEN_BACKEND
504     if (pendingImplicitLayout_.empty() && pendingImplicitRender_.empty()) {
505         LOGE("close implicit animation failed, need to open implicit animation first!");
506         return;
507     }
508 
509     // layout or render the views immediately to animate all related views, if layout or render updates are pending in
510     // the animation closure
511     if (pendingImplicitLayout_.top() || pendingImplicitRender_.top()) {
512         if (!isReloading_ && !IsLayouting()) {
513             FlushUITasks();
514         } else if (IsLayouting()) {
515             LOGW("IsLayouting, prepareCloseImplicitAnimation has tasks not flushed");
516         }
517     }
518     if (!pendingImplicitLayout_.empty()) {
519         pendingImplicitLayout_.pop();
520     }
521     if (!pendingImplicitRender_.empty()) {
522         pendingImplicitRender_.pop();
523     }
524 #endif
525 }
526 
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)527 void PipelineBase::OpenImplicitAnimation(
528     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
529 {
530 #ifdef ENABLE_ROSEN_BACKEND
531     PrepareOpenImplicitAnimation();
532 
533     auto wrapFinishCallback = [weak = AceType::WeakClaim(this), finishCallback]() {
534         auto context = weak.Upgrade();
535         if (!context) {
536             return;
537         }
538         context->GetTaskExecutor()->PostTask(
539             [finishCallback, weak]() {
540                 auto context = weak.Upgrade();
541                 CHECK_NULL_VOID(context);
542                 CHECK_NULL_VOID_NOLOG(finishCallback);
543                 if (context->IsFormRender()) {
544                     context->SetEnableImplicitAnimation(false);
545                     finishCallback();
546                     context->FlushBuild();
547                     context->SetEnableImplicitAnimation(true);
548                     return;
549                 }
550                 finishCallback();
551             },
552             TaskExecutor::TaskType::UI);
553     };
554     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
555 #endif
556 }
557 
CloseImplicitAnimation()558 bool PipelineBase::CloseImplicitAnimation()
559 {
560 #ifdef ENABLE_ROSEN_BACKEND
561     PrepareCloseImplicitAnimation();
562     return AnimationUtils::CloseImplicitAnimation();
563 #else
564     return false;
565 #endif
566 }
567 
OnVsyncEvent(uint64_t nanoTimestamp,uint32_t frameCount)568 void PipelineBase::OnVsyncEvent(uint64_t nanoTimestamp, uint32_t frameCount)
569 {
570     CHECK_RUN_ON(UI);
571     ACE_SCOPED_TRACE("OnVsyncEvent now:%" PRIu64 "", nanoTimestamp);
572 
573     for (auto& callback : subWindowVsyncCallbacks_) {
574         callback.second(nanoTimestamp, frameCount);
575     }
576 
577     if (onVsyncProfiler_) {
578         AceTracker::Start();
579     }
580 
581     if (gsVsyncCallback_) {
582         gsVsyncCallback_();
583     }
584 
585     FlushVsync(nanoTimestamp, frameCount);
586     if (onVsyncProfiler_) {
587         onVsyncProfiler_(AceTracker::Stop());
588     }
589 }
590 
SetTouchPipeline(const WeakPtr<PipelineBase> & context)591 void PipelineBase::SetTouchPipeline(const WeakPtr<PipelineBase>& context)
592 {
593     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
594     if (result == touchPluginPipelineContext_.end()) {
595         touchPluginPipelineContext_.emplace_back(context);
596     }
597 }
598 
RemoveTouchPipeline(const WeakPtr<PipelineBase> & context)599 void PipelineBase::RemoveTouchPipeline(const WeakPtr<PipelineBase>& context)
600 {
601     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
602     if (result != touchPluginPipelineContext_.end()) {
603         touchPluginPipelineContext_.erase(result);
604     }
605 }
606 
OnVirtualKeyboardAreaChange(Rect keyboardArea,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)607 void PipelineBase::OnVirtualKeyboardAreaChange(
608     Rect keyboardArea, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
609 {
610     auto currentContainer = Container::Current();
611     if (currentContainer && !currentContainer->IsSubContainer()) {
612         auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentContainer->GetInstanceId());
613         if (subwindow && subwindow->GetShown()) {
614             // subwindow is shown, main window no need to handle the keyboard event
615             return;
616         }
617     }
618     double keyboardHeight = keyboardArea.Height();
619     if (windowManager_ && windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
620         if (windowManager_->GetWindowType() == WindowType::WINDOW_TYPE_UNDEFINED ||
621             (windowManager_->GetWindowType() > WindowType::WINDOW_TYPE_APP_END &&
622                 windowManager_->GetWindowType() != WindowType::WINDOW_TYPE_FLOAT)) {
623             LOGW("this window type: %{public}d do not need avoid virtual keyboard.",
624                 static_cast<int32_t>(windowManager_->GetWindowMode()));
625             return;
626         }
627         keyboardHeight = ModifyKeyboardHeight(keyboardHeight);
628     }
629     if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight)) {
630         return;
631     }
632     OnVirtualKeyboardHeightChange(keyboardHeight, rsTransaction);
633 }
634 
ModifyKeyboardHeight(double keyboardHeight) const635 double PipelineBase::ModifyKeyboardHeight(double keyboardHeight) const
636 {
637     auto windowRect = GetCurrentWindowRect();
638     auto deviceHeight = SystemProperties::GetDeviceHeight();
639     return keyboardHeight > 0.0 && keyboardHeight - (deviceHeight - windowRect.Bottom()) > 0.0
640                ? keyboardHeight - (deviceHeight - windowRect.Bottom())
641                : 0.0;
642 }
643 
SetGetWindowRectImpl(std::function<Rect ()> && callback)644 void PipelineBase::SetGetWindowRectImpl(std::function<Rect()>&& callback)
645 {
646     if (window_) {
647         window_->SetGetWindowRectImpl(std::move(callback));
648     }
649 }
650 
GetCurrentWindowRect() const651 Rect PipelineBase::GetCurrentWindowRect() const
652 {
653     if (window_) {
654         return window_->GetCurrentWindowRect();
655     }
656     return {};
657 }
658 
HasFloatTitle() const659 bool PipelineBase::HasFloatTitle() const
660 {
661     CHECK_NULL_RETURN_NOLOG(windowManager_, false);
662     return GetWindowModal() == WindowModal::CONTAINER_MODAL &&
663            windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
664 }
665 
GetAccessibilityManager() const666 RefPtr<AccessibilityManager> PipelineBase::GetAccessibilityManager() const
667 {
668     auto frontend = weakFrontend_.Upgrade();
669     if (!frontend) {
670         LOGE("frontend is nullptr");
671         EventReport::SendAppStartException(AppStartExcepType::PIPELINE_CONTEXT_ERR);
672         return nullptr;
673     }
674     auto lock = frontend->GetLock();
675     return frontend->GetAccessibilityManager();
676 }
677 
SendEventToAccessibility(const AccessibilityEvent & accessibilityEvent)678 void PipelineBase::SendEventToAccessibility(const AccessibilityEvent& accessibilityEvent)
679 {
680     auto accessibilityManager = GetAccessibilityManager();
681     if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
682         return;
683     }
684     accessibilityManager->SendAccessibilityAsyncEvent(accessibilityEvent);
685 }
686 
SetSubWindowVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)687 void PipelineBase::SetSubWindowVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
688 {
689     if (callback) {
690         subWindowVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
691     }
692 }
693 
AddEtsCardTouchEventCallback(int32_t pointId,EtsCardTouchEventCallback && callback)694 void PipelineBase::AddEtsCardTouchEventCallback(int32_t pointId, EtsCardTouchEventCallback&& callback)
695 {
696     if (!callback || pointId < 0) {
697         return;
698     }
699 
700     etsCardTouchEventCallback_[pointId] = std::move(callback);
701 }
702 
HandleEtsCardTouchEvent(const TouchEvent & point)703 void PipelineBase::HandleEtsCardTouchEvent(const TouchEvent& point)
704 {
705     if (point.id < 0) {
706         return;
707     }
708 
709     auto iter = etsCardTouchEventCallback_.find(point.id);
710     if (iter == etsCardTouchEventCallback_.end()) {
711         return;
712     }
713 
714     if (iter->second) {
715         iter->second(point);
716     }
717 }
718 
RemoveEtsCardTouchEventCallback(int32_t pointId)719 void PipelineBase::RemoveEtsCardTouchEventCallback(int32_t pointId)
720 {
721     if (pointId < 0) {
722         return;
723     }
724 
725     auto iter = etsCardTouchEventCallback_.find(pointId);
726     if (iter == etsCardTouchEventCallback_.end()) {
727         return;
728     }
729 
730     etsCardTouchEventCallback_.erase(iter);
731 }
732 
RemoveSubWindowVsyncCallback(int32_t subWindowId)733 void PipelineBase::RemoveSubWindowVsyncCallback(int32_t subWindowId)
734 {
735     subWindowVsyncCallbacks_.erase(subWindowId);
736 }
737 
MaybeRelease()738 bool PipelineBase::MaybeRelease()
739 {
740     CHECK_RUN_ON(UI);
741     CHECK_NULL_RETURN(taskExecutor_, true);
742     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
743         LOGI("Destroy Pipeline on UI thread.");
744         return true;
745     } else {
746         LOGI("Post Destroy Pipeline Task to UI thread.");
747         return !taskExecutor_->PostTask([this] { delete this; }, TaskExecutor::TaskType::UI);
748     }
749 }
750 
Destroy()751 void PipelineBase::Destroy()
752 {
753     CHECK_RUN_ON(UI);
754     LOGI("PipelineBase::Destroy begin.");
755     ClearImageCache();
756     platformResRegister_.Reset();
757     drawDelegate_.reset();
758     eventManager_->ClearResults();
759     {
760         std::unique_lock<std::shared_mutex> lock(imageMtx_);
761         imageCache_.Reset();
762     }
763     {
764         std::unique_lock<std::shared_mutex> lock(themeMtx_);
765         themeManager_.Reset();
766     }
767     fontManager_.Reset();
768     window_->Destroy();
769     touchPluginPipelineContext_.clear();
770     virtualKeyBoardCallback_.clear();
771     etsCardTouchEventCallback_.clear();
772     formLinkInfoMap_.clear();
773     LOGI("PipelineBase::Destroy end.");
774 }
775 } // namespace OHOS::Ace
776