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