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