• 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/time_util.h"
26 #include "base/utils/utils.h"
27 #include "core/common/ace_application_info.h"
28 #include "core/common/ace_engine.h"
29 #include "core/common/container.h"
30 #include "core/common/container_scope.h"
31 #include "core/common/display_info.h"
32 #include "core/common/font_manager.h"
33 #include "core/common/frontend.h"
34 #include "core/common/manager_interface.h"
35 #include "core/common/thread_checker.h"
36 #include "core/common/window.h"
37 #include "core/components/common/layout/constants.h"
38 #include "core/components/custom_paint/render_custom_paint.h"
39 #include "core/components_ng/render/animation_utils.h"
40 #include "core/image/image_provider.h"
41 
42 #ifdef PLUGIN_COMPONENT_SUPPORTED
43 #include "core/common/plugin_manager.h"
44 #endif
45 
46 namespace OHOS::Ace {
47 
48 constexpr int32_t DEFAULT_VIEW_SCALE = 1;
49 
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)50 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
51     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
52     : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
53       weakFrontend_(frontend), instanceId_(instanceId)
54 {
55     CHECK_NULL_VOID(frontend);
56     frontendType_ = frontend->GetType();
57     eventManager_ = AceType::MakeRefPtr<EventManager>();
58     windowManager_ = AceType::MakeRefPtr<WindowManager>();
59     eventManager_->SetInstanceId(instanceId);
60     imageCache_ = ImageCache::Create();
61     fontManager_ = FontManager::Create();
62     auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
63                                const uint64_t nanoTimestamp, const uint32_t frameCount) {
64         ContainerScope scope(instanceId);
65         auto context = weak.Upgrade();
66         if (context) {
67             context->OnVsyncEvent(nanoTimestamp, frameCount);
68         }
69     };
70     ACE_DCHECK(window_);
71     window_->SetVsyncCallback(vsyncCallback);
72 }
73 
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId,RefPtr<PlatformResRegister> platformResRegister)74 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
75     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId,
76     RefPtr<PlatformResRegister> platformResRegister)
77     : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
78       weakFrontend_(frontend), instanceId_(instanceId), platformResRegister_(std::move(platformResRegister))
79 {
80     CHECK_NULL_VOID(frontend);
81     frontendType_ = frontend->GetType();
82     eventManager_ = AceType::MakeRefPtr<EventManager>();
83     windowManager_ = AceType::MakeRefPtr<WindowManager>();
84     eventManager_->SetInstanceId(instanceId);
85     imageCache_ = ImageCache::Create();
86     fontManager_ = FontManager::Create();
87     auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
88                                const uint64_t nanoTimestamp, const uint32_t frameCount) {
89         ContainerScope scope(instanceId);
90         auto context = weak.Upgrade();
91         if (context) {
92             context->OnVsyncEvent(nanoTimestamp, frameCount);
93         }
94     };
95     ACE_DCHECK(window_);
96     window_->SetVsyncCallback(vsyncCallback);
97 }
98 
~PipelineBase()99 PipelineBase::~PipelineBase()
100 {
101     std::lock_guard lock(destructMutex_);
102     LOG_DESTROY();
103 }
104 
SetCallBackNode(const WeakPtr<NG::FrameNode> & node)105 void PipelineBase::SetCallBackNode(const WeakPtr<NG::FrameNode>& node)
106 {
107     auto pipelineContext = PipelineContext::GetCurrentContext();
108     CHECK_NULL_VOID(pipelineContext);
109     pipelineContext->UpdateCurrentActiveNode(node);
110 }
111 
GetCurrentContext()112 RefPtr<PipelineBase> PipelineBase::GetCurrentContext()
113 {
114     auto currentContainer = Container::Current();
115     CHECK_NULL_RETURN(currentContainer, nullptr);
116     return currentContainer->GetPipelineContext();
117 }
118 
GetCurrentContextSafely()119 RefPtr<PipelineBase> PipelineBase::GetCurrentContextSafely()
120 {
121     auto currentContainer = Container::CurrentSafely();
122     CHECK_NULL_RETURN(currentContainer, nullptr);
123     return currentContainer->GetPipelineContext();
124 }
125 
GetCurrentDensity()126 double PipelineBase::GetCurrentDensity()
127 {
128     auto pipelineContext = PipelineContext::GetCurrentContextSafely();
129     if (!pipelineContext) {
130         auto container = Container::GetActive();
131         pipelineContext = container ? container->GetPipelineContext() : nullptr;
132     }
133     return pipelineContext ? pipelineContext->GetDensity() : SystemProperties::GetDefaultResolution();
134 }
135 
Px2VpWithCurrentDensity(double px)136 double PipelineBase::Px2VpWithCurrentDensity(double px)
137 {
138     double density = PipelineBase::GetCurrentDensity();
139     return px / density;
140 }
141 
Vp2PxWithCurrentDensity(double vp)142 double PipelineBase::Vp2PxWithCurrentDensity(double vp)
143 {
144     double density = PipelineBase::GetCurrentDensity();
145     return vp * density;
146 }
147 
GetMainPipelineContext()148 RefPtr<PipelineBase> PipelineBase::GetMainPipelineContext()
149 {
150     auto containerId = Container::CurrentId();
151     RefPtr<PipelineBase> context;
152     if (containerId >= MIN_SUBCONTAINER_ID) {
153         auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(containerId);
154         auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
155         CHECK_NULL_RETURN(parentContainer, nullptr);
156         context = parentContainer->GetPipelineContext();
157     } else {
158         context = PipelineBase::GetCurrentContext();
159     }
160     return context;
161 }
162 
CurrentThemeManager()163 RefPtr<ThemeManager> PipelineBase::CurrentThemeManager()
164 {
165     auto pipelineContext = OHOS::Ace::PipelineBase::GetCurrentContext();
166 #ifdef PLUGIN_COMPONENT_SUPPORTED
167     if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
168         auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
169         CHECK_NULL_RETURN(pluginContainer, nullptr);
170         pipelineContext = pluginContainer->GetPipelineContext();
171     }
172 #endif
173     CHECK_NULL_RETURN(pipelineContext, nullptr);
174     return pipelineContext->GetThemeManager();
175 }
176 
GetTimeFromExternalTimer()177 uint64_t PipelineBase::GetTimeFromExternalTimer()
178 {
179     static const int64_t secToNanosec = 1000000000;
180     struct timespec ts;
181     clock_gettime(CLOCK_MONOTONIC, &ts);
182     return (ts.tv_sec * secToNanosec + ts.tv_nsec);
183 }
184 
RequestFrame()185 void PipelineBase::RequestFrame()
186 {
187     window_->RequestFrame();
188 }
189 
GetFrontend() const190 RefPtr<Frontend> PipelineBase::GetFrontend() const
191 {
192     return weakFrontend_.Upgrade();
193 }
194 
ClearImageCache()195 void PipelineBase::ClearImageCache()
196 {
197     std::lock_guard<std::shared_mutex> lock(imageMtx_);
198     if (imageCache_) {
199         imageCache_->Clear();
200     }
201 }
202 
SetImageCache(const RefPtr<ImageCache> & imageCache)203 void PipelineBase::SetImageCache(const RefPtr<ImageCache>& imageCache)
204 {
205     std::lock_guard<std::shared_mutex> lock(imageMtx_);
206     if (imageCache) {
207         imageCache_ = imageCache;
208     }
209 }
210 
GetImageCache() const211 RefPtr<ImageCache> PipelineBase::GetImageCache() const
212 {
213     std::shared_lock<std::shared_mutex> lock(imageMtx_);
214     return imageCache_;
215 }
216 
SetRootSize(double density,float width,float height)217 void PipelineBase::SetRootSize(double density, float width, float height)
218 {
219     ACE_SCOPED_TRACE("SetRootSize(%lf, %f, %f)", density, width, height);
220     density_ = density;
221     auto task = [weak = AceType::WeakClaim(this), width, height]() {
222         auto context = weak.Upgrade();
223         if (!context) {
224             return;
225         }
226         context->SetRootRect(width, height);
227 
228     };
229 #ifdef NG_BUILD
230     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
231         task();
232     } else {
233         taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
234     }
235 #else
236     taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI);
237 #endif
238 }
239 
SetFontScale(float fontScale)240 void PipelineBase::SetFontScale(float fontScale)
241 {
242     const static float CARD_MAX_FONT_SCALE = 1.3f;
243     if (!NearEqual(fontScale_, fontScale)) {
244         fontScale_ = fontScale;
245         if (isJsCard_ && GreatOrEqual(fontScale_, CARD_MAX_FONT_SCALE)) {
246             fontScale_ = CARD_MAX_FONT_SCALE;
247         }
248         fontManager_->RebuildFontNode();
249     }
250 }
251 
NormalizeToPx(const Dimension & dimension) const252 double PipelineBase::NormalizeToPx(const Dimension& dimension) const
253 {
254     if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
255         return (dimension.Value() * dipScale_);
256     } else if (dimension.Unit() == DimensionUnit::LPX) {
257         return (dimension.Value() * designWidthScale_);
258     }
259     return dimension.Value();
260 }
261 
ConvertPxToVp(const Dimension & dimension) const262 double PipelineBase::ConvertPxToVp(const Dimension& dimension) const
263 {
264     if (dimension.Unit() == DimensionUnit::PX) {
265         return dimension.Value() / dipScale_;
266     }
267     return dimension.Value();
268 }
269 
UpdateFontWeightScale()270 void PipelineBase::UpdateFontWeightScale()
271 {
272     if (fontManager_) {
273         fontManager_->UpdateFontWeightScale();
274     }
275 }
276 
SetTextFieldManager(const RefPtr<ManagerInterface> & manager)277 void PipelineBase::SetTextFieldManager(const RefPtr<ManagerInterface>& manager)
278 {
279     textFieldManager_ = manager;
280 }
281 
RegisterFont(const std::string & familyName,const std::string & familySrc,const std::string & bundleName,const std::string & moduleName)282 void PipelineBase::RegisterFont(const std::string& familyName, const std::string& familySrc,
283     const std::string& bundleName, const std::string& moduleName)
284 {
285     if (fontManager_) {
286         fontManager_->RegisterFont(familyName, familySrc, AceType::Claim(this), bundleName, moduleName);
287     }
288 }
289 
GetSystemFontList(std::vector<std::string> & fontList)290 void PipelineBase::GetSystemFontList(std::vector<std::string>& fontList)
291 {
292     if (fontManager_) {
293         fontManager_->GetSystemFontList(fontList);
294     }
295 }
296 
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)297 bool PipelineBase::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
298 {
299     if (fontManager_) {
300         return fontManager_->GetSystemFont(fontName, fontInfo);
301     }
302     return false;
303 }
304 
GetUIFontConfig(FontConfigJsonInfo & fontConfigJsonInfo)305 void PipelineBase::GetUIFontConfig(FontConfigJsonInfo& fontConfigJsonInfo)
306 {
307     if (fontManager_) {
308         fontManager_->GetUIFontConfig(fontConfigJsonInfo);
309     }
310 }
311 
HyperlinkStartAbility(const std::string & address) const312 void PipelineBase::HyperlinkStartAbility(const std::string& address) const
313 {
314     CHECK_RUN_ON(UI);
315     if (startAbilityHandler_) {
316         startAbilityHandler_(address);
317     }
318 }
319 
NotifyStatusBarBgColor(const Color & color) const320 void PipelineBase::NotifyStatusBarBgColor(const Color& color) const
321 {
322     CHECK_RUN_ON(UI);
323     if (statusBarBgColorEventHandler_) {
324         statusBarBgColorEventHandler_(color);
325     }
326 }
327 
NotifyPopupDismiss() const328 void PipelineBase::NotifyPopupDismiss() const
329 {
330     CHECK_RUN_ON(UI);
331     if (popupEventHandler_) {
332         popupEventHandler_();
333     }
334 }
335 
NotifyMenuDismiss() const336 void PipelineBase::NotifyMenuDismiss() const
337 {
338     CHECK_RUN_ON(UI);
339     if (menuEventHandler_) {
340         menuEventHandler_();
341     }
342 }
343 
NotifyContextMenuDismiss() const344 void PipelineBase::NotifyContextMenuDismiss() const
345 {
346     CHECK_RUN_ON(UI);
347     if (contextMenuEventHandler_) {
348         contextMenuEventHandler_();
349     }
350 }
351 
NotifyRouterBackDismiss() const352 void PipelineBase::NotifyRouterBackDismiss() const
353 {
354     CHECK_RUN_ON(UI);
355     if (routerBackEventHandler_) {
356         routerBackEventHandler_();
357     }
358 }
359 
NotifyPopPageSuccessDismiss(const std::string & pageUrl,const int32_t pageId) const360 void PipelineBase::NotifyPopPageSuccessDismiss(const std::string& pageUrl, const int32_t pageId) const
361 {
362     CHECK_RUN_ON(UI);
363     for (auto& iterPopSuccessHander : popPageSuccessEventHandler_) {
364         if (iterPopSuccessHander) {
365             iterPopSuccessHander(pageUrl, pageId);
366         }
367     }
368 }
369 
NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const370 void PipelineBase::NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const
371 {
372     CHECK_RUN_ON(UI);
373     for (auto& iterPathInvalidHandler : isPagePathInvalidEventHandler_) {
374         if (iterPathInvalidHandler) {
375             iterPathInvalidHandler(isPageInvalid);
376         }
377     }
378 }
379 
NotifyDestroyEventDismiss() const380 void PipelineBase::NotifyDestroyEventDismiss() const
381 {
382     CHECK_RUN_ON(UI);
383     for (auto& iterDestroyEventHander : destroyEventHandler_) {
384         if (iterDestroyEventHander) {
385             iterDestroyEventHander();
386         }
387     }
388 }
389 
NotifyDispatchTouchEventDismiss(const TouchEvent & event) const390 void PipelineBase::NotifyDispatchTouchEventDismiss(const TouchEvent& event) const
391 {
392     CHECK_RUN_ON(UI);
393     for (auto& iterDispatchTouchEventHandler : dispatchTouchEventHandler_) {
394         if (iterDispatchTouchEventHandler) {
395             iterDispatchTouchEventHandler(event);
396         }
397     }
398 }
399 
OnActionEvent(const std::string & action)400 void PipelineBase::OnActionEvent(const std::string& action)
401 {
402     CHECK_RUN_ON(UI);
403     if (actionEventHandler_) {
404         actionEventHandler_(action);
405     }
406 }
407 
onRouterChange(const std::string & url)408 void PipelineBase::onRouterChange(const std::string& url)
409 {
410     if (onRouterChangeCallback_ != nullptr) {
411         onRouterChangeCallback_(url);
412     }
413 }
414 
TryLoadImageInfo(const std::string & src,std::function<void (bool,int32_t,int32_t)> && loadCallback)415 void PipelineBase::TryLoadImageInfo(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& loadCallback)
416 {
417     ImageProvider::TryLoadImageInfo(AceType::Claim(this), src, std::move(loadCallback));
418 }
419 
CreateOffscreenCanvas(int32_t width,int32_t height)420 RefPtr<OffscreenCanvas> PipelineBase::CreateOffscreenCanvas(int32_t width, int32_t height)
421 {
422     return RenderOffscreenCanvas::Create(AceType::WeakClaim(this), width, height);
423 }
424 
PostAsyncEvent(TaskExecutor::Task && task,TaskExecutor::TaskType type)425 void PipelineBase::PostAsyncEvent(TaskExecutor::Task&& task, TaskExecutor::TaskType type)
426 {
427     if (taskExecutor_) {
428         taskExecutor_->PostTask(std::move(task), type);
429     }
430 }
431 
PostAsyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)432 void PipelineBase::PostAsyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
433 {
434     if (taskExecutor_) {
435         taskExecutor_->PostTask(task, type);
436     }
437 }
438 
PostSyncEvent(const TaskExecutor::Task & task,TaskExecutor::TaskType type)439 void PipelineBase::PostSyncEvent(const TaskExecutor::Task& task, TaskExecutor::TaskType type)
440 {
441     if (taskExecutor_) {
442         taskExecutor_->PostSyncTask(task, type);
443     }
444 }
445 
UpdateRootSizeAndScale(int32_t width,int32_t height)446 void PipelineBase::UpdateRootSizeAndScale(int32_t width, int32_t height)
447 {
448     auto frontend = weakFrontend_.Upgrade();
449     CHECK_NULL_VOID(frontend);
450     auto lock = frontend->GetLock();
451     auto& windowConfig = frontend->GetWindowConfig();
452     if (windowConfig.designWidth <= 0) {
453         return;
454     }
455     if (GetIsDeclarative()) {
456         viewScale_ = DEFAULT_VIEW_SCALE;
457         designWidthScale_ = static_cast<double>(width) / windowConfig.designWidth;
458         windowConfig.designWidthScale = designWidthScale_;
459     } else {
460         viewScale_ = windowConfig.autoDesignWidth ? density_ : static_cast<double>(width) / windowConfig.designWidth;
461     }
462     if (NearZero(viewScale_)) {
463         return;
464     }
465     dipScale_ = density_ / viewScale_;
466     rootHeight_ = height / viewScale_;
467     rootWidth_ = width / viewScale_;
468 }
469 
DumpFrontend() const470 void PipelineBase::DumpFrontend() const
471 {
472     auto frontend = weakFrontend_.Upgrade();
473     CHECK_NULL_VOID(frontend);
474     auto lock = frontend->GetLock();
475     frontend->DumpFrontend();
476 }
477 
Dump(const std::vector<std::string> & params) const478 bool PipelineBase::Dump(const std::vector<std::string>& params) const
479 {
480     if (params.empty()) {
481         return false;
482     }
483     // the first param is the key word of dump.
484     if (params[0] == "-memory") {
485         MemoryMonitor::GetInstance().Dump();
486         return true;
487     }
488     if (params[0] == "-jscrash") {
489         EventReport::JsErrReport(
490             AceApplicationInfo::GetInstance().GetPackageName(), "js crash reason", "js crash summary");
491         return true;
492     }
493     // hiview report dump will provide three params .
494     if (params[0] == "-hiviewreport" && params.size() >= 3) {
495         DumpLog::GetInstance().Print("Report hiview event. EventType: " + params[1] + ", error type: " + params[2]);
496         EventInfo eventInfo = { .eventType = params[1], .errorType = StringUtils::StringToInt(params[2]) };
497         EventReport::SendEvent(eventInfo);
498         return true;
499     }
500     ContainerScope scope(instanceId_);
501     if (params[0] == "-frontend") {
502         DumpFrontend();
503         return true;
504     }
505     return OnDumpInfo(params);
506 }
507 
ForceLayoutForImplicitAnimation()508 void PipelineBase::ForceLayoutForImplicitAnimation()
509 {
510     if (!pendingImplicitLayout_.empty()) {
511         pendingImplicitLayout_.top() = true;
512     }
513     if (!pendingFrontendAnimation_.empty()) {
514         pendingFrontendAnimation_.top() = true;
515     }
516 }
517 
ForceRenderForImplicitAnimation()518 void PipelineBase::ForceRenderForImplicitAnimation()
519 {
520     if (!pendingImplicitRender_.empty()) {
521         pendingImplicitRender_.top() = true;
522     }
523     if (!pendingFrontendAnimation_.empty()) {
524         pendingFrontendAnimation_.top() = true;
525     }
526 }
527 
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback,const std::function<void ()> & finishCallback)528 bool PipelineBase::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
529     const std::function<void()>& propertyCallback, const std::function<void()>& finishCallback)
530 {
531     if (!propertyCallback) {
532         return false;
533     }
534 
535     OpenImplicitAnimation(option, curve, finishCallback);
536     propertyCallback();
537     return CloseImplicitAnimation();
538 }
539 
GetWrappedAnimationCallback(const std::function<void ()> & finishCallback)540 std::function<void()> PipelineBase::GetWrappedAnimationCallback(const std::function<void()>& finishCallback)
541 {
542     auto finishPtr = std::make_shared<std::function<void()>>(finishCallback);
543     finishFunctions_.emplace(finishPtr);
544     auto wrapFinishCallback = [weak = AceType::WeakClaim(this),
545                                   finishWeak = std::weak_ptr<std::function<void()>>(finishPtr)]() {
546         auto context = weak.Upgrade();
547         CHECK_NULL_VOID(context);
548         auto finishPtr = finishWeak.lock();
549         CHECK_NULL_VOID(finishPtr);
550         context->finishFunctions_.erase(finishPtr);
551         if (!(*finishPtr)) {
552             if (context->IsFormRender()) {
553                 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form animation is finish.");
554                 context->SetIsFormAnimation(false);
555             }
556             return;
557         }
558         if (context->IsFormRender()) {
559             TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form animation is finish.");
560             context->SetFormAnimationFinishCallback(true);
561             (*finishPtr)();
562             context->FlushBuild();
563             context->SetFormAnimationFinishCallback(false);
564             context->SetIsFormAnimation(false);
565             return;
566         }
567         (*finishPtr)();
568     };
569     return wrapFinishCallback;
570 }
571 
PrepareOpenImplicitAnimation()572 void PipelineBase::PrepareOpenImplicitAnimation()
573 {
574 #ifdef ENABLE_ROSEN_BACKEND
575     // initialize false for implicit animation layout and render pending flag
576     pendingImplicitLayout_.push(false);
577     pendingImplicitRender_.push(false);
578 
579     // flush ui tasks before open implicit animation
580     if (!IsLayouting()) {
581         FlushUITasks();
582     }
583 #endif
584 }
585 
PrepareCloseImplicitAnimation()586 void PipelineBase::PrepareCloseImplicitAnimation()
587 {
588 #ifdef ENABLE_ROSEN_BACKEND
589     if (pendingImplicitLayout_.empty() && pendingImplicitRender_.empty()) {
590         return;
591     }
592 
593     // layout or render the views immediately to animate all related views, if layout or render updates are pending in
594     // the animation closure
595     if (pendingImplicitLayout_.top() || pendingImplicitRender_.top()) {
596         if (!IsLayouting()) {
597             FlushUITasks();
598         } else if (IsLayouting()) {
599             LOGW("IsLayouting, prepareCloseImplicitAnimation has tasks not flushed");
600         }
601     }
602     if (!pendingImplicitLayout_.empty()) {
603         pendingImplicitLayout_.pop();
604     }
605     if (!pendingImplicitRender_.empty()) {
606         pendingImplicitRender_.pop();
607     }
608 #endif
609 }
610 
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)611 void PipelineBase::OpenImplicitAnimation(
612     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
613 {
614 #ifdef ENABLE_ROSEN_BACKEND
615     PrepareOpenImplicitAnimation();
616     auto wrapFinishCallback = GetWrappedAnimationCallback(finishCallback);
617     if (IsFormRender()) {
618         SetIsFormAnimation(true);
619         if (!IsFormAnimationFinishCallback()) {
620             SetFormAnimationStartTime(GetMicroTickCount());
621         }
622     }
623     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
624 #endif
625 }
626 
CloseImplicitAnimation()627 bool PipelineBase::CloseImplicitAnimation()
628 {
629 #ifdef ENABLE_ROSEN_BACKEND
630     PrepareCloseImplicitAnimation();
631     return AnimationUtils::CloseImplicitAnimation();
632 #else
633     return false;
634 #endif
635 }
636 
OnVsyncEvent(uint64_t nanoTimestamp,uint32_t frameCount)637 void PipelineBase::OnVsyncEvent(uint64_t nanoTimestamp, uint32_t frameCount)
638 {
639     CHECK_RUN_ON(UI);
640     ACE_SCOPED_TRACE("OnVsyncEvent now:%" PRIu64 "", nanoTimestamp);
641 
642     for (auto& callback : subWindowVsyncCallbacks_) {
643         callback.second(nanoTimestamp, frameCount);
644     }
645 
646     decltype(jsFormVsyncCallbacks_) jsFormVsyncCallbacks(std::move(jsFormVsyncCallbacks_));
647     for (auto& callback : jsFormVsyncCallbacks) {
648         callback.second(nanoTimestamp, frameCount);
649     }
650 
651     if (onVsyncProfiler_) {
652         AceTracker::Start();
653     }
654 
655     if (gsVsyncCallback_) {
656         gsVsyncCallback_();
657     }
658 
659     if (delaySurfaceChange_) {
660         delaySurfaceChange_ = false;
661         OnSurfaceChanged(width_, height_, type_, rsTransaction_);
662     }
663 
664     FlushVsync(nanoTimestamp, frameCount);
665     if (onVsyncProfiler_) {
666         onVsyncProfiler_(AceTracker::Stop());
667     }
668 }
669 
SetTouchPipeline(const WeakPtr<PipelineBase> & context)670 void PipelineBase::SetTouchPipeline(const WeakPtr<PipelineBase>& context)
671 {
672     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
673     if (result == touchPluginPipelineContext_.end()) {
674         touchPluginPipelineContext_.emplace_back(context);
675     }
676 }
677 
RemoveTouchPipeline(const WeakPtr<PipelineBase> & context)678 void PipelineBase::RemoveTouchPipeline(const WeakPtr<PipelineBase>& context)
679 {
680     auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
681     if (result != touchPluginPipelineContext_.end()) {
682         touchPluginPipelineContext_.erase(result);
683     }
684 }
685 
OnVirtualKeyboardAreaChange(Rect keyboardArea,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)686 void PipelineBase::OnVirtualKeyboardAreaChange(
687     Rect keyboardArea, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
688 {
689     auto currentContainer = Container::Current();
690     if (currentContainer && !currentContainer->IsSubContainer()) {
691         auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentContainer->GetInstanceId());
692         if (subwindow && subwindow->GetShown()) {
693             // subwindow is shown, main window no need to handle the keyboard event
694             return;
695         }
696     }
697     double keyboardHeight = keyboardArea.Height();
698     if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight)) {
699         return;
700     }
701     OnVirtualKeyboardHeightChange(keyboardHeight, rsTransaction);
702 }
703 
OnVirtualKeyboardAreaChange(Rect keyboardArea,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)704 void PipelineBase::OnVirtualKeyboardAreaChange(
705     Rect keyboardArea, double positionY, double height, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
706 {
707     auto currentContainer = Container::Current();
708     if (currentContainer && !currentContainer->IsSubContainer()) {
709         auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(currentContainer->GetInstanceId());
710         if (subwindow && subwindow->GetShown() && subwindow->IsFocused()) {
711             // subwindow is shown, main window no need to handle the keyboard event
712             return;
713         }
714     }
715     double keyboardHeight = keyboardArea.Height();
716     if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight)) {
717         return;
718     }
719     OnVirtualKeyboardHeightChange(keyboardHeight, positionY, height, rsTransaction);
720 }
721 
OnFoldStatusChanged(FoldStatus foldStatus)722 void PipelineBase::OnFoldStatusChanged(FoldStatus foldStatus)
723 {
724     OnFoldStatusChange(foldStatus);
725 }
726 
OnFoldDisplayModeChanged(FoldDisplayMode foldDisplayMode)727 void PipelineBase::OnFoldDisplayModeChanged(FoldDisplayMode foldDisplayMode)
728 {
729     OnFoldDisplayModeChange(foldDisplayMode);
730 }
731 
ModifyKeyboardHeight(double keyboardHeight) const732 double PipelineBase::ModifyKeyboardHeight(double keyboardHeight) const
733 {
734     auto windowRect = GetCurrentWindowRect();
735     auto deviceHeight = SystemProperties::GetDeviceHeight();
736     return keyboardHeight > 0.0 && keyboardHeight - (deviceHeight - windowRect.Bottom()) > 0.0
737                ? keyboardHeight - (deviceHeight - windowRect.Bottom())
738                : 0.0;
739 }
740 
SetGetWindowRectImpl(std::function<Rect ()> && callback)741 void PipelineBase::SetGetWindowRectImpl(std::function<Rect()>&& callback)
742 {
743     if (window_) {
744         window_->SetGetWindowRectImpl(std::move(callback));
745     }
746 }
747 
ContainerModalUnFocus()748 void PipelineBase::ContainerModalUnFocus() {}
749 
GetCurrentWindowRect() const750 Rect PipelineBase::GetCurrentWindowRect() const
751 {
752     if (window_) {
753         return window_->GetCurrentWindowRect();
754     }
755     return {};
756 }
757 
HasFloatTitle() const758 bool PipelineBase::HasFloatTitle() const
759 {
760     CHECK_NULL_RETURN(windowManager_, false);
761     return GetWindowModal() == WindowModal::CONTAINER_MODAL &&
762            windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
763 }
764 
GetAccessibilityManager() const765 RefPtr<AccessibilityManager> PipelineBase::GetAccessibilityManager() const
766 {
767     auto frontend = weakFrontend_.Upgrade();
768     if (!frontend) {
769         EventReport::SendAppStartException(AppStartExcepType::PIPELINE_CONTEXT_ERR);
770         return nullptr;
771     }
772     auto lock = frontend->GetLock();
773     return frontend->GetAccessibilityManager();
774 }
775 
SendEventToAccessibility(const AccessibilityEvent & accessibilityEvent)776 void PipelineBase::SendEventToAccessibility(const AccessibilityEvent& accessibilityEvent)
777 {
778     auto accessibilityManager = GetAccessibilityManager();
779     if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
780         return;
781     }
782     accessibilityManager->SendAccessibilityAsyncEvent(accessibilityEvent);
783 }
784 
SetSubWindowVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)785 void PipelineBase::SetSubWindowVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
786 {
787     if (callback) {
788         subWindowVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
789     }
790 }
791 
SetJsFormVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)792 void PipelineBase::SetJsFormVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
793 {
794     if (callback) {
795         jsFormVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
796     }
797 }
798 
AddEtsCardTouchEventCallback(int32_t pointId,EtsCardTouchEventCallback && callback)799 void PipelineBase::AddEtsCardTouchEventCallback(int32_t pointId, EtsCardTouchEventCallback&& callback)
800 {
801     if (!callback || pointId < 0) {
802         return;
803     }
804 
805     etsCardTouchEventCallback_[pointId] = std::move(callback);
806 }
807 
HandleEtsCardTouchEvent(const TouchEvent & point,SerializedGesture & serializedGesture)808 void PipelineBase::HandleEtsCardTouchEvent(const TouchEvent& point,
809     SerializedGesture& serializedGesture)
810 {
811     if (point.id < 0) {
812         return;
813     }
814 
815     auto iter = etsCardTouchEventCallback_.find(point.id);
816     if (iter == etsCardTouchEventCallback_.end()) {
817         return;
818     }
819     if (iter->second) {
820         iter->second(point, serializedGesture);
821     }
822 }
823 
RemoveEtsCardTouchEventCallback(int32_t pointId)824 void PipelineBase::RemoveEtsCardTouchEventCallback(int32_t pointId)
825 {
826     if (pointId < 0) {
827         return;
828     }
829 
830     auto iter = etsCardTouchEventCallback_.find(pointId);
831     if (iter == etsCardTouchEventCallback_.end()) {
832         return;
833     }
834 
835     etsCardTouchEventCallback_.erase(iter);
836 }
837 
RemoveSubWindowVsyncCallback(int32_t subWindowId)838 void PipelineBase::RemoveSubWindowVsyncCallback(int32_t subWindowId)
839 {
840     subWindowVsyncCallbacks_.erase(subWindowId);
841 }
842 
RemoveJsFormVsyncCallback(int32_t subWindowId)843 void PipelineBase::RemoveJsFormVsyncCallback(int32_t subWindowId)
844 {
845     jsFormVsyncCallbacks_.erase(subWindowId);
846 }
847 
MaybeRelease()848 bool PipelineBase::MaybeRelease()
849 {
850     CHECK_NULL_RETURN(taskExecutor_, true);
851     if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
852         LOGI("Destroy Pipeline on UI thread.");
853         return true;
854     } else {
855         std::lock_guard lock(destructMutex_);
856         LOGI("Post Destroy Pipeline Task to UI thread.");
857         return !taskExecutor_->PostTask([this] { delete this; }, TaskExecutor::TaskType::UI);
858     }
859 }
860 
Destroy()861 void PipelineBase::Destroy()
862 {
863     CHECK_RUN_ON(UI);
864     ClearImageCache();
865     platformResRegister_.Reset();
866     drawDelegate_.reset();
867     eventManager_->ClearResults();
868     {
869         std::unique_lock<std::shared_mutex> lock(imageMtx_);
870         imageCache_.Reset();
871     }
872     {
873         std::unique_lock<std::shared_mutex> lock(themeMtx_);
874         themeManager_.Reset();
875     }
876     fontManager_.Reset();
877     window_->Destroy();
878     touchPluginPipelineContext_.clear();
879     virtualKeyBoardCallback_.clear();
880     etsCardTouchEventCallback_.clear();
881     formLinkInfoMap_.clear();
882     finishFunctions_.clear();
883 }
884 
OnFormRecycle()885 std::string PipelineBase::OnFormRecycle()
886 {
887     if (onFormRecycle_) {
888         return onFormRecycle_();
889     }
890     LOGE("onFormRecycle_ is null.");
891     return "";
892 }
893 
OnFormRecover(const std::string & statusData)894 void PipelineBase::OnFormRecover(const std::string& statusData)
895 {
896     if (onFormRecover_) {
897         return onFormRecover_(statusData);
898     }
899     LOGE("onFormRecover_ is null.");
900 }
901 } // namespace OHOS::Ace
902