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 "base/log/ace_tracker.h"
19 #include "base/log/dump_log.h"
20 #include "base/log/event_report.h"
21 #include "base/subwindow/subwindow_manager.h"
22 #include "base/utils/feature_param.h"
23 #include "core/common/ace_engine.h"
24 #include "core/common/font_manager.h"
25 #include "core/common/manager_interface.h"
26 #include "core/common/window.h"
27 #include "core/components/common/layout/constants.h"
28 #include "core/components/container_modal/container_modal_constants.h"
29 #include "core/components/custom_paint/render_custom_paint.h"
30 #include "core/components_ng/base/ui_node_gc.h"
31 #include "core/components_ng/render/animation_utils.h"
32 #include "core/image/image_provider.h"
33
34 #ifdef PLUGIN_COMPONENT_SUPPORTED
35 #include "core/common/plugin_manager.h"
36 #endif
37
38 namespace OHOS::Ace {
39
40 constexpr int32_t DEFAULT_VIEW_SCALE = 1;
41
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)42 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
43 RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
44 : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
45 weakFrontend_(frontend), instanceId_(instanceId)
46 {
47 CHECK_NULL_VOID(frontend);
48 frontendType_ = frontend->GetType();
49 eventManager_ = AceType::MakeRefPtr<EventManager>();
50 windowManager_ = AceType::MakeRefPtr<WindowManager>();
51 eventManager_->SetInstanceId(instanceId);
52 imageCache_ = ImageCache::Create();
53 fontManager_ = FontManager::Create();
54 auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
55 uint64_t nanoTimestamp, uint64_t frameCount) {
56 ContainerScope scope(instanceId);
57 auto context = weak.Upgrade();
58 if (context) {
59 context->OnVsyncEvent(nanoTimestamp, frameCount);
60 }
61 };
62 ACE_DCHECK(window_);
63 window_->SetVsyncCallback(vsyncCallback);
64 }
65
PipelineBase(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId,RefPtr<PlatformResRegister> platformResRegister)66 PipelineBase::PipelineBase(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
67 RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId,
68 RefPtr<PlatformResRegister> platformResRegister)
69 : window_(window), taskExecutor_(std::move(taskExecutor)), assetManager_(std::move(assetManager)),
70 weakFrontend_(frontend), instanceId_(instanceId), platformResRegister_(std::move(platformResRegister))
71 {
72 CHECK_NULL_VOID(frontend);
73 frontendType_ = frontend->GetType();
74 eventManager_ = AceType::MakeRefPtr<EventManager>();
75 windowManager_ = AceType::MakeRefPtr<WindowManager>();
76 eventManager_->SetInstanceId(instanceId);
77 imageCache_ = ImageCache::Create();
78 fontManager_ = FontManager::Create();
79 auto&& vsyncCallback = [weak = AceType::WeakClaim(this), instanceId](
80 uint64_t nanoTimestamp, uint64_t frameCount) {
81 ContainerScope scope(instanceId);
82 auto context = weak.Upgrade();
83 if (context) {
84 context->OnVsyncEvent(nanoTimestamp, frameCount);
85 }
86 };
87 ACE_DCHECK(window_);
88 window_->SetVsyncCallback(vsyncCallback);
89 }
90
GetPerfMonitor()91 std::shared_ptr<ArkUIPerfMonitor> PipelineBase::GetPerfMonitor()
92 {
93 if (!perfMonitor_) {
94 perfMonitor_ = std::make_shared<ArkUIPerfMonitor>();
95 }
96 return perfMonitor_;
97 }
98
~PipelineBase()99 PipelineBase::~PipelineBase()
100 {
101 NG::UiNodeGc::PostReleaseNodeRawMemoryTask(taskExecutor_);
102 std::lock_guard lock(destructMutex_);
103 LOGI("PipelineBase destroyed");
104 }
105
SetCallBackNode(const WeakPtr<NG::FrameNode> & node)106 void PipelineBase::SetCallBackNode(const WeakPtr<NG::FrameNode>& node)
107 {
108 auto pipelineContext = PipelineContext::GetCurrentContext();
109 CHECK_NULL_VOID(pipelineContext);
110 pipelineContext->UpdateCurrentActiveNode(node);
111 }
112
GetCurrentContext()113 RefPtr<PipelineBase> PipelineBase::GetCurrentContext()
114 {
115 auto currentContainer = Container::Current();
116 CHECK_NULL_RETURN(currentContainer, nullptr);
117 return currentContainer->GetPipelineContext();
118 }
119
GetCurrentContextSafely()120 RefPtr<PipelineBase> PipelineBase::GetCurrentContextSafely()
121 {
122 auto currentContainer = Container::CurrentSafely();
123 CHECK_NULL_RETURN(currentContainer, nullptr);
124 return currentContainer->GetPipelineContext();
125 }
126
GetCurrentContextSafelyWithCheck()127 RefPtr<PipelineBase> PipelineBase::GetCurrentContextSafelyWithCheck()
128 {
129 auto currentContainer = Container::CurrentSafelyWithCheck();
130 CHECK_NULL_RETURN(currentContainer, nullptr);
131 return currentContainer->GetPipelineContext();
132 }
133
GetCurrentDensity()134 double PipelineBase::GetCurrentDensity()
135 {
136 auto pipelineContext = PipelineContext::GetCurrentContextSafely();
137 if (!pipelineContext) {
138 auto container = Container::GetActive();
139 pipelineContext = container ? container->GetPipelineContext() : nullptr;
140 }
141 CHECK_NULL_RETURN(pipelineContext, SystemProperties::GetDefaultResolution());
142 double wmDensity = pipelineContext->GetWindowDensity();
143 if (GreatNotEqual(wmDensity, 1.0)) {
144 return wmDensity;
145 }
146 return pipelineContext->GetDensity();
147 }
148
GetCurrentColorMode()149 ColorMode PipelineBase::GetCurrentColorMode()
150 {
151 auto currentContainer = Container::CurrentSafely();
152 CHECK_NULL_RETURN(currentContainer, ColorMode::LIGHT);
153 return currentContainer->GetColorMode();
154 }
155
Px2VpWithCurrentDensity(double px)156 double PipelineBase::Px2VpWithCurrentDensity(double px)
157 {
158 double density = PipelineBase::GetCurrentDensity();
159 return px / density;
160 }
161
Vp2PxWithCurrentDensity(double vp)162 double PipelineBase::Vp2PxWithCurrentDensity(double vp)
163 {
164 double density = PipelineBase::GetCurrentDensity();
165 return vp * density;
166 }
167
GetMainPipelineContext()168 RefPtr<PipelineBase> PipelineBase::GetMainPipelineContext()
169 {
170 auto containerId = Container::CurrentId();
171 RefPtr<PipelineBase> context;
172 if (containerId >= MIN_SUBCONTAINER_ID) {
173 auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(containerId);
174 auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
175 CHECK_NULL_RETURN(parentContainer, nullptr);
176 context = parentContainer->GetPipelineContext();
177 } else {
178 context = PipelineBase::GetCurrentContext();
179 }
180 return context;
181 }
182
CurrentThemeManager()183 RefPtr<ThemeManager> PipelineBase::CurrentThemeManager()
184 {
185 auto pipelineContext = OHOS::Ace::PipelineBase::GetCurrentContext();
186 #ifdef PLUGIN_COMPONENT_SUPPORTED
187 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
188 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
189 CHECK_NULL_RETURN(pluginContainer, nullptr);
190 pipelineContext = pluginContainer->GetPipelineContext();
191 }
192 #endif
193 CHECK_NULL_RETURN(pipelineContext, nullptr);
194 return pipelineContext->GetThemeManager();
195 }
196
GetTimeFromExternalTimer()197 uint64_t PipelineBase::GetTimeFromExternalTimer()
198 {
199 static const int64_t secToNanosec = 1000000000;
200 struct timespec ts;
201 clock_gettime(CLOCK_MONOTONIC, &ts);
202 return (ts.tv_sec * secToNanosec + ts.tv_nsec);
203 }
204
Vp2PxInner(double vpValue) const205 double PipelineBase::Vp2PxInner(double vpValue) const
206 {
207 double density = GetWindowDensity();
208 if (LessOrEqual(density, 1.0)) {
209 density = GetDensity();
210 }
211 return vpValue * density;
212 }
213
CalcPageWidth(double rootWidth) const214 double PipelineBase::CalcPageWidth(double rootWidth) const
215 {
216 if (!IsArkUIHookEnabled() || !isCurrentInForceSplitMode_) {
217 return rootWidth;
218 }
219 // Divider Width equal to 1.0_vp
220 constexpr double HALF = 2.0;
221 return (rootWidth - Vp2PxInner(1.0)) / HALF;
222 }
223
GetPageWidth() const224 double PipelineBase::GetPageWidth() const
225 {
226 auto pageWidth = rootWidth_;
227 if (IsContainerModalVisible()) {
228 pageWidth -= 2 * Vp2PxInner((CONTAINER_BORDER_WIDTH + CONTENT_PADDING).Value());
229 }
230 return CalcPageWidth(pageWidth);
231 }
232
RequestFrame()233 void PipelineBase::RequestFrame()
234 {
235 if (window_) {
236 window_->RequestFrame();
237 }
238 }
239
GetFrontend() const240 RefPtr<Frontend> PipelineBase::GetFrontend() const
241 {
242 return weakFrontend_.Upgrade();
243 }
244
ClearImageCache()245 void PipelineBase::ClearImageCache()
246 {
247 std::lock_guard<std::shared_mutex> lock(imageMtx_);
248 if (imageCache_) {
249 imageCache_->Clear();
250 }
251 }
252
SetImageCache(const RefPtr<ImageCache> & imageCache)253 void PipelineBase::SetImageCache(const RefPtr<ImageCache>& imageCache)
254 {
255 std::lock_guard<std::shared_mutex> lock(imageMtx_);
256 if (imageCache) {
257 imageCache_ = imageCache;
258 }
259 }
260
GetImageCache() const261 RefPtr<ImageCache> PipelineBase::GetImageCache() const
262 {
263 std::shared_lock<std::shared_mutex> lock(imageMtx_);
264 return imageCache_;
265 }
266
SetRootSize(double density,float width,float height)267 void PipelineBase::SetRootSize(double density, float width, float height)
268 {
269 ACE_SCOPED_TRACE("SetRootSize(%lf, %f, %f)", density, width, height);
270 density_ = density;
271 auto task = [weak = AceType::WeakClaim(this), width, height]() {
272 auto context = weak.Upgrade();
273 if (!context) {
274 return;
275 }
276 context->SetRootRect(width, height);
277 };
278
279 if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
280 task();
281 } else {
282 taskExecutor_->PostTask(task, TaskExecutor::TaskType::UI, "ArkUISetRootSize");
283 }
284 }
285
SetFontScale(float fontScale)286 void PipelineBase::SetFontScale(float fontScale)
287 {
288 const static float CARD_MAX_FONT_SCALE = 1.3f;
289 if (!NearEqual(fontScale_, fontScale)) {
290 fontScale_ = fontScale;
291 if ((isJsCard_ || (isFormRender_ && !isDynamicRender_)) && GreatOrEqual(fontScale_, CARD_MAX_FONT_SCALE)) {
292 fontScale_ = CARD_MAX_FONT_SCALE;
293 }
294 auto pipelineContext = PipelineContext::GetCurrentContext();
295 CHECK_NULL_VOID(pipelineContext);
296 pipelineContext->RebuildFontNode();
297 }
298 }
299
NeedTouchInterpolation()300 bool PipelineBase::NeedTouchInterpolation()
301 {
302 if (!IsFocusWindowIdSetted()) {
303 return true;
304 }
305 auto container = Container::GetContainer(instanceId_);
306 CHECK_NULL_RETURN(container, false);
307 auto uIContentType = container->GetUIContentType();
308 return SystemProperties::IsNeedResampleTouchPoints() &&
309 (uIContentType == UIContentType::SECURITY_UI_EXTENSION ||
310 uIContentType == UIContentType::MODAL_UI_EXTENSION ||
311 uIContentType == UIContentType::UI_EXTENSION);
312 }
313
SetFontWeightScale(float fontWeightScale)314 void PipelineBase::SetFontWeightScale(float fontWeightScale)
315 {
316 const static float CARD_MAX_FONT_WEIGHT_SCALE = 1.25f;
317 if (!NearEqual(fontWeightScale_, fontWeightScale)) {
318 fontWeightScale_ = fontWeightScale;
319 if (isJsCard_ && GreatOrEqual(fontWeightScale_, CARD_MAX_FONT_WEIGHT_SCALE)) {
320 fontWeightScale_ = CARD_MAX_FONT_WEIGHT_SCALE;
321 }
322 auto pipelineContext = PipelineContext::GetCurrentContext();
323 CHECK_NULL_VOID(pipelineContext);
324 pipelineContext->RebuildFontNode();
325 }
326 }
327
NormalizeToPx(const Dimension & dimension) const328 double PipelineBase::NormalizeToPx(const Dimension& dimension) const
329 {
330 if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
331 return (dimension.Value() * dipScale_);
332 } else if (dimension.Unit() == DimensionUnit::LPX) {
333 return (dimension.Value() * designWidthScale_);
334 }
335 return dimension.Value();
336 }
337
ConvertPxToVp(const Dimension & dimension) const338 double PipelineBase::ConvertPxToVp(const Dimension& dimension) const
339 {
340 if (dimension.Unit() == DimensionUnit::PX) {
341 return dimension.Value() / dipScale_;
342 }
343 return dimension.Value();
344 }
345
UpdateFontWeightScale()346 void PipelineBase::UpdateFontWeightScale()
347 {
348 if (fontManager_) {
349 fontManager_->UpdateFontWeightScale();
350 }
351 }
352
SetTextFieldManager(const RefPtr<ManagerInterface> & manager)353 void PipelineBase::SetTextFieldManager(const RefPtr<ManagerInterface>& manager)
354 {
355 textFieldManager_ = manager;
356 }
357
RegisterFont(const std::string & familyName,const std::string & familySrc,const std::string & bundleName,const std::string & moduleName)358 void PipelineBase::RegisterFont(const std::string& familyName, const std::string& familySrc,
359 const std::string& bundleName, const std::string& moduleName)
360 {
361 if (fontManager_) {
362 fontManager_->RegisterFont(familyName, familySrc, AceType::Claim(this), bundleName, moduleName);
363 }
364 }
365
GetSystemFontList(std::vector<std::string> & fontList)366 void PipelineBase::GetSystemFontList(std::vector<std::string>& fontList)
367 {
368 if (fontManager_) {
369 fontManager_->GetSystemFontList(fontList);
370 }
371 }
372
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)373 bool PipelineBase::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
374 {
375 if (fontManager_) {
376 return fontManager_->GetSystemFont(fontName, fontInfo);
377 }
378 return false;
379 }
380
GetUIFontConfig(FontConfigJsonInfo & fontConfigJsonInfo)381 void PipelineBase::GetUIFontConfig(FontConfigJsonInfo& fontConfigJsonInfo)
382 {
383 if (fontManager_) {
384 fontManager_->GetUIFontConfig(fontConfigJsonInfo);
385 }
386 }
387
HyperlinkStartAbility(const std::string & address) const388 void PipelineBase::HyperlinkStartAbility(const std::string& address) const
389 {
390 CHECK_RUN_ON(UI);
391 if (startAbilityHandler_) {
392 startAbilityHandler_(address);
393 }
394 }
395
StartAbilityOnQuery(const std::string & queryWord) const396 void PipelineBase::StartAbilityOnQuery(const std::string& queryWord) const
397 {
398 CHECK_RUN_ON(UI);
399 if (startAbilityOnQueryHandler_) {
400 startAbilityOnQueryHandler_(queryWord);
401 }
402 }
403
NotifyStatusBarBgColor(const Color & color) const404 void PipelineBase::NotifyStatusBarBgColor(const Color& color) const
405 {
406 CHECK_RUN_ON(UI);
407 if (statusBarBgColorEventHandler_) {
408 statusBarBgColorEventHandler_(color);
409 }
410 }
411
NotifyPopupDismiss() const412 void PipelineBase::NotifyPopupDismiss() const
413 {
414 CHECK_RUN_ON(UI);
415 if (popupEventHandler_) {
416 popupEventHandler_();
417 }
418 }
419
NotifyMenuDismiss() const420 void PipelineBase::NotifyMenuDismiss() const
421 {
422 CHECK_RUN_ON(UI);
423 if (menuEventHandler_) {
424 menuEventHandler_();
425 }
426 }
427
NotifyContextMenuDismiss() const428 void PipelineBase::NotifyContextMenuDismiss() const
429 {
430 CHECK_RUN_ON(UI);
431 if (contextMenuEventHandler_) {
432 contextMenuEventHandler_();
433 }
434 }
435
NotifyRouterBackDismiss() const436 void PipelineBase::NotifyRouterBackDismiss() const
437 {
438 CHECK_RUN_ON(UI);
439 if (routerBackEventHandler_) {
440 routerBackEventHandler_();
441 }
442 }
443
NotifyPopPageSuccessDismiss(const std::string & pageUrl,const int32_t pageId) const444 void PipelineBase::NotifyPopPageSuccessDismiss(const std::string& pageUrl, const int32_t pageId) const
445 {
446 CHECK_RUN_ON(UI);
447 for (auto& iterPopSuccessHander : popPageSuccessEventHandler_) {
448 if (iterPopSuccessHander) {
449 iterPopSuccessHander(pageUrl, pageId);
450 }
451 }
452 }
453
NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const454 void PipelineBase::NotifyIsPagePathInvalidDismiss(bool isPageInvalid) const
455 {
456 CHECK_RUN_ON(UI);
457 for (auto& iterPathInvalidHandler : isPagePathInvalidEventHandler_) {
458 if (iterPathInvalidHandler) {
459 iterPathInvalidHandler(isPageInvalid);
460 }
461 }
462 }
463
NotifyDestroyEventDismiss() const464 void PipelineBase::NotifyDestroyEventDismiss() const
465 {
466 CHECK_RUN_ON(UI);
467 for (auto& iterDestroyEventHander : destroyEventHandler_) {
468 if (iterDestroyEventHander) {
469 iterDestroyEventHander();
470 }
471 }
472 }
473
NotifyDispatchTouchEventDismiss(const TouchEvent & event) const474 void PipelineBase::NotifyDispatchTouchEventDismiss(const TouchEvent& event) const
475 {
476 CHECK_RUN_ON(UI);
477 for (auto& iterDispatchTouchEventHandler : dispatchTouchEventHandler_) {
478 if (iterDispatchTouchEventHandler) {
479 iterDispatchTouchEventHandler(event);
480 }
481 }
482 }
483
OnActionEvent(const std::string & action)484 void PipelineBase::OnActionEvent(const std::string& action)
485 {
486 CHECK_RUN_ON(UI);
487 if (actionEventHandler_) {
488 actionEventHandler_(action);
489 }
490 }
491
onRouterChange(const std::string & url)492 void PipelineBase::onRouterChange(const std::string& url)
493 {
494 if (onRouterChangeCallback_ != nullptr) {
495 onRouterChangeCallback_(url);
496 }
497 }
498
TryLoadImageInfo(const std::string & src,std::function<void (bool,int32_t,int32_t)> && loadCallback)499 void PipelineBase::TryLoadImageInfo(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& loadCallback)
500 {
501 ImageProvider::TryLoadImageInfo(AceType::Claim(this), src, std::move(loadCallback));
502 }
503
CreateOffscreenCanvas(int32_t width,int32_t height)504 RefPtr<OffscreenCanvas> PipelineBase::CreateOffscreenCanvas(int32_t width, int32_t height)
505 {
506 return RenderOffscreenCanvas::Create(AceType::WeakClaim(this), width, height);
507 }
508
PostAsyncEvent(TaskExecutor::Task && task,const std::string & name,TaskExecutor::TaskType type)509 void PipelineBase::PostAsyncEvent(TaskExecutor::Task&& task, const std::string& name, TaskExecutor::TaskType type)
510 {
511 if (taskExecutor_) {
512 taskExecutor_->PostTask(std::move(task), type, name);
513 }
514 }
515
PostAsyncEvent(const TaskExecutor::Task & task,const std::string & name,TaskExecutor::TaskType type)516 void PipelineBase::PostAsyncEvent(const TaskExecutor::Task& task, const std::string& name, TaskExecutor::TaskType type)
517 {
518 if (taskExecutor_) {
519 taskExecutor_->PostTask(task, type, name);
520 }
521 }
522
PostSyncEvent(const TaskExecutor::Task & task,const std::string & name,TaskExecutor::TaskType type)523 void PipelineBase::PostSyncEvent(const TaskExecutor::Task& task, const std::string& name, TaskExecutor::TaskType type)
524 {
525 if (taskExecutor_) {
526 taskExecutor_->PostSyncTask(task, type, name);
527 }
528 }
529
UpdateRootSizeAndScale(int32_t width,int32_t height)530 void PipelineBase::UpdateRootSizeAndScale(int32_t width, int32_t height)
531 {
532 ForceUpdateDesignWidthScale(width);
533 if (NearZero(viewScale_)) {
534 return;
535 }
536 dipScale_ = density_ / viewScale_;
537 rootHeight_ = height / viewScale_;
538 rootWidth_ = width / viewScale_;
539 }
540
DumpFrontend() const541 void PipelineBase::DumpFrontend() const
542 {
543 auto frontend = weakFrontend_.Upgrade();
544 CHECK_NULL_VOID(frontend);
545 auto lock = frontend->GetLock();
546 frontend->DumpFrontend();
547 }
548
Dump(const std::vector<std::string> & params) const549 bool PipelineBase::Dump(const std::vector<std::string>& params) const
550 {
551 if (params.empty()) {
552 return false;
553 }
554 // the first param is the key word of dump.
555 if (params[0] == "-memory") {
556 MemoryMonitor::GetInstance().Dump();
557 DumpUIExt();
558 return true;
559 }
560 if (params[0] == "-jscrash") {
561 ContainerScope scope(instanceId_);
562 EventReport::JsErrReport(Container::CurrentBundleName(), "js crash reason", "js crash summary");
563 return true;
564 }
565 // hiview report dump will provide three params .
566 if (params[0] == "-hiviewreport" && params.size() >= 3) {
567 DumpLog::GetInstance().Print("Report hiview event. EventType: " + params[1] + ", error type: " + params[2]);
568 EventInfo eventInfo = { .eventType = params[1], .errorType = StringUtils::StringToInt(params[2]) };
569 EventReport::SendEvent(eventInfo);
570 return true;
571 }
572 ContainerScope scope(instanceId_);
573 if (params[0] == "-frontend") {
574 DumpFrontend();
575 DumpUIExt();
576 return true;
577 }
578 return OnDumpInfo(params);
579 }
580
IsDestroyed()581 bool PipelineBase::IsDestroyed()
582 {
583 return destroyed_;
584 }
585
SetDestroyed()586 void PipelineBase::SetDestroyed()
587 {
588 destroyed_ = true;
589 }
590
ForceLayoutForImplicitAnimation()591 void PipelineBase::ForceLayoutForImplicitAnimation()
592 {
593 if (!pendingImplicitLayout_.empty()) {
594 pendingImplicitLayout_.top() = true;
595 }
596 if (!pendingFrontendAnimation_.empty()) {
597 pendingFrontendAnimation_.top() = true;
598 }
599 }
600
ForceRenderForImplicitAnimation()601 void PipelineBase::ForceRenderForImplicitAnimation()
602 {
603 if (!pendingImplicitRender_.empty()) {
604 pendingImplicitRender_.top() = true;
605 }
606 if (!pendingFrontendAnimation_.empty()) {
607 pendingFrontendAnimation_.top() = true;
608 }
609 }
610
Animate(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & propertyCallback,const std::function<void ()> & finishCallback)611 bool PipelineBase::Animate(const AnimationOption& option, const RefPtr<Curve>& curve,
612 const std::function<void()>& propertyCallback, const std::function<void()>& finishCallback)
613 {
614 if (!propertyCallback) {
615 return false;
616 }
617
618 OpenImplicitAnimation(option, curve, finishCallback);
619 propertyCallback();
620 return CloseImplicitAnimation();
621 }
622
GetUnexecutedFinishCount() const623 std::string PipelineBase::GetUnexecutedFinishCount() const
624 {
625 std::string finishCountToString;
626 for (const auto& element : finishCount_) {
627 finishCountToString += std::to_string(element) + " ";
628 }
629 return "[ " + finishCountToString + "]";
630 }
631
GetWrappedAnimationCallback(const AnimationOption & option,const std::function<void ()> & finishCallback,const std::optional<int32_t> & count)632 std::function<void()> PipelineBase::GetWrappedAnimationCallback(
633 const AnimationOption& option, const std::function<void()>& finishCallback, const std::optional<int32_t>& count)
634 {
635 if (!IsFormRenderExceptDynamicComponent() && !finishCallback) {
636 return nullptr;
637 }
638 auto finishPtr = std::make_shared<std::function<void()>>(finishCallback);
639 finishFunctions_.emplace(finishPtr);
640
641 // When the animateTo or keyframeAnimateTo has finishCallback and iteration is not infinite,
642 // count needs to be saved.
643 if (count.has_value() && option.GetIteration() != ANIMATION_REPEAT_INFINITE) {
644 finishCount_.emplace(count.value());
645 }
646 auto wrapFinishCallback = [weak = AceType::WeakClaim(this),
647 finishWeak = std::weak_ptr<std::function<void()>>(finishPtr), count]() {
648 auto context = weak.Upgrade();
649 CHECK_NULL_VOID(context);
650 auto finishPtr = finishWeak.lock();
651 CHECK_NULL_VOID(finishPtr);
652 context->finishFunctions_.erase(finishPtr);
653 if (count.has_value() && !context->finishFunctions_.count(finishPtr)) {
654 context->finishCount_.erase(count.value());
655 }
656 if (!(*finishPtr)) {
657 if (context->IsFormRenderExceptDynamicComponent()) {
658 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form animation is finish.");
659 context->SetIsFormAnimation(false);
660 }
661 return;
662 }
663 if (context->IsFormRenderExceptDynamicComponent()) {
664 TAG_LOGI(AceLogTag::ACE_FORM, "[Form animation] Form animation is finish.");
665 context->SetFormAnimationFinishCallback(true);
666 (*finishPtr)();
667 context->FlushBuild();
668 context->SetFormAnimationFinishCallback(false);
669 context->SetIsFormAnimation(false);
670 return;
671 }
672 (*finishPtr)();
673 };
674 return wrapFinishCallback;
675 }
676
PrepareOpenImplicitAnimation()677 void PipelineBase::PrepareOpenImplicitAnimation()
678 {
679 #ifdef ENABLE_ROSEN_BACKEND
680 // initialize false for implicit animation layout and render pending flag
681 pendingImplicitLayout_.push(false);
682 pendingImplicitRender_.push(false);
683
684 // flush ui tasks before open implicit animation
685 if (!IsLayouting()) {
686 FlushUITasks(true);
687 }
688 #endif
689 }
690
PrepareCloseImplicitAnimation()691 void PipelineBase::PrepareCloseImplicitAnimation()
692 {
693 #ifdef ENABLE_ROSEN_BACKEND
694 if (pendingImplicitLayout_.empty() && pendingImplicitRender_.empty()) {
695 return;
696 }
697
698 // layout or render the views immediately to animate all related views, if layout or render updates are pending in
699 // the animation closure
700 if (pendingImplicitLayout_.top() || pendingImplicitRender_.top()) {
701 if (!IsLayouting()) {
702 FlushUITasks(true);
703 } else if (IsLayouting()) {
704 LOGW("IsLayouting, prepareCloseImplicitAnimation has tasks not flushed");
705 }
706 }
707 if (!pendingImplicitLayout_.empty()) {
708 pendingImplicitLayout_.pop();
709 }
710 if (!pendingImplicitRender_.empty()) {
711 pendingImplicitRender_.pop();
712 }
713 #endif
714 }
715
OpenImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)716 void PipelineBase::OpenImplicitAnimation(
717 const AnimationOption& option,
718 const RefPtr<Curve>& curve,
719 const std::function<void()>& finishCallback)
720 {
721 #ifdef ENABLE_ROSEN_BACKEND
722 PrepareOpenImplicitAnimation();
723 StartImplicitAnimation(option, curve, finishCallback);
724 #endif
725 }
726
StartImplicitAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback,const std::optional<int32_t> & count)727 void PipelineBase::StartImplicitAnimation(const AnimationOption& option, const RefPtr<Curve>& curve,
728 const std::function<void()>& finishCallback, const std::optional<int32_t>& count)
729 {
730 #ifdef ENABLE_ROSEN_BACKEND
731 auto wrapFinishCallback = GetWrappedAnimationCallback(option, finishCallback, count);
732 if (IsFormRenderExceptDynamicComponent()) {
733 SetIsFormAnimation(true);
734 if (!IsFormAnimationFinishCallback()) {
735 SetFormAnimationStartTime(GetMicroTickCount());
736 }
737 }
738 AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
739 #endif
740 }
741
CloseImplicitAnimation()742 bool PipelineBase::CloseImplicitAnimation()
743 {
744 #ifdef ENABLE_ROSEN_BACKEND
745 PrepareCloseImplicitAnimation();
746 return AnimationUtils::CloseImplicitAnimation();
747 #else
748 return false;
749 #endif
750 }
751
OnVsyncEvent(uint64_t nanoTimestamp,uint64_t frameCount)752 void PipelineBase::OnVsyncEvent(uint64_t nanoTimestamp, uint64_t frameCount)
753 {
754 CHECK_RUN_ON(UI);
755 ACE_SCOPED_TRACE("OnVsyncEvent now:%" PRIu64 "", nanoTimestamp);
756 frameCount_ = frameCount;
757
758 recvTime_ = GetSysTimestamp();
759 currRecvTime_ = recvTime_;
760 compensationValue_ =
761 nanoTimestamp > static_cast<uint64_t>(recvTime_) ? (nanoTimestamp - static_cast<uint64_t>(recvTime_)) : 0;
762
763 for (auto& callback : subWindowVsyncCallbacks_) {
764 callback.second(nanoTimestamp, frameCount);
765 }
766
767 decltype(jsFormVsyncCallbacks_) jsFormVsyncCallbacks(std::move(jsFormVsyncCallbacks_));
768 for (auto& callback : jsFormVsyncCallbacks) {
769 callback.second(nanoTimestamp, frameCount);
770 }
771
772 if (onVsyncProfiler_) {
773 AceTracker::Start();
774 }
775
776 if (gsVsyncCallback_) {
777 gsVsyncCallback_();
778 }
779
780 FlushVsync(nanoTimestamp, frameCount);
781 if (onVsyncProfiler_) {
782 onVsyncProfiler_(AceTracker::Stop());
783 }
784 currRecvTime_ = -1;
785 }
786
ReachResponseDeadline() const787 bool PipelineBase::ReachResponseDeadline() const
788 {
789 if (currRecvTime_ >= 0) {
790 auto deadline = FeatureParam::GetSyncloadResponseDeadline();
791 return currRecvTime_ + deadline < GetSysTimestamp();
792 }
793 return false;
794 }
795
SetTouchPipeline(const WeakPtr<PipelineBase> & context)796 void PipelineBase::SetTouchPipeline(const WeakPtr<PipelineBase>& context)
797 {
798 auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
799 if (result == touchPluginPipelineContext_.end()) {
800 touchPluginPipelineContext_.emplace_back(context);
801 }
802 }
803
RemoveTouchPipeline(const WeakPtr<PipelineBase> & context)804 void PipelineBase::RemoveTouchPipeline(const WeakPtr<PipelineBase>& context)
805 {
806 auto result = std::find(touchPluginPipelineContext_.begin(), touchPluginPipelineContext_.end(), context);
807 if (result != touchPluginPipelineContext_.end()) {
808 touchPluginPipelineContext_.erase(result);
809 }
810 }
811
MarkUpdateSubwindowKeyboardInsert(int32_t instanceId,double keyboardHeight,int32_t type)812 bool PipelineBase::MarkUpdateSubwindowKeyboardInsert(int32_t instanceId, double keyboardHeight, int32_t type)
813 {
814 auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(instanceId, static_cast<SubwindowType>(type));
815 if (subwindow && subwindow->GetShown() && subwindow->IsFocused() && !CheckNeedAvoidInSubWindow() &&
816 !subwindow->NeedAvoidKeyboard()) {
817 // subwindow is shown, main window no need to handle the keyboard event
818 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "subwindow is shown and pageOffset is zero, main window doesn't lift");
819 CheckAndUpdateKeyboardInset(keyboardHeight);
820 return true;
821 }
822 return false;
823 }
824
OnVirtualKeyboardAreaChange(Rect keyboardArea,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,const float safeHeight,bool supportAvoidance,bool forceChange)825 void PipelineBase::OnVirtualKeyboardAreaChange(Rect keyboardArea,
826 const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, const float safeHeight, bool supportAvoidance,
827 bool forceChange)
828 {
829 auto currentContainer = Container::Current();
830 double keyboardHeight = keyboardArea.Height();
831 if (currentContainer && !currentContainer->IsSubContainer()) {
832 #ifdef OHOS_STANDARD_SYSTEM
833 int32_t instanceId = currentContainer->GetInstanceId();
834 if (MarkUpdateSubwindowKeyboardInsert(
835 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_DIALOG))) {
836 return;
837 }
838 if (MarkUpdateSubwindowKeyboardInsert(
839 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_POPUP))) {
840 return;
841 }
842 if (MarkUpdateSubwindowKeyboardInsert(
843 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_MENU))) {
844 return;
845 }
846 #endif
847 }
848 if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight, true)) {
849 return;
850 }
851 OnVirtualKeyboardHeightChange(keyboardHeight, rsTransaction, safeHeight, supportAvoidance, forceChange);
852 }
853
OnVirtualKeyboardAreaChange(Rect keyboardArea,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool forceChange)854 void PipelineBase::OnVirtualKeyboardAreaChange(Rect keyboardArea, double positionY, double height,
855 const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool forceChange)
856 {
857 auto currentContainer = Container::Current();
858 float keyboardHeight = keyboardArea.Height();
859 if (currentContainer && !currentContainer->IsSubContainer()) {
860 int32_t instanceId = currentContainer->GetInstanceId();
861 if (MarkUpdateSubwindowKeyboardInsert(
862 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_DIALOG))) {
863 return;
864 }
865 if (MarkUpdateSubwindowKeyboardInsert(
866 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_POPUP))) {
867 return;
868 }
869 if (MarkUpdateSubwindowKeyboardInsert(
870 instanceId, keyboardHeight, static_cast<int32_t>(SubwindowType::TYPE_MENU))) {
871 return;
872 }
873 }
874 if (NotifyVirtualKeyBoard(rootWidth_, rootHeight_, keyboardHeight, false)) {
875 return;
876 }
877 OnVirtualKeyboardHeightChange(keyboardHeight, positionY, height, rsTransaction, forceChange);
878 }
879
OnFoldStatusChanged(FoldStatus foldStatus)880 void PipelineBase::OnFoldStatusChanged(FoldStatus foldStatus)
881 {
882 OnFoldStatusChange(foldStatus);
883 }
884
OnFoldDisplayModeChanged(FoldDisplayMode foldDisplayMode)885 void PipelineBase::OnFoldDisplayModeChanged(FoldDisplayMode foldDisplayMode)
886 {
887 OnFoldDisplayModeChange(foldDisplayMode);
888 }
889
ModifyKeyboardHeight(double keyboardHeight) const890 double PipelineBase::ModifyKeyboardHeight(double keyboardHeight) const
891 {
892 auto windowRect = GetCurrentWindowRect();
893 auto deviceHeight = SystemProperties::GetDeviceHeight();
894 return keyboardHeight > 0.0 && keyboardHeight - (deviceHeight - windowRect.Bottom()) > 0.0
895 ? keyboardHeight - (deviceHeight - windowRect.Bottom())
896 : 0.0;
897 }
898
SetGetWindowRectImpl(std::function<Rect ()> && callback)899 void PipelineBase::SetGetWindowRectImpl(std::function<Rect()>&& callback)
900 {
901 if (window_) {
902 window_->SetGetWindowRectImpl(std::move(callback));
903 }
904 }
905
InitGetGlobalWindowRectCallback(std::function<Rect ()> && callback)906 void PipelineBase::InitGetGlobalWindowRectCallback(std::function<Rect()>&& callback)
907 {
908 CHECK_NULL_VOID(window_);
909 window_->InitGetGlobalWindowRectCallback(std::move(callback));
910 }
911
ContainerModalUnFocus()912 void PipelineBase::ContainerModalUnFocus() {}
913
GetCurrentWindowRect() const914 Rect PipelineBase::GetCurrentWindowRect() const
915 {
916 if (window_) {
917 Rect res = window_->GetCurrentWindowRect();
918 if (res.IsValid()) {
919 return res;
920 }
921 }
922 return Rect { 0.0, 0.0, width_, height_ };
923 }
924
GetGlobalDisplayWindowRect() const925 Rect PipelineBase::GetGlobalDisplayWindowRect() const
926 {
927 CHECK_NULL_RETURN(window_, {});
928 return window_->GetGlobalDisplayWindowRect();
929 }
930
IsArkUIHookEnabled() const931 bool PipelineBase::IsArkUIHookEnabled() const
932 {
933 auto hookEnabled = SystemProperties::GetArkUIHookEnabled();
934 if (hookEnabled.has_value()) {
935 return hookEnabled.value();
936 }
937 return isArkUIHookEnabled_;
938 }
939
HasFloatTitle() const940 bool PipelineBase::HasFloatTitle() const
941 {
942 CHECK_NULL_RETURN(windowManager_, false);
943 return GetWindowModal() == WindowModal::CONTAINER_MODAL &&
944 windowManager_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
945 }
946
GetAccessibilityManager() const947 RefPtr<AccessibilityManager> PipelineBase::GetAccessibilityManager() const
948 {
949 auto frontend = weakFrontend_.Upgrade();
950 if (!frontend) {
951 EventReport::SendAppStartException(AppStartExcepType::PIPELINE_CONTEXT_ERR);
952 return nullptr;
953 }
954 auto lock = frontend->GetLock();
955 return frontend->GetAccessibilityManager();
956 }
957
SendEventToAccessibility(const AccessibilityEvent & accessibilityEvent)958 void PipelineBase::SendEventToAccessibility(const AccessibilityEvent& accessibilityEvent)
959 {
960 auto accessibilityManager = GetAccessibilityManager();
961 if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
962 return;
963 }
964 accessibilityManager->SendAccessibilityAsyncEvent(accessibilityEvent);
965 }
966
FireUIExtensionEventValid()967 bool PipelineBase::FireUIExtensionEventValid()
968 {
969 if (!uiExtensionEventCallback_ || !IsFocusWindowIdSetted()) {
970 return false;
971 }
972 return true;
973 }
974
SetUIExtensionEventCallback(std::function<void (uint32_t)> && callback)975 void PipelineBase::SetUIExtensionEventCallback(std::function<void(uint32_t)>&& callback)
976 {
977 ACE_FUNCTION_TRACE();
978 uiExtensionEventCallback_ = callback;
979 }
980
AddUIExtensionCallbackEvent(NG::UIExtCallbackEventId eventId)981 void PipelineBase::AddUIExtensionCallbackEvent(NG::UIExtCallbackEventId eventId)
982 {
983 ACE_SCOPED_TRACE("AddUIExtensionCallbackEvent event[%u]", static_cast<uint32_t>(eventId));
984 uiExtensionEvents_.insert(NG::UIExtCallbackEvent(eventId));
985 }
986
FireAllUIExtensionEvents()987 void PipelineBase::FireAllUIExtensionEvents()
988 {
989 if (!FireUIExtensionEventValid() || uiExtensionEvents_.empty()) {
990 return;
991 }
992 std::vector<uint32_t> eventIds;
993 for (auto it = uiExtensionEvents_.begin(); it != uiExtensionEvents_.end();) {
994 eventIds.push_back(static_cast<uint32_t>(it->eventId));
995 if (!it->repeat) {
996 it = uiExtensionEvents_.erase(it);
997 } else {
998 ++it;
999 }
1000 }
1001 for (auto id : eventIds) {
1002 FireUIExtensionEventInner(id);
1003 }
1004 }
1005
FireUIExtensionEventOnceImmediately(NG::UIExtCallbackEventId eventId)1006 void PipelineBase::FireUIExtensionEventOnceImmediately(NG::UIExtCallbackEventId eventId)
1007 {
1008 if (!FireUIExtensionEventValid()) {
1009 return;
1010 }
1011 FireUIExtensionEventInner(static_cast<uint32_t>(eventId));
1012 }
1013
FireUIExtensionEventInner(uint32_t eventId)1014 void PipelineBase::FireUIExtensionEventInner(uint32_t eventId)
1015 {
1016 auto callback = uiExtensionEventCallback_;
1017 callback(eventId);
1018 }
1019
SetAccessibilityEventCallback(std::function<void (uint32_t,int64_t)> && callback)1020 void PipelineBase::SetAccessibilityEventCallback(std::function<void(uint32_t, int64_t)>&& callback)
1021 {
1022 ACE_FUNCTION_TRACE();
1023 accessibilityCallback_ = callback;
1024 }
1025
AddAccessibilityCallbackEvent(AccessibilityCallbackEventId event,int64_t parameter)1026 void PipelineBase::AddAccessibilityCallbackEvent(AccessibilityCallbackEventId event, int64_t parameter)
1027 {
1028 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
1029 ACE_SCOPED_TRACE("AccessibilityCallbackEvent event[%u]", static_cast<uint32_t>(event));
1030 accessibilityEvents_.insert(AccessibilityCallbackEvent(event, parameter));
1031 }
1032 }
1033
FireAccessibilityEvents()1034 void PipelineBase::FireAccessibilityEvents()
1035 {
1036 if (!accessibilityCallback_ || accessibilityEvents_.empty()) {
1037 return;
1038 }
1039 decltype(accessibilityEvents_) events;
1040 std::swap(accessibilityEvents_, events);
1041 for (auto &event : events) {
1042 FireAccessibilityEventInner(static_cast<uint32_t>(event.eventId), event.parameter);
1043 }
1044 }
1045
FireAccessibilityEventInner(uint32_t event,int64_t parameter)1046 void PipelineBase::FireAccessibilityEventInner(uint32_t event, int64_t parameter)
1047 {
1048 auto callback = accessibilityCallback_;
1049 callback(event, parameter);
1050 }
1051
SetSubWindowVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)1052 void PipelineBase::SetSubWindowVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
1053 {
1054 if (callback) {
1055 subWindowVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
1056 }
1057 }
1058
SetJsFormVsyncCallback(AceVsyncCallback && callback,int32_t subWindowId)1059 void PipelineBase::SetJsFormVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
1060 {
1061 if (callback) {
1062 jsFormVsyncCallbacks_.try_emplace(subWindowId, std::move(callback));
1063 }
1064 }
1065
RemoveSubWindowVsyncCallback(int32_t subWindowId)1066 void PipelineBase::RemoveSubWindowVsyncCallback(int32_t subWindowId)
1067 {
1068 subWindowVsyncCallbacks_.erase(subWindowId);
1069 }
1070
RemoveJsFormVsyncCallback(int32_t subWindowId)1071 void PipelineBase::RemoveJsFormVsyncCallback(int32_t subWindowId)
1072 {
1073 jsFormVsyncCallbacks_.erase(subWindowId);
1074 }
1075
MaybeRelease()1076 bool PipelineBase::MaybeRelease()
1077 {
1078 CHECK_NULL_RETURN(taskExecutor_, true);
1079 if (taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
1080 LOGI("Destroy Pipeline on UI thread.");
1081 return true;
1082 } else {
1083 std::lock_guard lock(destructMutex_);
1084 LOGI("Post Destroy Pipeline Task to UI thread.");
1085 return !taskExecutor_->PostTask([this] { delete this; }, TaskExecutor::TaskType::UI, "ArkUIDestroyPipeline");
1086 }
1087 }
1088
Destroy()1089 void PipelineBase::Destroy()
1090 {
1091 CHECK_RUN_ON(UI);
1092 destroyed_ = true;
1093 ClearImageCache();
1094 platformResRegister_.Reset();
1095 drawDelegate_.reset();
1096 if (eventManager_->GetCurrentMouseStyle() != MouseFormat::DEFAULT) {
1097 RestoreDefault(GetFocusWindowId(), MouseStyleChangeReason::CONTAINER_DESTROY_RESET_MOUSESTYLE);
1098 }
1099 eventManager_->ClearResults();
1100 {
1101 std::unique_lock<std::shared_mutex> lock(imageMtx_);
1102 imageCache_.Reset();
1103 }
1104 {
1105 std::unique_lock<std::shared_mutex> lock(themeMtx_);
1106 themeManager_.Reset();
1107 }
1108 fontManager_.Reset();
1109 window_->Destroy();
1110 touchPluginPipelineContext_.clear();
1111 virtualKeyBoardCallback_.clear();
1112 formLinkInfoMap_.clear();
1113 TAG_LOGI(AceLogTag::ACE_ANIMATION,
1114 "Pipeline destroyed, %{public}zu finish callbacks unexecuted, count: %{public}s",
1115 finishFunctions_.size(), GetUnexecutedFinishCount().c_str());
1116 finishFunctions_.clear();
1117 finishCount_.clear();
1118 animationOption_ = {};
1119 {
1120 // To avoid the race condition caused by the offscreen canvas get density from the pipeline in the worker
1121 // thread.
1122 std::lock_guard lock(densityChangeMutex_);
1123 densityChangedCallbacks_.clear();
1124 }
1125 }
1126
OnFormRecycle()1127 std::string PipelineBase::OnFormRecycle()
1128 {
1129 if (onFormRecycle_) {
1130 return onFormRecycle_();
1131 }
1132 LOGE("onFormRecycle_ is null.");
1133 return "";
1134 }
1135
OnFormRecover(const std::string & statusData)1136 void PipelineBase::OnFormRecover(const std::string& statusData)
1137 {
1138 if (onFormRecover_) {
1139 return onFormRecover_(statusData);
1140 }
1141 LOGE("onFormRecover_ is null.");
1142 }
1143
SetUiDvsyncSwitch(bool on)1144 void PipelineBase::SetUiDvsyncSwitch(bool on)
1145 {
1146 if (window_ && lastUiDvsyncStatus_ != on) {
1147 window_->SetUiDvsyncSwitch(on);
1148 }
1149 lastUiDvsyncStatus_ = on;
1150 }
1151
CheckIfGetTheme()1152 bool PipelineBase::CheckIfGetTheme()
1153 {
1154 auto container = Container::GetContainer(instanceId_);
1155 CHECK_NULL_RETURN(container, false);
1156 auto uIContentType = container->GetUIContentType();
1157 if (isJsCard_ || (isFormRender_ && uIContentType != UIContentType::DYNAMIC_COMPONENT)) {
1158 return false;
1159 }
1160 return true;
1161 }
1162
SetUiDVSyncCommandTime(uint64_t vsyncTime)1163 void PipelineBase::SetUiDVSyncCommandTime(uint64_t vsyncTime)
1164 {
1165 DVSyncChangeTime_ = vsyncTime;
1166 commandTimeUpdate_ = true;
1167 dvsyncTimeUpdate_ = true;
1168 dvsyncTimeUseCount_ = 0;
1169 }
1170
ForceUpdateDesignWidthScale(int32_t width)1171 void PipelineBase::ForceUpdateDesignWidthScale(int32_t width)
1172 {
1173 auto frontend = weakFrontend_.Upgrade();
1174 CHECK_NULL_VOID(frontend);
1175 auto lock = frontend->GetLock();
1176 auto& windowConfig = frontend->GetWindowConfig();
1177 if (windowConfig.designWidth <= 0) {
1178 return;
1179 }
1180 if (GetIsDeclarative()) {
1181 viewScale_ = DEFAULT_VIEW_SCALE;
1182 double pageWidth = width;
1183 if (IsContainerModalVisible()) {
1184 pageWidth -= 2 * (CONTAINER_BORDER_WIDTH + CONTENT_PADDING).ConvertToPx();
1185 }
1186 pageWidth = CalcPageWidth(pageWidth);
1187 designWidthScale_ =
1188 windowConfig.autoDesignWidth ? density_ : pageWidth / windowConfig.designWidth;
1189 windowConfig.designWidthScale = designWidthScale_;
1190 } else {
1191 viewScale_ = windowConfig.autoDesignWidth ? density_ : static_cast<double>(width) / windowConfig.designWidth;
1192 }
1193 }
1194 } // namespace OHOS::Ace
1195