• 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     if (imageCache_) {
143         imageCache_->Clear();
144     }
145 }
146 
SetImageCache(const RefPtr<ImageCache> & imageCache)147 void PipelineBase::SetImageCache(const RefPtr<ImageCache>& imageCache)
148 {
149     std::lock_guard<std::shared_mutex> lock(imageMtx_);
150     if (imageCache) {
151         imageCache_ = imageCache;
152     }
153 }
154 
GetImageCache() const155 RefPtr<ImageCache> PipelineBase::GetImageCache() const
156 {
157     std::shared_lock<std::shared_mutex> lock(imageMtx_);
158     return imageCache_;
159 }
160 
SetRootSize(double density,int32_t width,int32_t height)161 void PipelineBase::SetRootSize(double density, int32_t width, int32_t height)
162 {
163     ACE_SCOPED_TRACE("SetRootSize(%lf, %d, %d)", density, width, height);
164     density_ = density;
165     auto task = [weak = AceType::WeakClaim(this), density, width, height]() {
166         auto context = weak.Upgrade();
167         if (!context) {
168             return;
169         }
170         context->SetRootRect(width, height);
171     };
172 #ifdef NG_BUILD
173     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
174         task();
175     } else {
176         taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
177     }
178 #else
179     taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
180 #endif
181 }
182 
SetFontScale(float fontScale)183 void PipelineBase::SetFontScale(float fontScale)
184 {
185     const static float CARD_MAX_FONT_SCALE = 1.3f;
186     if (!NearEqual(fontScale_, fontScale)) {
187         fontScale_ = fontScale;
188         if (isJsCard_ && GreatOrEqual(fontScale_, CARD_MAX_FONT_SCALE)) {
189             fontScale_ = CARD_MAX_FONT_SCALE;
190         }
191         fontManager_->RebuildFontNode();
192     }
193 }
194 
NormalizeToPx(const Dimension & dimension) const195 double PipelineBase::NormalizeToPx(const Dimension& dimension) const
196 {
197     if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
198         return (dimension.Value() * dipScale_);
199     } else if (dimension.Unit() == DimensionUnit::LPX) {
200         return (dimension.Value() * designWidthScale_);
201     }
202     return dimension.Value();
203 }
204 
ConvertPxToVp(const Dimension & dimension) const205 double PipelineBase::ConvertPxToVp(const Dimension& dimension) const
206 {
207     if (dimension.Unit() == DimensionUnit::PX) {
208         return dimension.Value() / dipScale_;
209     }
210     return dimension.Value();
211 }
212 
UpdateFontWeightScale()213 void PipelineBase::UpdateFontWeightScale()
214 {
215     if (fontManager_) {
216         fontManager_->UpdateFontWeightScale();
217     }
218 }
219 
SetTextFieldManager(const RefPtr<ManagerInterface> & manager)220 void PipelineBase::SetTextFieldManager(const RefPtr<ManagerInterface>& manager)
221 {
222     textFieldManager_ = manager;
223 }
224 
RegisterFont(const std::string & familyName,const std::string & familySrc)225 void PipelineBase::RegisterFont(const std::string& familyName, const std::string& familySrc)
226 {
227     if (fontManager_) {
228         fontManager_->RegisterFont(familyName, familySrc, AceType::Claim(this));
229     }
230 }
231 
GetSystemFontList(std::vector<std::string> & fontList)232 void PipelineBase::GetSystemFontList(std::vector<std::string>& fontList)
233 {
234     if (fontManager_) {
235         fontManager_->GetSystemFontList(fontList);
236     }
237 }
238 
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)239 bool PipelineBase::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
240 {
241     if (fontManager_) {
242         return fontManager_->GetSystemFont(fontName, fontInfo);
243     }
244     return false;
245 }
246 
HyperlinkStartAbility(const std::string & address) const247 void PipelineBase::HyperlinkStartAbility(const std::string& address) const
248 {
249     CHECK_RUN_ON(UI);
250     if (startAbilityHandler_) {
251         startAbilityHandler_(address);
252     } else {
253         LOGE("Hyperlink fail to start ability due to handler is nullptr");
254     }
255 }
256 
NotifyStatusBarBgColor(const Color & color) const257 void PipelineBase::NotifyStatusBarBgColor(const Color& color) const
258 {
259     CHECK_RUN_ON(UI);
260     LOGD("Notify StatusBar BgColor, color: %{public}x", color.GetValue());
261     if (statusBarBgColorEventHandler_) {
262         statusBarBgColorEventHandler_(color);
263     } else {
264         LOGE("fail to finish current context due to handler is nullptr");
265     }
266 }
267 
NotifyPopupDismiss() const268 void PipelineBase::NotifyPopupDismiss() const
269 {
270     CHECK_RUN_ON(UI);
271     if (popupEventHandler_) {
272         popupEventHandler_();
273     }
274 }
275 
NotifyMenuDismiss() const276 void PipelineBase::NotifyMenuDismiss() const
277 {
278     CHECK_RUN_ON(UI);
279     if (menuEventHandler_) {
280         menuEventHandler_();
281     }
282 }
283 
NotifyContextMenuDismiss() const284 void PipelineBase::NotifyContextMenuDismiss() const
285 {
286     CHECK_RUN_ON(UI);
287     if (contextMenuEventHandler_) {
288         contextMenuEventHandler_();
289     }
290 }
291 
NotifyRouterBackDismiss() const292 void PipelineBase::NotifyRouterBackDismiss() const
293 {
294     CHECK_RUN_ON(UI);
295     if (routerBackEventHandler_) {
296         routerBackEventHandler_();
297     }
298 }
299 
NotifyPopPageSuccessDismiss(const std::string & pageUrl,const int32_t pageId) const300 void PipelineBase::NotifyPopPageSuccessDismiss(const std::string& pageUrl, const int32_t pageId) const
301 {
302     CHECK_RUN_ON(UI);
303     for (auto& iterPopSuccessHander : popPageSuccessEventHandler_) {
304         if (iterPopSuccessHander) {
305             iterPopSuccessHander(pageUrl, pageId);
306         }
307     }
308 }
309 
NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const310 void PipelineBase::NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const
311 {
312     CHECK_RUN_ON(UI);
313     for (auto& iterPathInvalidHandler : isPagePathInvalidEventHandler_) {
314         if (iterPathInvalidHandler) {
315             iterPathInvalidHandler(isPageInvalid);
316         }
317     }
318 }
319 
NotifyDestroyEventDismiss() const320 void PipelineBase::NotifyDestroyEventDismiss() const
321 {
322     CHECK_RUN_ON(UI);
323     for (auto& iterDestroyEventHander : destroyEventHandler_) {
324         if (iterDestroyEventHander) {
325             iterDestroyEventHander();
326         }
327     }
328 }
329 
NotifyDispatchTouchEventDismiss(const TouchEvent & event) const330 void PipelineBase::NotifyDispatchTouchEventDismiss(const TouchEvent& event) const
331 {
332     CHECK_RUN_ON(UI);
333     for (auto& iterDispatchTouchEventHandler : dispatchTouchEventHandler_) {
334         if (iterDispatchTouchEventHandler) {
335             iterDispatchTouchEventHandler(event);
336         }
337     }
338 }
339 
OnActionEvent(const std::string & action)340 void PipelineBase::OnActionEvent(const std::string& action)
341 {
342     CHECK_RUN_ON(UI);
343     if (actionEventHandler_) {
344         actionEventHandler_(action);
345     } else {
346         LOGE("the action event handler is null");
347     }
348 }
349 
onRouterChange(const std::string & url)350 void PipelineBase::onRouterChange(const std::string& url)
351 {
352     if (onRouterChangeCallback_ != nullptr) {
353         onRouterChangeCallback_(url);
354     }
355 }
356 
TryLoadImageInfo(const std::string & src,std::function<void (bool,int32_t,int32_t)> && loadCallback)357 void PipelineBase::TryLoadImageInfo(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& loadCallback)
358 {
359     ImageProvider::TryLoadImageInfo(AceType::Claim(this), src, std::move(loadCallback));
360 }
361 
CreateOffscreenCanvas(int32_t width,int32_t height)362 RefPtr<OffscreenCanvas> PipelineBase::CreateOffscreenCanvas(int32_t width, int32_t height)
363 {
364     return RenderOffscreenCanvas::Create(AceType::WeakClaim(this), width, height);
365 }
366 
PostAsyncEvent(TaskExecutor::Task && task,TaskExecutor::TaskType type)367 void PipelineBase::PostAsyncEvent(TaskExecutor::Task&& task, TaskExecutor::TaskType type)
368 {
369     if (taskExecutor_) {
370         taskExecutor_->PostTask(std::move(task), type);
371     } else {
372         LOGE("the task executor is nullptr");
373     }
374 }
375 
PostAsyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)376 void PipelineBase::PostAsyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
377 {
378     if (taskExecutor_) {
379         taskExecutor_->PostTask(task, type);
380     } else {
381         LOGE("the task executor is nullptr");
382     }
383 }
384 
PostSyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)385 void PipelineBase::PostSyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
386 {
387     if (taskExecutor_) {
388         taskExecutor_->PostSyncTask(task, type);
389     } else {
390         LOGE("the task executor is nullptr");
391     }
392 }
393 
UpdateRootSizeAndScale(int32_t width,int32_t height)394 void PipelineBase::UpdateRootSizeAndScale(int32_t width, int32_t height)
395 {
396     auto frontend = weakFrontend_.Upgrade();
397     CHECK_NULL_VOID(frontend);
398     auto lock = frontend->GetLock();
399     auto& windowConfig = frontend->GetWindowConfig();
400     if (windowConfig.designWidth <= 0) {
401         LOGE("the frontend design width <= 0");
402         return;
403     }
404     if (GetIsDeclarative()) {
405         viewScale_ = DEFAULT_VIEW_SCALE;
406         designWidthScale_ = static_cast<double>(width) / windowConfig.designWidth;
407         windowConfig.designWidthScale = designWidthScale_;
408     } else {
409         viewScale_ = windowConfig.autoDesignWidth ? density_ : static_cast<double>(width) / windowConfig.designWidth;
410     }
411     if (NearZero(viewScale_)) {
412         LOGW("the view scale is zero");
413         return;
414     }
415     dipScale_ = density_ / viewScale_;
416     rootHeight_ = height / viewScale_;
417     rootWidth_ = width / viewScale_;
418 }
419 
DumpFrontend() const420 void PipelineBase::DumpFrontend() const
421 {
422     auto frontend = weakFrontend_.Upgrade();
423     CHECK_NULL_VOID(frontend);
424     auto lock = frontend->GetLock();
425     frontend->DumpFrontend();
426 }
427 
Dump(const std::vector<std::string> & params) const428 bool PipelineBase::Dump(const std::vector<std::string>& params) const
429 {
430     if (params.empty()) {
431         LOGW("the params is empty");
432         return false;
433     }
434     // the first param is the key word of dump.
435     if (params[0] == "-memory") {
436         MemoryMonitor::GetInstance().Dump();
437         return true;
438     }
439     if (params[0] == "-jscrash") {
440         EventReport::JsErrReport(
441             AceApplicationInfo::GetInstance().GetPackageName(), "js crash reason", "js crash summary");
442         return true;
443     }
444     // hiview report dump will provide three params .
445     if (params[0] == "-hiviewreport" && params.size() >= 3) {
446         DumpLog::GetInstance().Print("Report hiview event. EventType: " + params[1] + ", error type: " + params[2]);
447         EventInfo eventInfo = { .eventType = params[1], .errorType = StringUtils::StringToInt(params[2]) };
448         EventReport::SendEvent(eventInfo);
449         return true;
450     }
451     ContainerScope scope(instanceId_);
452     if (params[0] == "-frontend") {
453         DumpFrontend();
454         return true;
455     }
456     return OnDumpInfo(params);
457 }
458 
ForceLayoutForImplicitAnimation()459 void PipelineBase::ForceLayoutForImplicitAnimation()
460 {
461     if (!pendingImplicitLayout_.empty()) {
462         pendingImplicitLayout_.top() = true;
463     }
464 }
465 
ForceRenderForImplicitAnimation()466 void PipelineBase::ForceRenderForImplicitAnimation()
467 {
468     if (!pendingImplicitRender_.empty()) {
469         pendingImplicitRender_.top() = true;
470     }
471 }
472 
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback,const std::function<void ()> & finishCallback)473 bool PipelineBase::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
474     const std::function<void()>& propertyCallback, const std::function<void()>& finishCallback)
475 {
476     if (!propertyCallback) {
477         LOGE("failed to create animation, property callback is null!");
478         return false;
479     }
480 
481     OpenImplicitAnimation(option, curve, finishCallback);
482     propertyCallback();
483     return CloseImplicitAnimation();
484 }
485 
PrepareOpenImplicitAnimation()486 void PipelineBase::PrepareOpenImplicitAnimation()
487 {
488 #ifdef ENABLE_ROSEN_BACKEND
489     // initialize false for implicit animation layout and render pending flag
490     pendingImplicitLayout_.push(false);
491     pendingImplicitRender_.push(false);
492 
493     // flush ui tasks before open implicit animation
494     if (!isReloading_ && !IsLayouting()) {
495         FlushUITasks();
496     }
497 #endif
498 }
499 
PrepareCloseImplicitAnimation()500 void PipelineBase::PrepareCloseImplicitAnimation()
501 {
502 #ifdef ENABLE_ROSEN_BACKEND
503     if (pendingImplicitLayout_.empty() && pendingImplicitRender_.empty()) {
504         LOGE("close implicit animation failed, need to open implicit animation first!");
505         return;
506     }
507 
508     // layout or render the views immediately to animate all related views, if layout or render updates are pending in
509     // the animation closure
510     if (pendingImplicitLayout_.top() || pendingImplicitRender_.top()) {
511         if (!isReloading_ && !IsLayouting()) {
512             FlushUITasks();
513         } else if (IsLayouting()) {
514             LOGW("IsLayouting, prepareCloseImplicitAnimation has tasks not flushed");
515         }
516     }
517     if (!pendingImplicitLayout_.empty()) {
518         pendingImplicitLayout_.pop();
519     }
520     if (!pendingImplicitRender_.empty()) {
521         pendingImplicitRender_.pop();
522     }
523 #endif
524 }
525 
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)526 void PipelineBase::OpenImplicitAnimation(
527     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
528 {
529 #ifdef ENABLE_ROSEN_BACKEND
530     PrepareOpenImplicitAnimation();
531 
532     auto wrapFinishCallback = [weak = AceType::WeakClaim(this), finishCallback]() {
533         auto context = weak.Upgrade();
534         if (!context) {
535             return;
536         }
537         context->GetTaskExecutor()->PostTask(
538             [finishCallback, weak]() {
539                 auto context = weak.Upgrade();
540                 CHECK_NULL_VOID(context);
541                 CHECK_NULL_VOID_NOLOG(finishCallback);
542                 if (context->IsFormRender()) {
543                     context->SetEnableImplicitAnimation(false);
544                     finishCallback();
545                     context->FlushBuild();
546                     context->SetEnableImplicitAnimation(true);
547                     return;
548                 }
549                 finishCallback();
550             },
551             TaskExecutor::TaskType::UI);
552     };
553     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
554 #endif
555 }
556 
CloseImplicitAnimation()557 bool PipelineBase::CloseImplicitAnimation()
558 {
559 #ifdef ENABLE_ROSEN_BACKEND
560     PrepareCloseImplicitAnimation();
561     return AnimationUtils::CloseImplicitAnimation();
562 #else
563     return false;
564 #endif
565 }
566 
OnVsyncEvent(uint64_t nanoTimestamp,uint32_t frameCount)567 void PipelineBase::OnVsyncEvent(uint64_t nanoTimestamp, uint32_t frameCount)
568 {
569     CHECK_RUN_ON(UI);
570     ACE_SCOPED_TRACE("OnVsyncEvent now:%" PRIu64 "", nanoTimestamp);
571 
572     for (auto& callback : subWindowVsyncCallbacks_) {
573         callback.second(nanoTimestamp, frameCount);
574     }
575 
576     if (onVsyncProfiler_) {
577         AceTracker::Start();
578     }
579 
580     if (gsVsyncCallback_) {
581         gsVsyncCallback_();
582     }
583 
584     FlushVsync(nanoTimestamp, frameCount);
585     if (onVsyncProfiler_) {
586         onVsyncProfiler_(AceTracker::Stop());
587     }
588 }
589 
SetTouchPipeline(const WeakPtr<PipelineBase> & context)590 void PipelineBase::SetTouchPipeline(const WeakPtr<PipelineBase>& context)
591 {
592     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
593     if (result == touchPluginPipelineContext_.end()) {
594         touchPluginPipelineContext_.emplace_back(context);
595     }
596 }
597 
RemoveTouchPipeline(const WeakPtr<PipelineBase> & context)598 void PipelineBase::RemoveTouchPipeline(const WeakPtr<PipelineBase>& context)
599 {
600     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
601     if (result != touchPluginPipelineContext_.end()) {
602         touchPluginPipelineContext_.erase(result);
603     }
604 }
605 
OnVirtualKeyboardAreaChange(Rect keyboardArea,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)606 void PipelineBase::OnVirtualKeyboardAreaChange(
607     Rect keyboardArea, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
608 {
609     auto currentContainer = Container::Current();
610     if (currentContainer && !currentContainer->IsSubContainer()) {
611         auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentContainer->GetInstanceId());
612         if (subwindow && subwindow->GetShown()) {
613             // subwindow is shown, main window no need to handle the keyboard event
614             return;
615         }
616     }
617     double keyboardHeight = keyboardArea.Height();
618     if (windowManager_ && windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
619         if (windowManager_->GetWindowType() == WindowType::WINDOW_TYPE_UNDEFINED ||
620             (windowManager_->GetWindowType() > WindowType::WINDOW_TYPE_APP_END &&
621                 windowManager_->GetWindowType() != WindowType::WINDOW_TYPE_FLOAT)) {
622             LOGW("this window type: %{public}d do not need avoid virtual keyboard.",
623                 static_cast<int32_t>(windowManager_->GetWindowMode()));
624             return;
625         }
626         keyboardHeight = ModifyKeyboardHeight(keyboardHeight);
627     }
628     if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight)) {
629         return;
630     }
631     OnVirtualKeyboardHeightChange(keyboardHeight, rsTransaction);
632 }
633 
ModifyKeyboardHeight(double keyboardHeight) const634 double PipelineBase::ModifyKeyboardHeight(double keyboardHeight) const
635 {
636     auto windowRect = GetCurrentWindowRect();
637     auto deviceHeight = SystemProperties::GetDeviceHeight();
638     return keyboardHeight > 0.0 && keyboardHeight - (deviceHeight - windowRect.Bottom()) > 0.0
639                ? keyboardHeight - (deviceHeight - windowRect.Bottom())
640                : 0.0;
641 }
642 
SetGetWindowRectImpl(std::function<Rect ()> && callback)643 void PipelineBase::SetGetWindowRectImpl(std::function<Rect()>&& callback)
644 {
645     if (window_) {
646         window_->SetGetWindowRectImpl(std::move(callback));
647     }
648 }
649 
GetCurrentWindowRect() const650 Rect PipelineBase::GetCurrentWindowRect() const
651 {
652     if (window_) {
653         return window_->GetCurrentWindowRect();
654     }
655     return {};
656 }
657 
HasFloatTitle() const658 bool PipelineBase::HasFloatTitle() const
659 {
660     CHECK_NULL_RETURN_NOLOG(windowManager_, false);
661     return GetWindowModal() == WindowModal::CONTAINER_MODAL &&
662            windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
663 }
664 
GetAccessibilityManager() const665 RefPtr<AccessibilityManager> PipelineBase::GetAccessibilityManager() const
666 {
667     auto frontend = weakFrontend_.Upgrade();
668     if (!frontend) {
669         LOGE("frontend is nullptr");
670         EventReport::SendAppStartException(AppStartExcepType::PIPELINE_CONTEXT_ERR);
671         return nullptr;
672     }
673     auto lock = frontend->GetLock();
674     return frontend->GetAccessibilityManager();
675 }
676 
SendEventToAccessibility(const AccessibilityEvent & accessibilityEvent)677 void PipelineBase::SendEventToAccessibility(const AccessibilityEvent& accessibilityEvent)
678 {
679     auto accessibilityManager = GetAccessibilityManager();
680     if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
681         return;
682     }
683     accessibilityManager->SendAccessibilityAsyncEvent(accessibilityEvent);
684 }
685 
SetSubWindowVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)686 void PipelineBase::SetSubWindowVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
687 {
688     if (callback) {
689         subWindowVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
690     }
691 }
692 
AddEtsCardTouchEventCallback(int32_t pointId,EtsCardTouchEventCallback && callback)693 void PipelineBase::AddEtsCardTouchEventCallback(int32_t pointId, EtsCardTouchEventCallback&& callback)
694 {
695     if (!callback || pointId < 0) {
696         return;
697     }
698 
699     etsCardTouchEventCallback_[pointId] = std::move(callback);
700 }
701 
HandleEtsCardTouchEvent(const TouchEvent & point)702 void PipelineBase::HandleEtsCardTouchEvent(const TouchEvent& point)
703 {
704     if (point.id < 0) {
705         return;
706     }
707 
708     auto iter = etsCardTouchEventCallback_.find(point.id);
709     if (iter == etsCardTouchEventCallback_.end()) {
710         return;
711     }
712 
713     if (iter->second) {
714         iter->second(point);
715     }
716 }
717 
RemoveEtsCardTouchEventCallback(int32_t pointId)718 void PipelineBase::RemoveEtsCardTouchEventCallback(int32_t pointId)
719 {
720     if (pointId < 0) {
721         return;
722     }
723 
724     auto iter = etsCardTouchEventCallback_.find(pointId);
725     if (iter == etsCardTouchEventCallback_.end()) {
726         return;
727     }
728 
729     etsCardTouchEventCallback_.erase(iter);
730 }
731 
RemoveSubWindowVsyncCallback(int32_t subWindowId)732 void PipelineBase::RemoveSubWindowVsyncCallback(int32_t subWindowId)
733 {
734     subWindowVsyncCallbacks_.erase(subWindowId);
735 }
736 
MaybeRelease()737 bool PipelineBase::MaybeRelease()
738 {
739     CHECK_RUN_ON(UI);
740     CHECK_NULL_RETURN(taskExecutor_, true);
741     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
742         LOGI("Destroy Pipeline on UI thread.");
743         return true;
744     } else {
745         LOGI("Post Destroy Pipeline Task to UI thread.");
746         return !taskExecutor_->PostTask([this] { delete this; }, TaskExecutor::TaskType::UI);
747     }
748 }
749 
Destroy()750 void PipelineBase::Destroy()
751 {
752     CHECK_RUN_ON(UI);
753     LOGI("PipelineBase::Destroy begin.");
754     ClearImageCache();
755     platformResRegister_.Reset();
756     drawDelegate_.reset();
757     eventManager_->ClearResults();
758     {
759         std::unique_lock<std::shared_mutex> lock(imageMtx_);
760         imageCache_.Reset();
761     }
762     {
763         std::unique_lock<std::shared_mutex> lock(themeMtx_);
764         themeManager_.Reset();
765     }
766     fontManager_.Reset();
767     window_->Destroy();
768     touchPluginPipelineContext_.clear();
769     virtualKeyBoardCallback_.clear();
770     etsCardTouchEventCallback_.clear();
771     formLinkInfoMap_.clear();
772     LOGI("PipelineBase::Destroy end.");
773 }
774 } // namespace OHOS::Ace
775