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