• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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_ng/pipeline_context.h"
17 
18 #include "base/subwindow/subwindow_manager.h"
19 #include "core/components_ng/event/event_constants.h"
20 #include "core/event/key_event.h"
21 
22 #ifdef ENABLE_ROSEN_BACKEND
23 #include "render_service_client/core/transaction/rs_transaction.h"
24 #include "render_service_client/core/ui/rs_ui_director.h"
25 #endif
26 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
27 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
28 #include "frameworks/core/components_ng/base/inspector.h"
29 #endif
30 
31 #include "base/geometry/ng/offset_t.h"
32 #include "base/geometry/ng/rect_t.h"
33 #include "base/log/ace_performance_monitor.h"
34 #include "base/log/ace_trace.h"
35 #include "base/log/ace_tracker.h"
36 #include "base/log/dump_log.h"
37 #include "base/log/event_report.h"
38 #include "base/memory/ace_type.h"
39 #include "base/mousestyle/mouse_style.h"
40 #include "base/perfmonitor/perf_monitor.h"
41 #include "base/ressched/ressched_report.h"
42 #include "core/common/ace_engine.h"
43 #include "core/common/font_manager.h"
44 #include "core/common/font_change_observer.h"
45 #include "core/common/ime/input_method_manager.h"
46 #include "core/common/layout_inspector.h"
47 #include "core/common/stylus/stylus_detector_default.h"
48 #include "core/common/stylus/stylus_detector_mgr.h"
49 #include "core/common/text_field_manager.h"
50 #include "core/components_ng/base/view_advanced_register.h"
51 #include "core/components_ng/pattern/container_modal/container_modal_view_factory.h"
52 #include "core/components_ng/pattern/container_modal/enhance/container_modal_pattern_enhance.h"
53 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
54 #include "core/components_ng/pattern/navigation/nav_bar_node.h"
55 #include "core/components_ng/pattern/root/root_pattern.h"
56 #include "core/components_ng/pattern/text_field/text_field_manager.h"
57 #ifdef WINDOW_SCENE_SUPPORTED
58 #include "core/components_ng/pattern/window_scene/scene/window_scene_layout_manager.h"
59 #endif
60 #include "core/image/image_file_cache.h"
61 #include "core/pipeline/pipeline_context.h"
62 
63 namespace {
64 constexpr uint64_t ONE_MS_IN_NS = 1 * 1000 * 1000;
65 constexpr int32_t TIME_THRESHOLD = 2 * 1000000; // 3 millisecond
66 constexpr int32_t PLATFORM_VERSION_TEN = 10;
67 constexpr int32_t USED_ID_FIND_FLAG = 3;                 // if args >3 , it means use id to find
68 constexpr int32_t MILLISECONDS_TO_NANOSECONDS = 1000000; // Milliseconds to nanoseconds
69 constexpr int32_t VSYNC_PERIOD_COUNT = 5;
70 constexpr int32_t MIN_IDLE_TIME = 1000000;
71 constexpr uint8_t SINGLECOLOR_UPDATE_ALPHA = 75;
72 constexpr int8_t RENDERING_SINGLE_COLOR = 1;
73 constexpr int32_t MAX_MISS_COUNT = 3;
74 constexpr int32_t DELAY_TIME = 500;
75 
76 } // namespace
77 
78 namespace OHOS::Ace::NG {
79 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,RefPtr<PlatformResRegister> platformResRegister,const RefPtr<Frontend> & frontend,int32_t instanceId)80 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
81     RefPtr<AssetManager> assetManager, RefPtr<PlatformResRegister> platformResRegister,
82     const RefPtr<Frontend>& frontend, int32_t instanceId)
83     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId, platformResRegister)
84 {
85     window_->OnHide();
86 }
87 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)88 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
89     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
90     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId)
91 {
92     window_->OnHide();
93 }
94 
GetCurrentContext()95 RefPtr<PipelineContext> PipelineContext::GetCurrentContext()
96 {
97     auto currentContainer = Container::Current();
98     CHECK_NULL_RETURN(currentContainer, nullptr);
99     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
100 }
101 
GetCurrentContextSafely()102 RefPtr<PipelineContext> PipelineContext::GetCurrentContextSafely()
103 {
104     auto currentContainer = Container::CurrentSafely();
105     CHECK_NULL_RETURN(currentContainer, nullptr);
106     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
107 }
108 
GetCurrentContextSafelyWithCheck()109 RefPtr<PipelineContext> PipelineContext::GetCurrentContextSafelyWithCheck()
110 {
111     auto currentContainer = Container::CurrentSafelyWithCheck();
112     CHECK_NULL_RETURN(currentContainer, nullptr);
113     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
114 }
115 
GetCurrentContextPtrSafely()116 PipelineContext* PipelineContext::GetCurrentContextPtrSafely()
117 {
118     auto currentContainer = Container::CurrentSafely();
119     CHECK_NULL_RETURN(currentContainer, nullptr);
120     const auto& base = currentContainer->GetPipelineContext();
121     CHECK_NULL_RETURN(base, nullptr);
122     return DynamicCast<PipelineContext>(RawPtr(base));
123 }
124 
GetCurrentContextPtrSafelyWithCheck()125 PipelineContext* PipelineContext::GetCurrentContextPtrSafelyWithCheck()
126 {
127     auto currentContainer = Container::CurrentSafelyWithCheck();
128     CHECK_NULL_RETURN(currentContainer, nullptr);
129     const auto& base = currentContainer->GetPipelineContext();
130     CHECK_NULL_RETURN(base, nullptr);
131     return DynamicCast<PipelineContext>(RawPtr(base));
132 }
133 
GetMainPipelineContext()134 RefPtr<PipelineContext> PipelineContext::GetMainPipelineContext()
135 {
136     auto pipeline = PipelineBase::GetMainPipelineContext();
137     CHECK_NULL_RETURN(pipeline, nullptr);
138     return DynamicCast<PipelineContext>(pipeline);
139 }
140 
NeedSoftKeyboard()141 bool PipelineContext::NeedSoftKeyboard()
142 {
143     auto needKeyboard = InputMethodManager::GetInstance()->NeedSoftKeyboard();
144     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "need keyboard : %{public}d.", needKeyboard);
145     return needKeyboard;
146 }
147 
GetContextByContainerId(int32_t containerId)148 RefPtr<PipelineContext> PipelineContext::GetContextByContainerId(int32_t containerId)
149 {
150     auto preContainer = Container::GetContainer(containerId);
151     CHECK_NULL_RETURN(preContainer, nullptr);
152     return DynamicCast<PipelineContext>(preContainer->GetPipelineContext());
153 }
154 
GetCurrentRootWidth()155 float PipelineContext::GetCurrentRootWidth()
156 {
157     auto context = GetCurrentContext();
158     CHECK_NULL_RETURN(context, 0.0f);
159     return static_cast<float>(context->rootWidth_);
160 }
161 
GetCurrentRootHeight()162 float PipelineContext::GetCurrentRootHeight()
163 {
164     auto context = GetCurrentContext();
165     CHECK_NULL_RETURN(context, 0.0f);
166     return static_cast<float>(context->rootHeight_);
167 }
168 
AddDirtyPropertyNode(const RefPtr<FrameNode> & dirtyNode)169 void PipelineContext::AddDirtyPropertyNode(const RefPtr<FrameNode>& dirtyNode)
170 {
171     if (!CheckThreadSafe()) {
172         LOGW("AddDirtyPropertyNode doesn't run on UI thread!");
173     }
174     dirtyPropertyNodes_.emplace(dirtyNode);
175     hasIdleTasks_ = true;
176     RequestFrame();
177 }
178 
AddDirtyCustomNode(const RefPtr<UINode> & dirtyNode)179 void PipelineContext::AddDirtyCustomNode(const RefPtr<UINode>& dirtyNode)
180 {
181     CHECK_RUN_ON(UI);
182     CHECK_NULL_VOID(dirtyNode);
183     auto customNode = DynamicCast<CustomNode>(dirtyNode);
184     if (customNode && !dirtyNode->GetInspectorIdValue("").empty()) {
185         ACE_BUILD_TRACE_BEGIN("AddDirtyCustomNode[%s][self:%d][parent:%d][key:%s]",
186             customNode->GetJSViewName().c_str(),
187             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0,
188             dirtyNode->GetInspectorIdValue("").c_str());
189         ACE_BUILD_TRACE_END()
190     } else if (customNode) {
191         ACE_BUILD_TRACE_BEGIN("AddDirtyCustomNode[%s][self:%d][parent:%d]",
192             customNode->GetJSViewName().c_str(),
193             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0);
194         ACE_BUILD_TRACE_END()
195     }
196     dirtyNodes_.emplace(dirtyNode);
197     hasIdleTasks_ = true;
198     RequestFrame();
199 }
200 
AddDirtyLayoutNode(const RefPtr<FrameNode> & dirty)201 void PipelineContext::AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty)
202 {
203     CHECK_RUN_ON(UI);
204     CHECK_NULL_VOID(dirty);
205     if (IsDestroyed()) {
206         LOGW("Cannot add dirty layout node as the pipeline context is destroyed.");
207         return;
208     }
209     if (!dirty->GetInspectorIdValue("").empty()) {
210         ACE_BUILD_TRACE_BEGIN("AddDirtyLayoutNode[%s][self:%d][parent:%d][key:%s]",
211             dirty->GetTag().c_str(),
212             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
213             dirty->GetInspectorIdValue("").c_str());
214         ACE_BUILD_TRACE_END()
215     } else {
216         ACE_BUILD_TRACE_BEGIN("AddDirtyLayoutNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
217             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
218         ACE_BUILD_TRACE_END()
219     }
220     if (!dirty->IsOnMainTree() && predictNode_) {
221         predictNode_->AddPredictLayoutNode(dirty);
222         return;
223     }
224     taskScheduler_->AddDirtyLayoutNode(dirty);
225     ForceLayoutForImplicitAnimation();
226 #ifdef UICAST_COMPONENT_SUPPORTED
227     do {
228         auto container = Container::Current();
229         CHECK_NULL_BREAK(container);
230         auto distributedUI = container->GetDistributedUI();
231         CHECK_NULL_BREAK(distributedUI);
232         distributedUI->AddDirtyLayoutNode(dirty->GetId());
233     } while (false);
234 #endif
235     hasIdleTasks_ = true;
236     if (dirty->GetTag() == V2::ROOT_ETS_TAG && isFirstRootLayout_) {
237         isFirstRootLayout_ = false;
238         LOGI("Root node request first frame.");
239     }
240     RequestFrame();
241 }
242 
AddLayoutNode(const RefPtr<FrameNode> & layoutNode)243 void PipelineContext::AddLayoutNode(const RefPtr<FrameNode>& layoutNode)
244 {
245     taskScheduler_->AddLayoutNode(layoutNode);
246 }
247 
AddDirtyRenderNode(const RefPtr<FrameNode> & dirty)248 void PipelineContext::AddDirtyRenderNode(const RefPtr<FrameNode>& dirty)
249 {
250     CHECK_RUN_ON(UI);
251     CHECK_NULL_VOID(dirty);
252     if (IsDestroyed()) {
253         LOGW("Cannot add dirty render node as the pipeline context is destroyed.");
254         return;
255     }
256     if (!dirty->GetInspectorIdValue("").empty()) {
257         ACE_BUILD_TRACE_BEGIN("AddDirtyRenderNode[%s][self:%d][parent:%d][key:%s]", dirty->GetTag().c_str(),
258             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
259             dirty->GetInspectorIdValue("").c_str());
260         ACE_BUILD_TRACE_END()
261     } else {
262         ACE_BUILD_TRACE_BEGIN("AddDirtyRenderNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
263             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
264         ACE_BUILD_TRACE_END()
265     }
266     taskScheduler_->AddDirtyRenderNode(dirty);
267     ForceRenderForImplicitAnimation();
268 #ifdef UICAST_COMPONENT_SUPPORTED
269     do {
270         auto container = Container::Current();
271         CHECK_NULL_BREAK(container);
272         auto distributedUI = container->GetDistributedUI();
273         CHECK_NULL_BREAK(distributedUI);
274         distributedUI->AddDirtyRenderNode(dirty->GetId());
275     } while (false);
276 #endif
277     hasIdleTasks_ = true;
278     RequestFrame();
279 }
280 
AddDirtyFreezeNode(FrameNode * node)281 void PipelineContext::AddDirtyFreezeNode(FrameNode* node)
282 {
283     dirtyFreezeNode_.emplace_back(WeakClaim(node));
284     hasIdleTasks_ = true;
285     RequestFrame();
286 }
287 
FlushFreezeNode()288 void PipelineContext::FlushFreezeNode()
289 {
290     std::set<RefPtr<FrameNode>, NodeCompare<RefPtr<FrameNode>>> dirtyFreezeNodeSet;
291     auto dirtyFreezeNodes = std::move(dirtyFreezeNode_);
292     dirtyFreezeNode_.clear();
293     for (auto&& weakNode : dirtyFreezeNodes) {
294         auto node = weakNode.Upgrade();
295         if (node) {
296             dirtyFreezeNodeSet.emplace(node);
297         }
298     }
299     // Process parentNode before childNode
300     for (auto&& node : dirtyFreezeNodeSet) {
301         node->ProcessFreezeNode();
302     }
303 }
304 
FlushDirtyPropertyNodes()305 void PipelineContext::FlushDirtyPropertyNodes()
306 {
307     // node api property diff before ets update.
308     if (!CheckThreadSafe()) {
309         LOGW("FlushDirtyNodeUpdate doesn't run on UI thread!");
310     }
311     decltype(dirtyPropertyNodes_) dirtyPropertyNodes(std::move(dirtyPropertyNodes_));
312     dirtyPropertyNodes_.clear();
313     for (const auto& node : dirtyPropertyNodes) {
314         node->ProcessPropertyDiff();
315     }
316 }
317 
FlushDirtyNodeUpdate()318 void PipelineContext::FlushDirtyNodeUpdate()
319 {
320     CHECK_RUN_ON(UI);
321     ACE_FUNCTION_TRACE();
322     if (FrameReport::GetInstance().GetEnable()) {
323         FrameReport::GetInstance().BeginFlushBuild();
324     }
325 
326     // freeze node unlock before build begin.
327     FlushFreezeNode();
328 
329     FlushDirtyPropertyNodes();
330 
331     if (!ViewStackProcessor::GetInstance()->IsEmpty() && !dirtyNodes_.empty()) {
332         ACE_SCOPED_TRACE("Error update, node stack non-empty");
333         LOGW("stack is not empty when call FlushDirtyNodeUpdate, node may be mounted to incorrect pos!");
334     }
335     // SomeTimes, customNode->Update may add some dirty custom nodes to dirtyNodes_,
336     // use maxFlushTimes to avoid dead cycle.
337     int maxFlushTimes = 3;
338     while (!dirtyNodes_.empty() && maxFlushTimes > 0) {
339         ArkUIPerfMonitor::GetInstance().RecordStateMgmtNode(dirtyNodes_.size());
340         decltype(dirtyNodes_) dirtyNodes(std::move(dirtyNodes_));
341         for (const auto& node : dirtyNodes) {
342             if (AceType::InstanceOf<NG::CustomNodeBase>(node)) {
343                 auto customNode = AceType::DynamicCast<NG::CustomNodeBase>(node);
344                 ACE_SCOPED_TRACE("CustomNodeUpdate %s", customNode->GetJSViewName().c_str());
345                 customNode->Update();
346             }
347         }
348         --maxFlushTimes;
349     }
350 
351     if (FrameReport::GetInstance().GetEnable()) {
352         FrameReport::GetInstance().EndFlushBuild();
353     }
354 }
355 
AddScheduleTask(const RefPtr<ScheduleTask> & task)356 uint32_t PipelineContext::AddScheduleTask(const RefPtr<ScheduleTask>& task)
357 {
358     CHECK_RUN_ON(UI);
359     scheduleTasks_.try_emplace(++nextScheduleTaskId_, task);
360     RequestFrame();
361     return nextScheduleTaskId_;
362 }
363 
RemoveScheduleTask(uint32_t id)364 void PipelineContext::RemoveScheduleTask(uint32_t id)
365 {
366     CHECK_RUN_ON(UI);
367     scheduleTasks_.erase(id);
368 }
369 
FlushOnceVsyncTask()370 void PipelineContext::FlushOnceVsyncTask()
371 {
372     if (onceVsyncListener_ != nullptr) {
373         onceVsyncListener_();
374         onceVsyncListener_ = nullptr;
375     }
376 }
377 
FlushVsync(uint64_t nanoTimestamp,uint32_t frameCount)378 void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount)
379 {
380     CHECK_RUN_ON(UI);
381     if (IsDestroyed()) {
382         LOGW("Cannot flush vsync as the pipeline context is destroyed.");
383         return;
384     }
385     SetVsyncTime(nanoTimestamp);
386     ACE_SCOPED_TRACE_COMMERCIAL("UIVsyncTask[timestamp:%" PRIu64 "][vsyncID:%" PRIu64 "][instanceID:%d]", nanoTimestamp,
387         static_cast<uint64_t>(frameCount), instanceId_);
388     window_->Lock();
389     static const std::string abilityName = AceApplicationInfo::GetInstance().GetProcessName().empty()
390                                                ? AceApplicationInfo::GetInstance().GetPackageName()
391                                                : AceApplicationInfo::GetInstance().GetProcessName();
392     window_->RecordFrameTime(nanoTimestamp, abilityName);
393     resampleTimeStamp_ = nanoTimestamp - static_cast<uint64_t>(window_->GetVSyncPeriod()) + ONE_MS_IN_NS -\
394         compensationValue_;
395 #ifdef UICAST_COMPONENT_SUPPORTED
396     do {
397         auto container = Container::Current();
398         CHECK_NULL_BREAK(container);
399         auto distributedUI = container->GetDistributedUI();
400         CHECK_NULL_BREAK(distributedUI);
401         distributedUI->ApplyOneUpdate();
402     } while (false);
403 #endif
404     ProcessDelayTasks();
405     DispatchDisplaySync(nanoTimestamp);
406     FlushAnimation(nanoTimestamp);
407     FlushFrameCallback(nanoTimestamp);
408     auto hasRunningAnimation = FlushModifierAnimation(nanoTimestamp);
409     FlushTouchEvents();
410     FlushBuild();
411     if (isFormRender_ && drawDelegate_ && rootNode_) {
412         auto renderContext = AceType::DynamicCast<NG::RenderContext>(rootNode_->GetRenderContext());
413         drawDelegate_->DrawRSFrame(renderContext);
414         drawDelegate_ = nullptr;
415     }
416     if (!taskScheduler_->isEmpty()) {
417 #if !defined(PREVIEW)
418         LayoutInspector::SupportInspector();
419 #endif
420     }
421 
422     taskScheduler_->StartRecordFrameInfo(GetCurrentFrameInfo(recvTime_, nanoTimestamp));
423     taskScheduler_->FlushTask();
424     UIObserverHandler::GetInstance().HandleLayoutDoneCallBack();
425     // flush correct rect again
426     taskScheduler_->FlushPersistAfterLayoutTask();
427     taskScheduler_->FinishRecordFrameInfo();
428     FlushNodeChangeFlag();
429     FlushAnimationClosure();
430     TryCallNextFrameLayoutCallback();
431 
432 #ifdef UICAST_COMPONENT_SUPPORTED
433     do {
434         auto container = Container::Current();
435         CHECK_NULL_BREAK(container);
436         auto distributedUI = container->GetDistributedUI();
437         CHECK_NULL_BREAK(distributedUI);
438         distributedUI->OnTreeUpdate();
439     } while (false);
440 #endif
441 
442     if (hasRunningAnimation || window_->HasUIRunningAnimation()) {
443         RequestFrame();
444     }
445     window_->FlushModifier();
446     FlushFrameRate();
447     if (dragWindowVisibleCallback_) {
448         dragWindowVisibleCallback_();
449         dragWindowVisibleCallback_ = nullptr;
450     }
451     if (isFirstFlushMessages_) {
452         isFirstFlushMessages_ = false;
453         LOGI("ArkUi flush first frame messages.");
454     }
455     FlushMessages();
456     FlushWindowPatternInfo();
457     InspectDrew();
458     UIObserverHandler::GetInstance().HandleDrawCommandSendCallBack();
459     if (onShow_ && onFocus_ && isWindowHasFocused_) {
460         auto isDynamicRender = Container::Current() == nullptr ? false : Container::Current()->IsDynamicRender();
461         if ((!isFormRender_) || isDynamicRender) {
462             FlushFocusView();
463             FlushFocus();
464             FlushFocusScroll();
465         }
466     }
467     HandleOnAreaChangeEvent(nanoTimestamp);
468     HandleVisibleAreaChangeEvent(nanoTimestamp);
469     if (isNeedFlushMouseEvent_) {
470         FlushMouseEvent();
471         isNeedFlushMouseEvent_ = false;
472     }
473     eventManager_->FlushCursorStyleRequests();
474     if (isNeedFlushAnimationStartTime_) {
475         window_->FlushAnimationStartTime(animationTimeStamp_);
476         isNeedFlushAnimationStartTime_ = false;
477     }
478     needRenderNode_.clear();
479     taskScheduler_->FlushAfterRenderTask();
480     window_->FlushLayoutSize(width_, height_);
481     if (IsFocusWindowIdSetted()) {
482         FireAllUIExtensionEvents();
483     }
484     FireAccessibilityEvents();
485     // Keep the call sent at the end of the function
486     ResSchedReport::GetInstance().LoadPageEvent(ResDefine::LOAD_PAGE_COMPLETE_EVENT);
487     window_->Unlock();
488 }
489 
FlushWindowPatternInfo()490 void PipelineContext::FlushWindowPatternInfo()
491 {
492 #ifdef WINDOW_SCENE_SUPPORTED
493     auto container = Container::Current();
494     CHECK_NULL_VOID(container);
495     if (!container->IsScenceBoardWindow()) {
496         return;
497     }
498     auto screenNode = screenNode_.Upgrade();
499     if (!screenNode) {
500         return;
501     }
502     ACE_SCOPED_TRACE("FlushWindowPatternInfo");
503     auto instance = WindowSceneLayoutManager::GetInstance();
504     if (instance != nullptr) {
505         instance->FlushWindowPatternInfo(screenNode);
506     }
507 #endif
508 }
509 
InspectDrew()510 void PipelineContext::InspectDrew()
511 {
512     CHECK_RUN_ON(UI);
513     if (!needRenderNode_.empty()) {
514         auto needRenderNode = std::move(needRenderNode_);
515         for (auto&& nodeWeak : needRenderNode) {
516             auto node = nodeWeak.Upgrade();
517             if (!node) {
518                 continue;
519             }
520             if (node->GetInspectorId().has_value()) {
521                 OnDrawCompleted(node->GetInspectorId()->c_str());
522             }
523             auto eventHub = node->GetEventHub<NG::EventHub>();
524             CHECK_NULL_VOID(eventHub);
525             eventHub->FireDrawCompletedNDKCallback(Claim(this));
526         }
527     }
528 }
529 
ProcessDelayTasks()530 void PipelineContext::ProcessDelayTasks()
531 {
532     if (delayedTasks_.empty()) {
533         return;
534     }
535     auto currentTimeStamp = GetSysTimestamp();
536     auto delayedTasks = std::move(delayedTasks_);
537     auto result = std::remove_if(delayedTasks.begin(), delayedTasks.end(), [this, currentTimeStamp](const auto& task) {
538         if (task.timeStamp + static_cast<int64_t>(task.time) * MILLISECONDS_TO_NANOSECONDS > currentTimeStamp) {
539             delayedTasks_.emplace_back(task);
540             return true;
541         }
542         return false;
543     });
544     delayedTasks.erase(result, delayedTasks.end());
545     std::for_each(delayedTasks.begin(), delayedTasks.end(), [this](auto& delayedTask) {
546         if (delayedTask.task) {
547             delayedTask.task();
548         }
549     });
550 }
551 
DispatchDisplaySync(uint64_t nanoTimestamp)552 void PipelineContext::DispatchDisplaySync(uint64_t nanoTimestamp)
553 {
554     CHECK_RUN_ON(UI);
555     ACE_FUNCTION_TRACE();
556 
557     GetOrCreateUIDisplaySyncManager()->SetRefreshRateMode(window_->GetCurrentRefreshRateMode());
558     GetOrCreateUIDisplaySyncManager()->SetVsyncPeriod(window_->GetVSyncPeriod());
559 
560     if (FrameReport::GetInstance().GetEnable()) {
561         FrameReport::GetInstance().BeginFlushAnimation();
562     }
563 
564     scheduleTasks_.clear();
565     GetOrCreateUIDisplaySyncManager()->DispatchFunc(nanoTimestamp);
566 
567     if (FrameReport::GetInstance().GetEnable()) {
568         FrameReport::GetInstance().EndFlushAnimation();
569     }
570 
571     int32_t displaySyncRate = GetOrCreateUIDisplaySyncManager()->GetDisplaySyncRate();
572     frameRateManager_->SetDisplaySyncRate(displaySyncRate);
573     ArkUIPerfMonitor::GetInstance().RecordDisplaySyncRate(displaySyncRate);
574 }
575 
FlushAnimation(uint64_t nanoTimestamp)576 void PipelineContext::FlushAnimation(uint64_t nanoTimestamp)
577 {
578     CHECK_RUN_ON(UI);
579     ACE_FUNCTION_TRACE();
580     if (scheduleTasks_.empty()) {
581         return;
582     }
583 }
584 
FlushModifier()585 void PipelineContext::FlushModifier()
586 {
587     window_->FlushModifier();
588 }
589 
FlushMessages()590 void PipelineContext::FlushMessages()
591 {
592     ACE_FUNCTION_TRACE();
593     if (IsFreezeFlushMessage()) {
594         SetIsFreezeFlushMessage(false);
595         LOGI("Flush message is freezed.");
596         return;
597     }
598     window_->FlushTasks();
599 }
600 
FlushUITasks(bool triggeredByImplicitAnimation)601 void PipelineContext::FlushUITasks(bool triggeredByImplicitAnimation)
602 {
603     window_->Lock();
604     if (!CheckThreadSafe()) {
605         LOGW("FlushUITasks doesn't run on UI thread!");
606     }
607     decltype(dirtyPropertyNodes_) dirtyPropertyNodes(std::move(dirtyPropertyNodes_));
608     dirtyPropertyNodes_.clear();
609     for (const auto& dirtyNode : dirtyPropertyNodes) {
610         dirtyNode->ProcessPropertyDiff();
611     }
612     taskScheduler_->FlushTaskWithCheck(triggeredByImplicitAnimation);
613     window_->Unlock();
614 }
615 
FlushUITaskWithSingleDirtyNode(const RefPtr<FrameNode> & node)616 void PipelineContext::FlushUITaskWithSingleDirtyNode(const RefPtr<FrameNode>& node)
617 {
618     CHECK_NULL_VOID(node);
619     if (IsLayouting()) {
620         taskScheduler_->AddSingleNodeToFlush(node);
621         return;
622     }
623     auto layoutProperty = node->GetLayoutProperty();
624     CHECK_NULL_VOID(layoutProperty);
625     auto layoutConstraint = node->GetLayoutConstraint();
626     auto originLayoutingFlag = IsLayouting();
627     SetIsLayouting(true);
628     if (layoutProperty->GetLayoutRect()) {
629         node->SetActive(true, true);
630         node->Measure(std::nullopt);
631         node->Layout();
632     } else {
633         auto ancestorNodeOfFrame = node->GetAncestorNodeOfFrame(false);
634         {
635             ACE_SCOPED_TRACE("FlushUITaskWithSingleDirtyNodeMeasure[%s][self:%d][parent:%d][layoutConstraint:%s]"
636                              "[pageId:%d][depth:%d]",
637                 node->GetTag().c_str(), node->GetId(), ancestorNodeOfFrame ? ancestorNodeOfFrame->GetId() : 0,
638                 layoutConstraint.ToString().c_str(), node->GetPageId(), node->GetDepth());
639             node->Measure(layoutConstraint);
640         }
641         {
642             ACE_SCOPED_TRACE("FlushUITaskWithSingleDirtyNodeLayout[%s][self:%d][parent:%d][pageId:%d][depth:%d]",
643                 node->GetTag().c_str(), node->GetId(), ancestorNodeOfFrame ? ancestorNodeOfFrame->GetId() : 0,
644                 node->GetPageId(), node->GetDepth());
645             node->Layout();
646         }
647     }
648     SetIsLayouting(originLayoutingFlag);
649 }
650 
FlushAfterLayoutCallbackInImplicitAnimationTask()651 void PipelineContext::FlushAfterLayoutCallbackInImplicitAnimationTask()
652 {
653     if (AnimationUtils::IsImplicitAnimationOpen()) {
654         TAG_LOGI(AceLogTag::ACE_ANIMATION,
655             "Can not flush implicit animation task after layout because implicit animation is open.");
656         return;
657     }
658     window_->Lock();
659     taskScheduler_->FlushAfterLayoutCallbackInImplicitAnimationTask();
660     window_->Unlock();
661 }
662 
SetNeedRenderNode(const WeakPtr<FrameNode> & node)663 void PipelineContext::SetNeedRenderNode(const WeakPtr<FrameNode>& node)
664 {
665     CHECK_RUN_ON(UI);
666     needRenderNode_.insert(node);
667 }
668 
FlushFocus()669 void PipelineContext::FlushFocus()
670 {
671     CHECK_RUN_ON(UI);
672     ACE_FUNCTION_TRACK();
673     ACE_FUNCTION_TRACE();
674 
675     FlushRequestFocus();
676 
677     auto focusNode = dirtyFocusNode_.Upgrade();
678     if (!focusNode || focusNode->GetFocusType() != FocusType::NODE) {
679         dirtyFocusNode_.Reset();
680     } else {
681         FlushFocusWithNode(focusNode, false);
682         return;
683     }
684     auto focusScope = dirtyFocusScope_.Upgrade();
685     if (!focusScope || focusScope->GetFocusType() != FocusType::SCOPE) {
686         dirtyFocusScope_.Reset();
687     } else {
688         FlushFocusWithNode(focusScope, true);
689         return;
690     }
691     focusManager_->WindowFocusMoveEnd();
692 }
693 
FlushFocusWithNode(RefPtr<FrameNode> focusNode,bool isScope)694 void PipelineContext::FlushFocusWithNode(RefPtr<FrameNode> focusNode, bool isScope)
695 {
696     auto focusNodeHub = focusNode->GetFocusHub();
697     if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
698         auto unfocusableParentFocusNode = focusNodeHub->GetUnfocusableParentFocusNode().Upgrade();
699         if (unfocusableParentFocusNode) {
700             TAG_LOGI(AceLogTag::ACE_FOCUS,
701                 "Request focus on %{public}s: %{public}s/%{public}d return false, unfocusable node: "
702                 "%{public}s/%{public}d, focusable = %{public}d, shown = %{public}d, enabled = %{public}d",
703                 isScope ? "scope" : "node", focusNode->GetTag().c_str(), focusNode->GetId(),
704                 unfocusableParentFocusNode->GetFrameName().c_str(), unfocusableParentFocusNode->GetFrameId(),
705                 unfocusableParentFocusNode->GetFocusable(), unfocusableParentFocusNode->IsShow(),
706                 unfocusableParentFocusNode->IsEnabled());
707             unfocusableParentFocusNode = nullptr;
708         } else {
709             TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus on %{public}s: %{public}s/%{public}d return false",
710                 isScope ? "scope" : "node", focusNode->GetTag().c_str(), focusNode->GetId());
711         }
712     }
713     dirtyFocusNode_.Reset();
714     dirtyFocusScope_.Reset();
715     dirtyRequestFocusNode_.Reset();
716     focusManager_->WindowFocusMoveEnd();
717 }
718 
FlushRequestFocus()719 void PipelineContext::FlushRequestFocus()
720 {
721     CHECK_RUN_ON(UI);
722 
723     auto requestFocusNode = dirtyRequestFocusNode_.Upgrade();
724     if (!requestFocusNode) {
725         dirtyRequestFocusNode_.Reset();
726     } else {
727         auto focusNodeHub = requestFocusNode->GetFocusHub();
728         if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
729             auto unfocusableParentFocusNode = focusNodeHub->GetUnfocusableParentFocusNode().Upgrade();
730             if (unfocusableParentFocusNode) {
731                 TAG_LOGI(AceLogTag::ACE_FOCUS,
732                     "Request focus by id on node: %{public}s/%{public}d return false, unfocusable node: "
733                     "%{public}s/%{public}d, focusable = %{public}d, shown = %{public}d, enabled = %{public}d",
734                     requestFocusNode->GetTag().c_str(), requestFocusNode->GetId(),
735                     unfocusableParentFocusNode->GetFrameName().c_str(), unfocusableParentFocusNode->GetFrameId(),
736                     unfocusableParentFocusNode->GetFocusable(), unfocusableParentFocusNode->IsShow(),
737                     unfocusableParentFocusNode->IsEnabled());
738                 unfocusableParentFocusNode = nullptr;
739             } else {
740                 TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus by id on node: %{public}s/%{public}d return false",
741                     requestFocusNode->GetTag().c_str(), requestFocusNode->GetId());
742             }
743         }
744         dirtyFocusNode_.Reset();
745         dirtyFocusScope_.Reset();
746         dirtyRequestFocusNode_.Reset();
747         return;
748     }
749 }
750 
FlushFocusView()751 void PipelineContext::FlushFocusView()
752 {
753     CHECK_NULL_VOID(focusManager_);
754     auto lastFocusView = (focusManager_->GetLastFocusView()).Upgrade();
755     CHECK_NULL_VOID(lastFocusView);
756     auto lastFocusViewHub = lastFocusView->GetFocusHub();
757     CHECK_NULL_VOID(lastFocusViewHub);
758     auto container = Container::Current();
759     if (container && (container->IsUIExtensionWindow() || container->IsDynamicRender()) &&
760         (!lastFocusView->IsRootScopeCurrentFocus())) {
761         lastFocusView->SetIsViewRootScopeFocused(false);
762     }
763     if (lastFocusView && (!lastFocusView->IsRootScopeCurrentFocus() || !lastFocusView->GetIsViewHasFocused()) &&
764         lastFocusViewHub->IsFocusableNode()) {
765         lastFocusView->RequestDefaultFocus();
766         focusManager_->SetFocusViewStackState(FocusViewStackState::IDLE);
767     }
768 }
769 
FlushFocusScroll()770 void PipelineContext::FlushFocusScroll()
771 {
772     CHECK_NULL_VOID(focusManager_);
773     if (!focusManager_->GetNeedTriggerScroll()) {
774         return;
775     }
776     auto lastFocusStateNode = focusManager_->GetLastFocusStateNode();
777     CHECK_NULL_VOID(lastFocusStateNode);
778     if (!lastFocusStateNode->TriggerFocusScroll()) {
779         focusManager_->SetNeedTriggerScroll(false);
780     }
781 }
782 
FlushPipelineImmediately()783 void PipelineContext::FlushPipelineImmediately()
784 {
785     CHECK_RUN_ON(UI);
786     ACE_FUNCTION_TRACE();
787     FlushPipelineWithoutAnimation();
788 }
789 
RebuildFontNode()790 void PipelineContext::RebuildFontNode()
791 {
792     if (fontManager_) {
793         fontManager_->RebuildFontNodeNG();
794     }
795 }
796 
FlushPipelineWithoutAnimation()797 void PipelineContext::FlushPipelineWithoutAnimation()
798 {
799     ACE_FUNCTION_TRACE();
800     window_->Lock();
801     FlushBuild();
802     FlushTouchEvents();
803     taskScheduler_->FlushTask();
804     FlushAnimationClosure();
805     window_->FlushModifier();
806     FlushMessages();
807     FlushFocus();
808     window_->Unlock();
809 }
810 
FlushFrameRate()811 void PipelineContext::FlushFrameRate()
812 {
813     frameRateManager_->SetAnimateRate(window_->GetAnimateExpectedRate());
814     int32_t currAnimatorExpectedFrameRate = GetOrCreateUIDisplaySyncManager()->GetAnimatorRate();
815     if (frameRateManager_->IsRateChanged() || currAnimatorExpectedFrameRate != lastAnimatorExpectedFrameRate_) {
816         auto [rate, rateType] = frameRateManager_->GetExpectedRate();
817         ACE_SCOPED_TRACE("FlushFrameRate Expected frameRate = %d frameRateType = %d "
818             "currAnimatorExpectedFrameRate = %d, lastAnimatorExpectedFrameRate = %d",
819             rate, rateType, currAnimatorExpectedFrameRate, lastAnimatorExpectedFrameRate_);
820         TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "FlushFrameRate Expected frameRate = %{public}d "
821             "frameRateType = %{public}d currAnimatorExpectedFrameRate = %{public}d, lastRate = %{public}d",
822             rate, rateType, currAnimatorExpectedFrameRate, lastAnimatorExpectedFrameRate_);
823         window_->FlushFrameRate(rate, currAnimatorExpectedFrameRate, rateType);
824         frameRateManager_->SetIsRateChanged(false);
825         lastAnimatorExpectedFrameRate_ = currAnimatorExpectedFrameRate;
826     }
827 }
828 
FlushBuild()829 void PipelineContext::FlushBuild()
830 {
831     if (vsyncListener_ != nullptr) {
832         ACE_SCOPED_TRACE("arkoala build");
833         vsyncListener_();
834     }
835     FlushOnceVsyncTask();
836     isRebuildFinished_ = false;
837     FlushDirtyNodeUpdate();
838     isRebuildFinished_ = true;
839     FlushBuildFinishCallbacks();
840 }
841 
AddAnimationClosure(std::function<void ()> && animation)842 void PipelineContext::AddAnimationClosure(std::function<void()>&& animation)
843 {
844     animationClosuresList_.emplace_back(std::move(animation));
845 }
846 
FlushAnimationClosure()847 void PipelineContext::FlushAnimationClosure()
848 {
849     if (animationClosuresList_.empty()) {
850         return;
851     }
852     window_->Lock();
853     taskScheduler_->FlushTask();
854 
855     decltype(animationClosuresList_) temp(std::move(animationClosuresList_));
856     for (const auto& animation : temp) {
857         animation();
858     }
859     window_->Unlock();
860 }
861 
FlushBuildFinishCallbacks()862 void PipelineContext::FlushBuildFinishCallbacks()
863 {
864     decltype(buildFinishCallbacks_) buildFinishCallbacks(std::move(buildFinishCallbacks_));
865     for (const auto& func : buildFinishCallbacks) {
866         if (func) {
867             func();
868         }
869     }
870 }
871 
RegisterRootEvent()872 void PipelineContext::RegisterRootEvent()
873 {
874     if (!IsFormRender()) {
875         return;
876     }
877     auto accessibilityProperty = rootNode_->GetAccessibilityProperty<AccessibilityProperty>();
878     if (accessibilityProperty != nullptr) {
879         accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
880     }
881 
882     // To avoid conflicts between longPress and click events on the card,
883     // use an empty longPress event placeholder in the EtsCard scenario
884     auto hub = rootNode_->GetOrCreateGestureEventHub();
885     CHECK_NULL_VOID(hub);
886     auto event = [](const GestureEvent& info) mutable {};
887     auto longPress = AceType::MakeRefPtr<NG::LongPressEvent>(std::move(event));
888     hub->SetLongPressEvent(longPress, false, true);
889 }
890 
SetupRootElement()891 void PipelineContext::SetupRootElement()
892 {
893     CHECK_RUN_ON(UI);
894     rootNode_ = FrameNode::CreateFrameNodeWithTree(
895         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
896     rootNode_->SetHostRootId(GetInstanceId());
897     rootNode_->SetHostPageId(-1);
898     rootNode_->SetActive(true);
899     RegisterRootEvent();
900     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
901     MeasureProperty layoutConstraint;
902     layoutConstraint.selfIdealSize = idealSize;
903     layoutConstraint.maxSize = idealSize;
904     rootNode_->UpdateLayoutConstraint(layoutConstraint);
905     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
906     rootFocusHub->SetFocusType(FocusType::SCOPE);
907     rootFocusHub->SetFocusable(true);
908     window_->SetRootFrameNode(rootNode_);
909     rootNode_->AttachToMainTree(false, this);
910     auto stagePattern = ViewAdvancedRegister::GetInstance()->GeneratePattern(V2::STAGE_ETS_TAG);
911     if (!stagePattern) {
912         stagePattern = MakeRefPtr<StagePattern>();
913     }
914     auto stageNode = FrameNode::CreateFrameNode(
915         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), stagePattern);
916     RefPtr<AppBarView> appBar = AceType::MakeRefPtr<AppBarView>();
917     auto atomicService = installationFree_ ? appBar->Create(stageNode) : nullptr;
918     auto container = Container::Current();
919     if (container) {
920         container->SetAppBar(appBar);
921     }
922     if (windowModal_ == WindowModal::CONTAINER_MODAL) {
923         MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
924         rootNode_->AddChild(
925             ContainerModalViewFactory::GetView(atomicService ? atomicService : stageNode, maximizeMode));
926     } else {
927         rootNode_->AddChild(atomicService ? atomicService : stageNode);
928     }
929 #ifdef ENABLE_ROSEN_BACKEND
930     if (!IsJsCard() && !isFormRender_) {
931         auto window = GetWindow();
932         if (window) {
933             auto rsUIDirector = window->GetRSUIDirector();
934             if (rsUIDirector) {
935                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
936             }
937         }
938     }
939 #endif
940     accessibilityManagerNG_ = MakeRefPtr<AccessibilityManagerNG>();
941     stageManager_ = ViewAdvancedRegister::GetInstance()->GenerateStageManager(stageNode);
942     if (!stageManager_) {
943         stageManager_ = MakeRefPtr<StageManager>(stageNode);
944     }
945     overlayManager_ = MakeRefPtr<OverlayManager>(
946         DynamicCast<FrameNode>(installationFree_ ? stageNode->GetParent()->GetParent() : stageNode->GetParent()));
947     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
948     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
949     fontManager_->AddFontObserver(selectOverlayManager_);
950     if (!privacySensitiveManager_) {
951         privacySensitiveManager_ = MakeRefPtr<PrivacySensitiveManager>();
952     }
953     postEventManager_ = MakeRefPtr<PostEventManager>();
954     dragDropManager_ = MakeRefPtr<DragDropManager>();
955     focusManager_ = GetOrCreateFocusManager();
956     sharedTransitionManager_ = MakeRefPtr<SharedOverlayManager>(
957         DynamicCast<FrameNode>(installationFree_ ? stageNode->GetParent()->GetParent() : stageNode->GetParent()));
958 
959     OnAreaChangedFunc onAreaChangedFunc = [weakOverlayManger = AceType::WeakClaim(AceType::RawPtr(overlayManager_))](
960                                               const RectF& /* oldRect */, const OffsetF& /* oldOrigin */,
961                                               const RectF& /* rect */, const OffsetF& /* origin */) {
962         TAG_LOGD(AceLogTag::ACE_OVERLAY, "start OnAreaChangedFunc");
963         auto overlay = weakOverlayManger.Upgrade();
964         CHECK_NULL_VOID(overlay);
965         overlay->HideAllMenus();
966         SubwindowManager::GetInstance()->HideMenuNG(false);
967         overlay->HideCustomPopups();
968         SubwindowManager::GetInstance()->ClearToastInSubwindow();
969         SubwindowManager::GetInstance()->ClearToastInSystemSubwindow();
970         overlay->UpdateCustomKeyboardPosition();
971     };
972     rootNode_->SetOnAreaChangeCallback(std::move(onAreaChangedFunc));
973     AddOnAreaChangeNode(rootNode_->GetId());
974 }
975 
SetOnWindowFocused(const std::function<void ()> & callback)976 void PipelineContext::SetOnWindowFocused(const std::function<void()>& callback)
977 {
978     CHECK_NULL_VOID(taskExecutor_);
979     taskExecutor_->PostTask([weak = WeakClaim(this), callback]() {
980             auto pipeline = weak.Upgrade();
981             CHECK_NULL_VOID(pipeline);
982             pipeline->focusOnNodeCallback_ = callback;
983         }, TaskExecutor::TaskType::UI, "ArkUISetOnWindowFocusedCallback");
984 }
985 
SetupSubRootElement()986 void PipelineContext::SetupSubRootElement()
987 {
988     CHECK_RUN_ON(UI);
989     appBgColor_ = Color::TRANSPARENT;
990     rootNode_ = FrameNode::CreateFrameNodeWithTree(
991         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
992     rootNode_->SetHostRootId(GetInstanceId());
993     rootNode_->SetHostPageId(-1);
994     rootNode_->SetActive(true);
995     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
996     MeasureProperty layoutConstraint;
997     layoutConstraint.selfIdealSize = idealSize;
998     layoutConstraint.maxSize = idealSize;
999     rootNode_->UpdateLayoutConstraint(layoutConstraint);
1000     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
1001     rootFocusHub->SetFocusType(FocusType::SCOPE);
1002     rootFocusHub->SetFocusable(true);
1003     window_->SetRootFrameNode(rootNode_);
1004     rootNode_->AttachToMainTree(false, this);
1005 
1006 #ifdef ENABLE_ROSEN_BACKEND
1007     if (!IsJsCard()) {
1008         auto window = GetWindow();
1009         if (window) {
1010             auto rsUIDirector = window->GetRSUIDirector();
1011             if (rsUIDirector) {
1012                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
1013             }
1014         }
1015     }
1016 #endif
1017 #ifdef WINDOW_SCENE_SUPPORTED
1018     uiExtensionManager_ = MakeRefPtr<UIExtensionManager>();
1019 #endif
1020     accessibilityManagerNG_ = MakeRefPtr<AccessibilityManagerNG>();
1021     // the subwindow for overlay not need stage
1022     stageManager_ = ViewAdvancedRegister::GetInstance()->GenerateStageManager(nullptr);
1023     if (!stageManager_) {
1024         stageManager_ = MakeRefPtr<StageManager>(nullptr);
1025     }
1026     overlayManager_ = MakeRefPtr<OverlayManager>(rootNode_);
1027     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
1028     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
1029     fontManager_->AddFontObserver(selectOverlayManager_);
1030     dragDropManager_ = MakeRefPtr<DragDropManager>();
1031     focusManager_ = GetOrCreateFocusManager();
1032     postEventManager_ = MakeRefPtr<PostEventManager>();
1033 }
1034 
GetAccessibilityManagerNG()1035 RefPtr<AccessibilityManagerNG> PipelineContext::GetAccessibilityManagerNG()
1036 {
1037     return accessibilityManagerNG_;
1038 }
1039 
SendEventToAccessibilityWithNode(const AccessibilityEvent & accessibilityEvent,const RefPtr<FrameNode> & node)1040 void PipelineContext::SendEventToAccessibilityWithNode(
1041     const AccessibilityEvent& accessibilityEvent, const RefPtr<FrameNode>& node)
1042 {
1043     auto accessibilityManager = GetAccessibilityManager();
1044     if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
1045         return;
1046     }
1047     accessibilityManager->SendEventToAccessibilityWithNode(accessibilityEvent, node, Claim(this));
1048 }
1049 
GetStageManager()1050 const RefPtr<StageManager>& PipelineContext::GetStageManager()
1051 {
1052     return stageManager_;
1053 }
1054 
GetDragDropManager()1055 const RefPtr<DragDropManager>& PipelineContext::GetDragDropManager()
1056 {
1057     return dragDropManager_;
1058 }
1059 
GetFocusManager() const1060 const RefPtr<FocusManager>& PipelineContext::GetFocusManager() const
1061 {
1062     return focusManager_;
1063 }
1064 
GetOrCreateFocusManager()1065 const RefPtr<FocusManager>& PipelineContext::GetOrCreateFocusManager()
1066 {
1067     if (!focusManager_) {
1068         focusManager_ = MakeRefPtr<FocusManager>(AceType::Claim(this));
1069         RegisterFocusCallback();
1070     }
1071     return focusManager_;
1072 }
1073 
GetSelectOverlayManager()1074 const RefPtr<SelectOverlayManager>& PipelineContext::GetSelectOverlayManager()
1075 {
1076     return selectOverlayManager_;
1077 }
1078 
GetOverlayManager()1079 const RefPtr<OverlayManager>& PipelineContext::GetOverlayManager()
1080 {
1081     return overlayManager_;
1082 }
1083 
GetFullScreenManager()1084 const RefPtr<FullScreenManager>& PipelineContext::GetFullScreenManager()
1085 {
1086     return fullScreenManager_;
1087 }
1088 
OnSurfaceChanged(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1089 void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type,
1090     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1091 {
1092     CHECK_RUN_ON(UI);
1093     width_ = width;
1094     height_ = height;
1095     if (NearEqual(rootWidth_, width) && NearEqual(rootHeight_, height) &&
1096         type == WindowSizeChangeReason::CUSTOM_ANIMATION && !isDensityChanged_) {
1097         TryCallNextFrameLayoutCallback();
1098         return;
1099     }
1100     ExecuteSurfaceChangedCallbacks(width, height, type);
1101     auto callback = [weakFrontend = weakFrontend_, width, height]() {
1102         auto frontend = weakFrontend.Upgrade();
1103         if (frontend) {
1104             frontend->OnSurfaceChanged(width, height);
1105         }
1106     };
1107     auto container = Container::Current();
1108     if (!container) {
1109         return;
1110     }
1111     if (container->IsUseStageModel()) {
1112         callback();
1113         FlushBuild();
1114     } else {
1115         taskExecutor_->PostTask(callback, TaskExecutor::TaskType::JS, "ArkUISurfaceChanged");
1116     }
1117 
1118     FlushWindowSizeChangeCallback(width, height, type);
1119     UpdateHalfFoldHoverProperty(width, height);
1120     UpdateSizeChangeReason(type, rsTransaction);
1121 
1122 #ifdef ENABLE_ROSEN_BACKEND
1123     StartWindowSizeChangeAnimate(width, height, type, rsTransaction);
1124 #else
1125     SetRootRect(width, height, 0.0);
1126 #endif
1127 }
1128 
UpdateHalfFoldHoverProperty(int32_t windowWidth,int32_t windowHeight)1129 void PipelineContext::UpdateHalfFoldHoverProperty(int32_t windowWidth, int32_t windowHeight)
1130 {
1131     isHoverModeChanged_ = false;
1132     preIsHalfFoldHoverStatus_ = isHalfFoldHoverStatus_;
1133     UpdateHalfFoldHoverStatus(windowWidth, windowHeight);
1134     if (preIsHalfFoldHoverStatus_ != isHalfFoldHoverStatus_) {
1135         isHoverModeChanged_ = true;
1136     }
1137 }
1138 
OnLayoutCompleted(const std::string & componentId)1139 void PipelineContext::OnLayoutCompleted(const std::string& componentId)
1140 {
1141     CHECK_RUN_ON(UI);
1142     auto frontend = weakFrontend_.Upgrade();
1143     if (frontend) {
1144         frontend->OnLayoutCompleted(componentId);
1145     }
1146 }
1147 
OnDrawCompleted(const std::string & componentId)1148 void PipelineContext::OnDrawCompleted(const std::string& componentId)
1149 {
1150     CHECK_RUN_ON(UI);
1151     auto frontend = weakFrontend_.Upgrade();
1152     if (frontend) {
1153         frontend->OnDrawCompleted(componentId);
1154     }
1155 }
1156 
ExecuteSurfaceChangedCallbacks(int32_t newWidth,int32_t newHeight,WindowSizeChangeReason type)1157 void PipelineContext::ExecuteSurfaceChangedCallbacks(int32_t newWidth, int32_t newHeight, WindowSizeChangeReason type)
1158 {
1159     for (auto&& [id, callback] : surfaceChangedCallbackMap_) {
1160         if (callback) {
1161             callback(newWidth, newHeight, rootWidth_, rootHeight_, type);
1162         }
1163     }
1164 }
1165 
OnSurfacePositionChanged(int32_t posX,int32_t posY)1166 void PipelineContext::OnSurfacePositionChanged(int32_t posX, int32_t posY)
1167 {
1168     for (auto&& [id, callback] : surfacePositionChangedCallbackMap_) {
1169         if (callback) {
1170             callback(posX, posY);
1171         }
1172     }
1173 }
1174 
OnFoldStatusChange(FoldStatus foldStatus)1175 void PipelineContext::OnFoldStatusChange(FoldStatus foldStatus)
1176 {
1177     for (auto&& [id, callback] : foldStatusChangedCallbackMap_) {
1178         if (callback) {
1179             callback(foldStatus);
1180         }
1181     }
1182     StartFoldStatusDelayTask(foldStatus);
1183 }
1184 
OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)1185 void PipelineContext::OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)
1186 {
1187     for (auto&& [id, callback] : foldDisplayModeChangedCallbackMap_) {
1188         if (callback) {
1189             callback(foldDisplayMode);
1190         }
1191     }
1192 }
1193 
OnTransformHintChanged(uint32_t transform)1194 void PipelineContext::OnTransformHintChanged(uint32_t transform)
1195 {
1196     for (auto&& [id, callback] : transformHintChangedCallbackMap_) {
1197         if (callback) {
1198             callback(transform);
1199         }
1200     }
1201     transform_ = transform;
1202 }
1203 
StartWindowSizeChangeAnimate(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1204 void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type,
1205     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1206 {
1207     static const bool IsWindowSizeAnimationEnabled = SystemProperties::IsWindowSizeAnimationEnabled();
1208     if (!IsWindowSizeAnimationEnabled) {
1209         SetRootRect(width, height, 0.0);
1210         return;
1211     }
1212     switch (type) {
1213         case WindowSizeChangeReason::FULL_TO_SPLIT:
1214         case WindowSizeChangeReason::FULL_TO_FLOATING: {
1215             StartFullToMultWindowAnimation(width, height, type, rsTransaction);
1216             break;
1217         }
1218         case WindowSizeChangeReason::RECOVER:
1219         case WindowSizeChangeReason::MAXIMIZE: {
1220             StartWindowMaximizeAnimation(width, height, rsTransaction);
1221             break;
1222         }
1223         case WindowSizeChangeReason::ROTATION: {
1224             if (UsingCaretAvoidMode()) {
1225                 safeAreaManager_->UpdateKeyboardSafeArea(0.0f);
1226             }
1227             safeAreaManager_->UpdateKeyboardOffset(0.0);
1228             SetRootRect(width, height, 0.0);
1229             FlushUITasks();
1230             if (textFieldManager_) {
1231                 DynamicCast<TextFieldManagerNG>(textFieldManager_)->ScrollTextFieldToSafeArea();
1232             }
1233             FlushUITasks();
1234             if (!textFieldManager_) {
1235                 break;
1236             }
1237             PostKeyboardAvoidTask();
1238             break;
1239         }
1240         case WindowSizeChangeReason::DRAG_START:
1241         case WindowSizeChangeReason::DRAG:
1242         case WindowSizeChangeReason::DRAG_END:
1243         case WindowSizeChangeReason::RESIZE:
1244         case WindowSizeChangeReason::UNDEFINED:
1245         default: {
1246             SetRootRect(width, height, 0.0f);
1247         }
1248     }
1249 }
1250 
PostKeyboardAvoidTask()1251 void PipelineContext::PostKeyboardAvoidTask()
1252 {
1253     auto textFieldManager = DynamicCast<TextFieldManagerNG>(textFieldManager_);
1254     CHECK_NULL_VOID(textFieldManager);
1255     if (textFieldManager->UsingCustomKeyboardAvoid()) {
1256         taskExecutor_->PostTask(
1257             [weak = WeakPtr<TextFieldManagerNG>(textFieldManager)] {
1258                 auto manager = weak.Upgrade();
1259                 CHECK_NULL_VOID(manager);
1260                 manager->TriggerCustomKeyboardAvoid();
1261             },
1262             TaskExecutor::TaskType::UI, "ArkUICustomKeyboardAvoid");
1263         return;
1264     }
1265     CHECK_NULL_VOID(textFieldManager->GetLaterAvoid());
1266     auto container = Container::Current();
1267     if (container) {
1268         auto displayInfo = container->GetDisplayInfo();
1269         if (displayInfo && textFieldManager->GetLaterOrientation() != (int32_t)displayInfo->GetRotation()) {
1270             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "orientation not match, clear laterAvoid");
1271             textFieldManager->SetLaterAvoid(false);
1272             return;
1273         }
1274     }
1275     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "after rotation set root, trigger avoid now");
1276     taskExecutor_->PostTask(
1277         [weakContext = WeakClaim(this), keyboardRect = textFieldManager->GetLaterAvoidKeyboardRect(),
1278             positionY = textFieldManager->GetLaterAvoidPositionY(),
1279             height = textFieldManager->GetLaterAvoidHeight(),
1280             weakManager = WeakPtr<TextFieldManagerNG>(textFieldManager)] {
1281             auto context = weakContext.Upgrade();
1282             CHECK_NULL_VOID(context);
1283             context->OnVirtualKeyboardAreaChange(keyboardRect, positionY, height);
1284             auto manager = weakManager.Upgrade();
1285             CHECK_NULL_VOID(manager);
1286             manager->SetLaterAvoid(false);
1287         },
1288         TaskExecutor::TaskType::UI, "ArkUIVirtualKeyboardAreaChange");
1289 }
1290 
StartWindowMaximizeAnimation(int32_t width,int32_t height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1291 void PipelineContext::StartWindowMaximizeAnimation(
1292     int32_t width, int32_t height, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1293 {
1294     TAG_LOGI(AceLogTag::ACE_ANIMATION,
1295         "Root node start RECOVER/MAXIMIZE animation, width = %{public}d, height = %{public}d", width, height);
1296 #ifdef ENABLE_ROSEN_BACKEND
1297     if (rsTransaction) {
1298         FlushMessages();
1299         rsTransaction->Begin();
1300     }
1301 #endif
1302     AnimationOption option;
1303     int32_t duration = 400;
1304     MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
1305     bool freeMultiWindowModeEnabled = GetWindowManager()->GetFreeMultiWindowModeEnabledState();
1306     if (maximizeMode == MaximizeMode::MODE_FULL_FILL || maximizeMode == MaximizeMode::MODE_AVOID_SYSTEM_BAR ||
1307         freeMultiWindowModeEnabled) {
1308         int32_t preWidth = GetRootRect().Width();
1309         int32_t preHeight = GetRootRect().Height();
1310         if (width > preWidth && height > preHeight) {
1311             duration = 0;
1312         }
1313     }
1314     option.SetDuration(duration);
1315     auto curve = Curves::EASE_OUT;
1316     option.SetCurve(curve);
1317     auto weak = WeakClaim(this);
1318     Animate(option, curve, [width, height, weak]() {
1319         auto pipeline = weak.Upgrade();
1320         CHECK_NULL_VOID(pipeline);
1321         pipeline->SetRootRect(width, height, 0.0);
1322         pipeline->FlushUITasks();
1323     });
1324 #ifdef ENABLE_ROSEN_BACKEND
1325     if (rsTransaction) {
1326         rsTransaction->Commit();
1327     }
1328 #endif
1329 }
1330 
StartFullToMultWindowAnimation(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1331 void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t height,
1332     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1333 {
1334     TAG_LOGI(AceLogTag::ACE_ANIMATION,
1335         "Root node start multiple window animation, type = %{public}d, width = %{public}d, height = %{public}d", type,
1336         width, height);
1337 #ifdef ENABLE_ROSEN_BACKEND
1338     if (rsTransaction) {
1339         FlushMessages();
1340         rsTransaction->Begin();
1341     }
1342 #endif
1343     float response = 0.5f;
1344     float dampingFraction = 1.0f;
1345     AnimationOption option;
1346     if (type == WindowSizeChangeReason::FULL_TO_FLOATING) {
1347         response = 0.45f;
1348         dampingFraction = 0.75f;
1349     }
1350     auto springMotion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingFraction, 0);
1351     option.SetCurve(springMotion);
1352     auto weak = WeakClaim(this);
1353     Animate(option, springMotion, [width, height, weak]() {
1354         auto pipeline = weak.Upgrade();
1355         CHECK_NULL_VOID(pipeline);
1356         pipeline->SetRootRect(width, height, 0.0);
1357         pipeline->FlushUITasks();
1358     });
1359 #ifdef ENABLE_ROSEN_BACKEND
1360     if (rsTransaction) {
1361         rsTransaction->Commit();
1362     }
1363 #endif
1364 }
1365 
SetRootRect(double width,double height,double offset)1366 void PipelineContext::SetRootRect(double width, double height, double offset)
1367 {
1368     CHECK_RUN_ON(UI);
1369     UpdateRootSizeAndScale(width, height);
1370     CHECK_NULL_VOID(rootNode_);
1371     if (Container::CurrentId() < MIN_SUBCONTAINER_ID) {
1372         ScreenSystemManager::GetInstance().SetWindowInfo(rootWidth_, density_, dipScale_);
1373         ScreenSystemManager::GetInstance().OnSurfaceChanged(width);
1374     } else {
1375         ScreenSystemManager::GetInstance().SetWindowInfo(density_, dipScale_);
1376     }
1377     SizeF sizeF { static_cast<float>(width), static_cast<float>(height) };
1378     if (rootNode_->GetGeometryNode()->GetFrameSize() != sizeF || rootNode_->IsLayoutDirtyMarked()) {
1379         CalcSize idealSize { CalcLength(width), CalcLength(height) };
1380         MeasureProperty layoutConstraint;
1381         layoutConstraint.selfIdealSize = idealSize;
1382         layoutConstraint.maxSize = idealSize;
1383         rootNode_->UpdateLayoutConstraint(layoutConstraint);
1384         // reset parentLayoutConstraint to update itself when next measure task
1385         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1386         rootNode_->MarkDirtyNode();
1387     }
1388     if (rootNode_->GetGeometryNode()->GetFrameOffset().GetY() != offset) {
1389         OffsetF newOffset = rootNode_->GetGeometryNode()->GetFrameOffset();
1390         newOffset.SetY(static_cast<float>(offset));
1391         rootNode_->GetGeometryNode()->SetMarginFrameOffset(newOffset);
1392         auto rootContext = rootNode_->GetRenderContext();
1393         rootContext->SyncGeometryProperties(RawPtr(rootNode_->GetGeometryNode()));
1394         RequestFrame();
1395     }
1396     if (isDensityChanged_) {
1397         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1398         rootNode_->MarkForceMeasure();
1399         isDensityChanged_ = false;
1400     }
1401 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1402     // For cross-platform build, flush tasks when first resize, speed up for fisrt frame.
1403     if (window_ && rootNode_->GetRenderContext() && !NearZero(width) && !NearZero(height)) {
1404         rootNode_->GetRenderContext()->SetBounds(0.0, 0.0, width, height);
1405         window_->FlushTasks();
1406         FlushVsync(GetTimeFromExternalTimer(), 0);
1407     }
1408 #endif
1409 }
1410 
UpdateSystemSafeArea(const SafeAreaInsets & systemSafeArea)1411 void PipelineContext::UpdateSystemSafeArea(const SafeAreaInsets& systemSafeArea)
1412 {
1413     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1414     if (safeAreaManager_->UpdateSystemSafeArea(systemSafeArea)) {
1415         AnimateOnSafeAreaUpdate();
1416     }
1417 }
1418 
UpdateCutoutSafeArea(const SafeAreaInsets & cutoutSafeArea)1419 void PipelineContext::UpdateCutoutSafeArea(const SafeAreaInsets& cutoutSafeArea)
1420 {
1421     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1422     if (safeAreaManager_->UpdateCutoutSafeArea(cutoutSafeArea)) {
1423         AnimateOnSafeAreaUpdate();
1424     }
1425 }
1426 
UpdateNavSafeArea(const SafeAreaInsets & navSafeArea)1427 void PipelineContext::UpdateNavSafeArea(const SafeAreaInsets& navSafeArea)
1428 {
1429     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1430     if (safeAreaManager_->UpdateNavArea(navSafeArea)) {
1431         AnimateOnSafeAreaUpdate();
1432     }
1433 }
1434 
CheckAndUpdateKeyboardInset(float keyboardHeight)1435 void PipelineContext::CheckAndUpdateKeyboardInset(float keyboardHeight)
1436 {
1437     safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1438 }
1439 
UpdateOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1440 void PipelineContext::UpdateOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1441 {
1442 #ifdef WINDOW_SCENE_SUPPORTED
1443     CHECK_NULL_VOID(uiExtensionManager_);
1444     uiExtensionManager_->TransferOriginAvoidArea(avoidArea, type);
1445 #endif
1446 }
1447 
UpdateSizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1448 void PipelineContext::UpdateSizeChangeReason(
1449     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1450 {
1451 #ifdef WINDOW_SCENE_SUPPORTED
1452     CHECK_NULL_VOID(uiExtensionManager_);
1453     uiExtensionManager_->NotifySizeChangeReason(type, rsTransaction);
1454 #endif
1455 }
1456 
SetEnableKeyBoardAvoidMode(KeyBoardAvoidMode value)1457 void PipelineContext::SetEnableKeyBoardAvoidMode(KeyBoardAvoidMode value)
1458 {
1459     if (safeAreaManager_->SetKeyBoardAvoidMode(value)) {
1460         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1461         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "keyboardAvoid Mode update:%{public}d", value);
1462     }
1463 }
1464 
GetEnableKeyBoardAvoidMode()1465 KeyBoardAvoidMode PipelineContext::GetEnableKeyBoardAvoidMode()
1466 {
1467     return safeAreaManager_->GetKeyBoardAvoidMode();
1468 }
1469 
IsEnableKeyBoardAvoidMode()1470 bool PipelineContext::IsEnableKeyBoardAvoidMode()
1471 {
1472     return safeAreaManager_->KeyboardSafeAreaEnabled();
1473 }
1474 
SetIgnoreViewSafeArea(bool value)1475 void PipelineContext::SetIgnoreViewSafeArea(bool value)
1476 {
1477     if (safeAreaManager_->SetIgnoreSafeArea(value)) {
1478         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1479     }
1480 }
1481 
SetIsLayoutFullScreen(bool value)1482 void PipelineContext::SetIsLayoutFullScreen(bool value)
1483 {
1484     if (safeAreaManager_->SetIsFullScreen(value)) {
1485         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1486     }
1487 }
1488 
SetIsNeedAvoidWindow(bool value)1489 void PipelineContext::SetIsNeedAvoidWindow(bool value)
1490 {
1491     if (safeAreaManager_->SetIsNeedAvoidWindow(value)) {
1492         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1493     }
1494 }
1495 
GetSafeArea() const1496 PipelineBase::SafeAreaInsets PipelineContext::GetSafeArea() const
1497 {
1498     return safeAreaManager_->GetSafeArea();
1499 }
1500 
GetSafeAreaWithoutProcess() const1501 PipelineBase::SafeAreaInsets PipelineContext::GetSafeAreaWithoutProcess() const
1502 {
1503     return safeAreaManager_->GetSafeAreaWithoutProcess();
1504 }
1505 
GetPageAvoidOffset()1506 float PipelineContext::GetPageAvoidOffset()
1507 {
1508     return safeAreaManager_->GetKeyboardOffset();
1509 }
1510 
CheckNeedAvoidInSubWindow()1511 bool PipelineContext::CheckNeedAvoidInSubWindow()
1512 {
1513     CHECK_NULL_RETURN(NearZero(GetPageAvoidOffset()), true);
1514     CHECK_NULL_RETURN(safeAreaManager_->KeyboardSafeAreaEnabled(), false);
1515     auto KeyboardInsetLength = safeAreaManager_->GetKeyboardInset().Length();
1516     return GreatNotEqual(KeyboardInsetLength, 0.0f);
1517 }
1518 
SyncSafeArea(SafeAreaSyncType syncType)1519 void PipelineContext::SyncSafeArea(SafeAreaSyncType syncType)
1520 {
1521     bool keyboardSafeArea =
1522         syncType == SafeAreaSyncType::SYNC_TYPE_KEYBOARD && !safeAreaManager_->KeyboardSafeAreaEnabled();
1523     CHECK_NULL_VOID(stageManager_);
1524     stageManager_->SyncPageSafeArea(keyboardSafeArea);
1525     SubwindowManager::GetInstance()->MarkDirtyDialogSafeArea();
1526     if (overlayManager_) {
1527         overlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1528     }
1529     if (selectOverlayManager_) {
1530         selectOverlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1531     }
1532     auto&& restoreNodes = safeAreaManager_->GetGeoRestoreNodes();
1533     for (auto&& wk : restoreNodes) {
1534         auto node = wk.Upgrade();
1535         if (node) {
1536             bool needMeasure = (syncType == SafeAreaSyncType::SYNC_TYPE_KEYBOARD && node->SelfExpansiveToKeyboard()) ||
1537                                (syncType == SafeAreaSyncType::SYNC_TYPE_AVOID_AREA ||
1538                                    syncType == SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1539             node->MarkDirtyNode(needMeasure ? PROPERTY_UPDATE_MEASURE : PROPERTY_UPDATE_LAYOUT);
1540         }
1541     }
1542 }
1543 
DetachNode(RefPtr<UINode> uiNode)1544 void PipelineContext::DetachNode(RefPtr<UINode> uiNode)
1545 {
1546     auto frameNode = DynamicCast<FrameNode>(uiNode);
1547     attachedNodeSet_.erase(RawPtr(uiNode));
1548     CHECK_NULL_VOID(frameNode);
1549 
1550     RemoveStoredNode(frameNode->GetRestoreId());
1551     if (frameNode->IsPrivacySensitive()) {
1552         auto privacyManager = GetPrivacySensitiveManager();
1553         privacyManager->RemoveNode(AceType::WeakClaim(AceType::RawPtr(frameNode)));
1554     }
1555 
1556     if (!CheckThreadSafe()) {
1557         LOGW("DetachNode doesn't run on UI thread!");
1558     }
1559     dirtyPropertyNodes_.erase(frameNode);
1560     needRenderNode_.erase(WeakPtr<FrameNode>(frameNode));
1561 
1562     if (dirtyFocusNode_ == frameNode) {
1563         dirtyFocusNode_.Reset();
1564     }
1565 
1566     if (dirtyFocusScope_ == frameNode) {
1567         dirtyFocusScope_.Reset();
1568     }
1569 
1570     if (dirtyRequestFocusNode_ == frameNode) {
1571         dirtyRequestFocusNode_.Reset();
1572     }
1573 
1574     if (activeNode_ == frameNode) {
1575         activeNode_.Reset();
1576     }
1577 
1578     if (focusNode_ == frameNode) {
1579         focusNode_.Reset();
1580     }
1581 }
1582 
OnVirtualKeyboardHeightChange(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,const float safeHeight,const bool supportAvoidance,bool forceChange)1583 void PipelineContext::OnVirtualKeyboardHeightChange(float keyboardHeight,
1584     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, const float safeHeight, const bool supportAvoidance,
1585     bool forceChange)
1586 {
1587     CHECK_RUN_ON(UI);
1588     // prevent repeated trigger with same keyboardHeight
1589     if (!forceChange && NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length())) {
1590         return;
1591     }
1592 
1593     ACE_FUNCTION_TRACE();
1594 #ifdef ENABLE_ROSEN_BACKEND
1595     if (rsTransaction) {
1596         FlushMessages();
1597         rsTransaction->Begin();
1598     }
1599 #endif
1600 
1601     if (supportAvoidance) {
1602         AvoidanceLogic(keyboardHeight, rsTransaction, safeHeight, supportAvoidance);
1603     } else {
1604         OriginalAvoidanceLogic(keyboardHeight, rsTransaction);
1605     }
1606 
1607 #ifdef ENABLE_ROSEN_BACKEND
1608     if (rsTransaction) {
1609         rsTransaction->Commit();
1610     }
1611 #endif
1612 }
1613 
AvoidanceLogic(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,const float safeHeight,const bool supportAvoidance)1614 void PipelineContext::AvoidanceLogic(float keyboardHeight, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction,
1615     const float safeHeight, const bool supportAvoidance)
1616 {
1617     auto func = [this, keyboardHeight, safeHeight, supportAvoidance]() mutable {
1618         safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1619         keyboardHeight += safeAreaManager_->GetSafeHeight();
1620         float positionY = 0.0f;
1621         float textfieldHeight = 0.0f;
1622         float keyboardPosition = rootHeight_ - keyboardHeight;
1623         auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1624         float keyboardOffset = manager ? manager->GetClickPositionOffset() : safeAreaManager_->GetKeyboardOffset();
1625         if (manager) {
1626             positionY = static_cast<float>(manager->GetClickPosition().GetY()) - keyboardOffset;
1627             textfieldHeight = manager->GetHeight();
1628         }
1629         if (!NearZero(keyboardOffset)) {
1630             auto offsetY = keyboardPosition - safeAreaManager_->GetLastKeyboardPoistion();
1631             safeAreaManager_->UpdateKeyboardOffset(keyboardOffset + offsetY);
1632         } else {
1633             if (NearZero(keyboardHeight)) {
1634                 safeAreaManager_->UpdateKeyboardOffset(0.0f);
1635             } else if (LessOrEqual(positionY + safeHeight + textfieldHeight, rootHeight_ - keyboardHeight)) {
1636                 safeAreaManager_->UpdateKeyboardOffset(0.0f);
1637             } else if (positionY + safeHeight + textfieldHeight > rootHeight_ - keyboardHeight) {
1638                 safeAreaManager_->UpdateKeyboardOffset(
1639                     -(positionY - rootHeight_ + keyboardHeight)- safeHeight - textfieldHeight);
1640             } else {
1641                 safeAreaManager_->UpdateKeyboardOffset(0.0f);
1642             }
1643         }
1644         safeAreaManager_->SetLastKeyboardPoistion(keyboardPosition);
1645         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1646         CHECK_NULL_VOID(manager);
1647         manager->AvoidKeyBoardInNavigation();
1648         // layout before scrolling textfield to safeArea, because of getting correct position
1649         FlushUITasks();
1650         bool scrollResult = manager->ScrollTextFieldToSafeArea();
1651         if (scrollResult) {
1652             FlushUITasks();
1653         }
1654         MarkDirtyOverlay();
1655         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
1656 
1657         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
1658             "AvoidanceLogic keyboardHeight: %{public}f, positionY: %{public}f, safeHeight: %{public}f, "
1659             "rootHeight_ %{public}f final calculate keyboard offset is %{public}f",
1660             keyboardHeight, positionY, safeHeight, rootHeight_, safeAreaManager_->GetKeyboardOffset());
1661     };
1662     FlushUITasks();
1663     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
1664 }
1665 
OriginalAvoidanceLogic(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1666 void PipelineContext::OriginalAvoidanceLogic(
1667     float keyboardHeight, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1668 {
1669     auto func = [this, keyboardHeight]() mutable {
1670         safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1671         if (keyboardHeight > 0) {
1672             // add height of navigation bar
1673             keyboardHeight += safeAreaManager_->GetSystemSafeArea().bottom_.Length();
1674         }
1675         float positionY = 0.0f;
1676         auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1677         float height = 0.0f;
1678         if (manager) {
1679             height = manager->GetHeight();
1680             positionY = static_cast<float>(manager->GetClickPosition().GetY());
1681         }
1682         SizeF rootSize { static_cast<float>(rootWidth_), static_cast<float>(rootHeight_) };
1683         float keyboardOffset = manager ? manager->GetClickPositionOffset() : safeAreaManager_->GetKeyboardOffset();
1684         float positionYWithOffset = positionY - keyboardOffset;
1685         float offsetFix = (rootSize.Height() - positionYWithOffset) > 100.0f
1686                               ? keyboardHeight - (rootSize.Height() - positionYWithOffset) / 2.0f
1687                               : keyboardHeight;
1688 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1689         if (offsetFix > 0.0f && positionYWithOffset < offsetFix) {
1690             offsetFix = keyboardHeight - (rootSize.Height() - positionYWithOffset - height);
1691         }
1692 #endif
1693         if (NearZero(keyboardHeight)) {
1694             safeAreaManager_->UpdateKeyboardOffset(0.0f);
1695         } else if (LessOrEqual(rootSize.Height() - positionYWithOffset - height, height) &&
1696                    LessOrEqual(rootSize.Height() - positionYWithOffset, keyboardHeight)) {
1697             safeAreaManager_->UpdateKeyboardOffset(-keyboardHeight);
1698         } else if (positionYWithOffset + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
1699             safeAreaManager_->UpdateKeyboardOffset(-offsetFix);
1700         } else if ((positionYWithOffset + height > rootSize.Height() - keyboardHeight &&
1701                        positionYWithOffset < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
1702                    NearZero(rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
1703             safeAreaManager_->UpdateKeyboardOffset(-height - offsetFix / 2.0f);
1704         } else {
1705             safeAreaManager_->UpdateKeyboardOffset(0.0f);
1706         }
1707         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1708         CHECK_NULL_VOID(manager);
1709         manager->AvoidKeyBoardInNavigation();
1710         // layout before scrolling textfield to safeArea, because of getting correct position
1711         FlushUITasks();
1712         bool scrollResult = manager->ScrollTextFieldToSafeArea();
1713         if (scrollResult) {
1714             FlushUITasks();
1715         }
1716         MarkDirtyOverlay();
1717         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
1718     };
1719     FlushUITasks();
1720     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
1721 }
1722 
OnVirtualKeyboardHeightChange(float keyboardHeight,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool forceChange)1723 void PipelineContext::OnVirtualKeyboardHeightChange(float keyboardHeight, double positionY, double height,
1724     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool forceChange)
1725 {
1726     CHECK_RUN_ON(UI);
1727     // prevent repeated trigger with same keyboardHeight
1728     CHECK_NULL_VOID(safeAreaManager_);
1729     if (UsingCaretAvoidMode()) {
1730         OnCaretPositionChangeOrKeyboardHeightChange(keyboardHeight,
1731             positionY, height, rsTransaction, forceChange);
1732         return;
1733     }
1734     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1735     CHECK_NULL_VOID(manager);
1736     if (!forceChange && NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length()) &&
1737         prevKeyboardAvoidMode_ == safeAreaManager_->GetKeyBoardAvoidMode() && manager->PrevHasTextFieldPattern()) {
1738         safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1739         TAG_LOGD(
1740             AceLogTag::ACE_KEYBOARD, "KeyboardHeight as same as last time, don't need to calculate keyboardOffset");
1741         return;
1742     }
1743 
1744     if (!forceChange && (NearEqual(keyboardHeight + 1, safeAreaManager_->GetKeyboardInset().Length()) ||
1745         NearEqual(keyboardHeight - 1, safeAreaManager_->GetKeyboardInset().Length())) &&
1746         prevKeyboardAvoidMode_ == safeAreaManager_->GetKeyBoardAvoidMode() && manager->PrevHasTextFieldPattern()) {
1747         TAG_LOGI(
1748             AceLogTag::ACE_KEYBOARD, "Ignore ileagal keyboard height change");
1749         return;
1750     }
1751 
1752     if (keyboardHeight > rootHeight_) {
1753         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Keyboard higher than whole rootrect, no need to avoid");
1754         return;
1755     }
1756 
1757     if (manager->UsingCustomKeyboardAvoid()) {
1758         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Using Custom Avoid Instead");
1759         return;
1760     }
1761 
1762     manager->UpdatePrevHasTextFieldPattern();
1763     prevKeyboardAvoidMode_ = safeAreaManager_->GetKeyBoardAvoidMode();
1764 
1765     ACE_FUNCTION_TRACE();
1766 #ifdef ENABLE_ROSEN_BACKEND
1767     if (rsTransaction) {
1768         FlushMessages();
1769         rsTransaction->Begin();
1770     }
1771 #endif
1772 
1773     auto weak = WeakClaim(this);
1774     auto func = [weak, keyboardHeight, positionY, height, manager]() mutable {
1775         auto context = weak.Upgrade();
1776         CHECK_NULL_VOID(context);
1777         context->SetIsLayouting(false);
1778         context->safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1779         context->SetKeyboardAction(NearZero(keyboardHeight) ? KeyboardAction::CLOSING : KeyboardAction::OPENING);
1780         if (keyboardHeight > 0) {
1781             // add height of navigation bar
1782             keyboardHeight += context->safeAreaManager_->GetSystemSafeArea().bottom_.Length();
1783         }
1784 
1785         SizeF rootSize { static_cast<float>(context->rootWidth_), static_cast<float>(context->rootHeight_) };
1786 
1787         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
1788             "origin positionY: %{public}f, height %{public}f", positionY, height);
1789 
1790         float positionYWithOffset = positionY;
1791         float keyboardOffset = manager ? manager->GetClickPositionOffset() :
1792             context->safeAreaManager_->GetKeyboardOffset();
1793         float currentPos = manager->GetClickPosition().GetY() - context->GetRootRect().GetOffset().GetY() -
1794             keyboardOffset;
1795 
1796         auto onFocusField = manager->GetOnFocusTextField().Upgrade();
1797         float adjust = 0.0f;
1798         if (onFocusField && onFocusField->GetHost() && onFocusField->GetHost()->GetGeometryNode()) {
1799             auto adjustRect = onFocusField->GetHost()->GetGeometryNode()->GetParentAdjust();
1800             adjust = adjustRect.Top();
1801         }
1802         currentPos += adjust;
1803 
1804         if (!onFocusField) {
1805             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "use origin arg from the window");
1806         } else if (manager->GetIfFocusTextFieldIsInline()) {
1807             manager->GetInlineTextFieldAvoidPositionYAndHeight(positionY, height);
1808             positionYWithOffset = positionY;
1809         } else if (!NearEqual(positionY, currentPos) && !context->IsEnableKeyBoardAvoidMode()) {
1810             positionY = currentPos;
1811             positionYWithOffset = currentPos;
1812             height = manager->GetHeight();
1813         }
1814 
1815         if (rootSize.Height() - positionY - height < 0) {
1816             height = rootSize.Height() - positionY;
1817         }
1818         float offsetFix = (rootSize.Height() - positionY - height) < keyboardHeight
1819                               ? keyboardHeight - (rootSize.Height() - positionY - height)
1820                               : keyboardHeight;
1821         auto lastKeyboardOffset = context->safeAreaManager_->GetKeyboardOffset();
1822         float newKeyboardOffset = 0.0f;
1823         if (NearZero(keyboardHeight)) {
1824             newKeyboardOffset = 0.0f;
1825         } else if (positionYWithOffset + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
1826             newKeyboardOffset = -offsetFix;
1827         } else if (LessOrEqual(rootSize.Height() - positionYWithOffset - height, height) &&
1828                    LessOrEqual(rootSize.Height() - positionYWithOffset, keyboardHeight)) {
1829             newKeyboardOffset = -keyboardHeight;
1830         } else if ((positionYWithOffset + height > rootSize.Height() - keyboardHeight &&
1831                        positionYWithOffset < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
1832                    NearZero(context->rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
1833             newKeyboardOffset = -height - offsetFix / 2.0f;
1834         } else {
1835             newKeyboardOffset = 0.0f;
1836         }
1837 
1838         if (NearZero(keyboardHeight) || LessOrEqual(newKeyboardOffset, lastKeyboardOffset) ||
1839             manager->GetOnFocusTextFieldId() == manager->GetLastAvoidFieldId()) {
1840             context->safeAreaManager_->UpdateKeyboardOffset(newKeyboardOffset);
1841         } else {
1842             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Different field, Calculated offfset %{public}f is smaller than current"
1843                 "keyboardOffset, so keep current keyboardOffset", newKeyboardOffset);
1844         }
1845         manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
1846 
1847         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
1848             "keyboardHeight: %{public}f, positionY: %{public}f, textHeight: %{public}f, "
1849             "rootSize.Height() %{public}f final calculate keyboard offset is %{public}f",
1850             keyboardHeight, positionY, height, rootSize.Height(), context->safeAreaManager_->GetKeyboardOffset());
1851         context->SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1852         manager->AvoidKeyBoardInNavigation();
1853         // layout before scrolling textfield to safeArea, because of getting correct position
1854         context->FlushUITasks();
1855         bool scrollResult = manager->ScrollTextFieldToSafeArea();
1856         if (scrollResult) {
1857             context->FlushUITasks();
1858         }
1859         context->SetKeyboardAction(KeyboardAction::NONE);
1860         context->MarkDirtyOverlay();
1861         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
1862     };
1863     FlushUITasks();
1864     // flush ui tasks when dirty layout nodes exist: the previous ui tasks may generate dirty nodes.
1865     // if dirty nodes exist, they will be carried into the keyboard avoid animation, causing abnormal animation.
1866     FlushDirtyPropertyNodesWhenExist();
1867     SetIsLayouting(true);
1868     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
1869 
1870 #ifdef ENABLE_ROSEN_BACKEND
1871     if (rsTransaction) {
1872         rsTransaction->Commit();
1873     }
1874 #endif
1875 }
1876 
MarkDirtyOverlay()1877 void PipelineContext::MarkDirtyOverlay()
1878 {
1879     CHECK_NULL_VOID(rootNode_);
1880     auto childNodes = rootNode_->GetChildren();
1881     for (auto child: childNodes) {
1882         if (child && child->GetTag() == V2::POPUP_ETS_TAG) {
1883             child->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1884         }
1885     }
1886 }
1887 
FlushDirtyPropertyNodesWhenExist()1888 void PipelineContext::FlushDirtyPropertyNodesWhenExist()
1889 {
1890     if ((!IsDirtyLayoutNodesEmpty() || !dirtyPropertyNodes_.empty()) && !IsLayouting()) {
1891         FlushUITasks();
1892     }
1893 }
1894 
UsingCaretAvoidMode()1895 bool PipelineContext::UsingCaretAvoidMode()
1896 {
1897     CHECK_NULL_RETURN(safeAreaManager_, false);
1898     return safeAreaManager_->GetKeyBoardAvoidMode() == KeyBoardAvoidMode::OFFSET_WITH_CARET ||
1899         safeAreaManager_->GetKeyBoardAvoidMode() == KeyBoardAvoidMode::RESIZE_WITH_CARET;
1900 }
1901 
OnCaretPositionChangeOrKeyboardHeightChange(float keyboardHeight,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool forceChange)1902 void PipelineContext::OnCaretPositionChangeOrKeyboardHeightChange(
1903     float keyboardHeight, double positionY, double height,
1904     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool forceChange)
1905 {
1906     CHECK_RUN_ON(UI);
1907     CHECK_NULL_VOID(safeAreaManager_);
1908     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1909     CHECK_NULL_VOID(manager);
1910     if (manager->UsingCustomKeyboardAvoid()) {
1911         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Using Custom Avoid Instead");
1912         return;
1913     }
1914     manager->UpdatePrevHasTextFieldPattern();
1915     prevKeyboardAvoidMode_ = safeAreaManager_->GetKeyBoardAvoidMode();
1916     ACE_FUNCTION_TRACE();
1917 #ifdef ENABLE_ROSEN_BACKEND
1918     if (rsTransaction) {
1919         FlushMessages();
1920         rsTransaction->Begin();
1921     }
1922 #endif
1923 
1924     bool keyboardHeightChanged = NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length());
1925     auto weak = WeakClaim(this);
1926     auto func = [weak, keyboardHeight, positionY, height, manager, keyboardHeightChanged]() mutable {
1927         auto context = weak.Upgrade();
1928         CHECK_NULL_VOID(context);
1929         context->SetIsLayouting(false);
1930         context->safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1931         if (keyboardHeight > 0) {
1932             // add height of navigation bar
1933             keyboardHeight += context->safeAreaManager_->GetSystemSafeArea().bottom_.Length();
1934         }
1935         SizeF rootSize { static_cast<float>(context->rootWidth_), static_cast<float>(context->rootHeight_) };
1936         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "origin positionY: %{public}f, height %{public}f", positionY, height);
1937         float caretPos = manager->GetFocusedNodeCaretRect().Top() - context->GetRootRect().GetOffset().GetY() -
1938             context->GetSafeAreaManager()->GetKeyboardOffsetDirectly();
1939         auto onFocusField = manager->GetOnFocusTextField().Upgrade();
1940         float adjust = 0.0f;
1941         if (onFocusField && onFocusField->GetHost() && onFocusField->GetHost()->GetGeometryNode()) {
1942             adjust = onFocusField->GetHost()->GetGeometryNode()->GetParentAdjust().Top();
1943             positionY = caretPos;
1944             height = manager->GetHeight();
1945         }
1946         positionY += adjust;
1947         if (rootSize.Height() - positionY - height < 0 && manager->IsScrollableChild()) {
1948             height = rootSize.Height() - positionY;
1949         }
1950         auto lastKeyboardOffset = context->safeAreaManager_->GetKeyboardOffsetDirectly();
1951         auto newKeyboardOffset = context->CalcNewKeyboardOffset(keyboardHeight, positionY, height, rootSize);
1952         if (NearZero(keyboardHeight) || LessOrEqual(newKeyboardOffset, lastKeyboardOffset) ||
1953             (manager->GetOnFocusTextFieldId() == manager->GetLastAvoidFieldId() && !keyboardHeightChanged)) {
1954             context->safeAreaManager_->UpdateKeyboardOffset(newKeyboardOffset);
1955         } else {
1956             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "calc offset %{public}f is smaller, keep current", newKeyboardOffset);
1957             manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
1958             return;
1959         }
1960         manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
1961         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
1962             "keyboardHeight: %{public}f, caretPos: %{public}f, caretHeight: %{public}f, "
1963             "rootSize.Height() %{public}f adjust: %{public}f lastOffset: %{public}f, "
1964             "final calculate keyboard offset is %{public}f",
1965             keyboardHeight, positionY, height, rootSize.Height(), adjust, lastKeyboardOffset,
1966             context->safeAreaManager_->GetKeyboardOffset());
1967         context->SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1968         manager->AvoidKeyBoardInNavigation();
1969         // layout before scrolling textfield to safeArea, because of getting correct position
1970         context->FlushUITasks();
1971         bool scrollResult = manager->ScrollTextFieldToSafeArea();
1972         if (scrollResult) {
1973             context->FlushUITasks();
1974         }
1975         context->MarkDirtyOverlay();
1976         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
1977     };
1978     FlushUITasks();
1979     SetIsLayouting(true);
1980     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
1981 
1982 #ifdef ENABLE_ROSEN_BACKEND
1983     if (rsTransaction) {
1984         rsTransaction->Commit();
1985     }
1986 #endif
1987 }
1988 
CalcNewKeyboardOffset(float keyboardHeight,float positionY,float height,SizeF & rootSize)1989 float  PipelineContext::CalcNewKeyboardOffset(float keyboardHeight, float positionY,
1990     float height, SizeF& rootSize)
1991 {
1992     auto newKeyboardOffset = CalcAvoidOffset(keyboardHeight, positionY, height, rootSize);
1993     CHECK_NULL_RETURN(safeAreaManager_, newKeyboardOffset);
1994     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1995     CHECK_NULL_RETURN(manager, newKeyboardOffset);
1996     auto onFocusField = manager->GetOnFocusTextField().Upgrade();
1997     CHECK_NULL_RETURN(onFocusField, newKeyboardOffset);
1998     auto host = onFocusField->GetHost();
1999     CHECK_NULL_RETURN(host, newKeyboardOffset);
2000     auto geometryNode = host->GetGeometryNode();
2001     CHECK_NULL_RETURN(geometryNode, newKeyboardOffset);
2002     auto paintOffset = host->GetPaintRectOffset(false, true);
2003     auto frameSize = geometryNode->GetFrameSize();
2004     auto offset = CalcAvoidOffset(keyboardHeight, paintOffset.GetY() - safeAreaManager_->GetKeyboardOffsetDirectly(),
2005         frameSize.Height(), rootSize);
2006     return std::max(offset, newKeyboardOffset);
2007 }
2008 
CalcAvoidOffset(float keyboardHeight,float positionY,float height,SizeF rootSize)2009 float PipelineContext::CalcAvoidOffset(float keyboardHeight, float positionY,
2010     float height, SizeF rootSize)
2011 {
2012     float offsetFix = (rootSize.Height() - positionY - height) < keyboardHeight
2013         ? keyboardHeight - (rootSize.Height() - positionY - height)
2014         : keyboardHeight;
2015     if (NearZero(keyboardHeight)) {
2016         return 0.0f;
2017     }
2018     if (positionY + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
2019         return -offsetFix;
2020     }
2021     if (LessOrEqual(rootSize.Height() - positionY - height, height) &&
2022         LessOrEqual(rootSize.Height() - positionY, keyboardHeight)) {
2023         return -keyboardHeight;
2024     }
2025     if ((positionY + height > rootSize.Height() - keyboardHeight &&
2026         positionY < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
2027         NearZero(rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
2028         return -height - offsetFix / 2.0f;
2029     }
2030     return 0.0f;
2031 }
2032 
OnBackPressed()2033 bool PipelineContext::OnBackPressed()
2034 {
2035     CHECK_RUN_ON(PLATFORM);
2036     auto frontend = weakFrontend_.Upgrade();
2037     if (!frontend) {
2038         // return back.
2039         return false;
2040     }
2041 
2042     // If the tag of the last child of the rootnode is video, exit full screen.
2043     if (fullScreenManager_->OnBackPressed()) {
2044         LOGI("fullscreen component: video or web consumed backpressed event");
2045         return true;
2046     }
2047 
2048     // if has sharedTransition, back press will stop the sharedTransition
2049     if (sharedTransitionManager_ && sharedTransitionManager_->OnBackPressed()) {
2050         LOGI("sharedTransition consumed backpressed event");
2051         return true;
2052     }
2053 
2054     // if has popup, back press would hide popup and not trigger page back
2055     auto textfieldMgr = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2056     if (textfieldMgr) {
2057         auto lastRequestKeyboardNodeId = textfieldMgr->GetLastRequestKeyboardId();
2058         auto lastRequestKeyboardNode = DynamicCast<FrameNode>(
2059             ElementRegister::GetInstance()->GetUINodeById(lastRequestKeyboardNodeId));
2060         if (lastRequestKeyboardNode && lastRequestKeyboardNode->GetPageId() == -1 &&
2061             textfieldMgr->OnBackPressed()) {
2062             LOGI("textfield consumed backpressed event");
2063             return true;
2064         }
2065     }
2066 
2067     auto hasOverlay = false;
2068     taskExecutor_->PostSyncTask(
2069         [weakOverlay = AceType::WeakClaim(AceType::RawPtr(overlayManager_)),
2070             weakSelectOverlay = AceType::WeakClaim(AceType::RawPtr(selectOverlayManager_)), &hasOverlay]() {
2071             // Destroy behaviour of Select Overlay shouble be adjusted.
2072             auto overlay = weakOverlay.Upgrade();
2073             CHECK_NULL_VOID(overlay);
2074             auto selectOverlay = weakSelectOverlay.Upgrade();
2075             CHECK_NULL_VOID(selectOverlay);
2076             hasOverlay = selectOverlay->ResetSelectionAndDestroySelectOverlay(true);
2077             hasOverlay |= overlay->RemoveOverlay(true);
2078         },
2079         TaskExecutor::TaskType::UI, "ArkUIBackPressedRemoveOverlay");
2080     if (hasOverlay) {
2081         LOGI("Overlay consumed backpressed event");
2082         return true;
2083     }
2084 
2085     auto textfieldManager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2086     if (textfieldManager && textfieldManager->OnBackPressed()) {
2087         LOGI("textfield consumed backpressed event");
2088         return true;
2089     }
2090 
2091     auto result = false;
2092     taskExecutor_->PostSyncTask(
2093         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), stageManager = stageManager_, &result]() {
2094             auto frontend = weakFrontend.Upgrade();
2095             if (!frontend) {
2096                 result = false;
2097                 return;
2098             }
2099             auto context = weakPipelineContext.Upgrade();
2100             if (!context) {
2101                 result = false;
2102                 return;
2103             }
2104             CHECK_NULL_VOID(stageManager);
2105             auto lastPage = stageManager->GetLastPage();
2106             CHECK_NULL_VOID(lastPage);
2107             bool isEntry = false;
2108             auto pagePattern = lastPage->GetPattern<NG::PagePattern>();
2109             if (pagePattern) {
2110                 isEntry = pagePattern->IsNeedCallbackBackPressed();
2111             }
2112             auto navigationGroupNode =
2113                 AceType::DynamicCast<NavigationGroupNode>(context->FindNavigationNodeToHandleBack(lastPage, isEntry));
2114             if (navigationGroupNode) {
2115                 result = true;
2116             }
2117         },
2118         TaskExecutor::TaskType::UI, "ArkUIBackPressedFindNavigationGroup");
2119 
2120     if (result) {
2121         // user accept
2122         LOGI("Navigation consumed backpressed event");
2123         return true;
2124     }
2125 
2126     taskExecutor_->PostSyncTask(
2127         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), &result]() {
2128             auto frontend = weakFrontend.Upgrade();
2129             if (!frontend) {
2130                 result = false;
2131                 return;
2132             }
2133             result = frontend->OnBackPressed();
2134         },
2135         TaskExecutor::TaskType::JS, "ArkUIBackPressed");
2136 
2137     if (result) {
2138         // user accept
2139         LOGI("router consumed backpressed event");
2140         return true;
2141     }
2142     return false;
2143 }
2144 
FindNavigationNodeToHandleBack(const RefPtr<UINode> & node,bool & isEntry)2145 RefPtr<FrameNode> PipelineContext::FindNavigationNodeToHandleBack(const RefPtr<UINode>& node, bool& isEntry)
2146 {
2147     CHECK_NULL_RETURN(node, nullptr);
2148     const auto& children = node->GetChildren();
2149     for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
2150         auto& child = *iter;
2151         auto childNode = AceType::DynamicCast<FrameNode>(child);
2152         if (childNode && childNode->GetLayoutProperty()) {
2153             auto property = childNode->GetLayoutProperty();
2154             if (property->GetVisibilityValue(VisibleType::VISIBLE) != VisibleType::VISIBLE ||
2155                 !childNode->IsActive()) {
2156                 continue;
2157             }
2158         }
2159         if (childNode && childNode->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
2160             auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(childNode);
2161             auto topChild = navigationGroupNode->GetTopDestination();
2162             // find navigation from top destination
2163             auto targetNodeFromDestination = FindNavigationNodeToHandleBack(topChild, isEntry);
2164             if (targetNodeFromDestination) {
2165                 return targetNodeFromDestination;
2166             }
2167             if (isEntry) {
2168                 return nullptr;
2169             }
2170             targetNodeFromDestination = childNode;
2171             auto targetNavigation = AceType::DynamicCast<NavigationGroupNode>(targetNodeFromDestination);
2172             // check if the destination responds
2173             if (targetNavigation && targetNavigation->CheckCanHandleBack(isEntry)) {
2174                 return targetNavigation;
2175             }
2176             if (isEntry) {
2177                 return nullptr;
2178             }
2179             // if the destination does not responds, find navigation from navbar
2180             auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
2181             auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
2182             CHECK_NULL_RETURN(navigationLayoutProperty, nullptr);
2183             if (navigationLayoutProperty->GetHideNavBarValue(false)) {
2184                 return nullptr;
2185             }
2186             auto targetNodeFromNavbar = FindNavigationNodeToHandleBack(navBarNode, isEntry);
2187             if (targetNodeFromNavbar) {
2188                 return targetNodeFromNavbar;
2189             }
2190             return nullptr;
2191         }
2192         auto target = FindNavigationNodeToHandleBack(child, isEntry);
2193         if (target) {
2194             return target;
2195         }
2196         if (isEntry) {
2197             return nullptr;
2198         }
2199     }
2200     return nullptr;
2201 }
2202 
SetIsFocusActive(bool isFocusActive,FocusActiveReason reason,bool autoFocusInactive)2203 bool PipelineContext::SetIsFocusActive(bool isFocusActive, FocusActiveReason reason, bool autoFocusInactive)
2204 {
2205     if (reason == FocusActiveReason::USE_API) {
2206         TAG_LOGI(AceLogTag::ACE_FOCUS, "autoFocusInactive turns to %{public}d", autoFocusInactive);
2207         autoFocusInactive_ = autoFocusInactive;
2208     }
2209     if (!isFocusActive && reason == FocusActiveReason::POINTER_EVENT && !autoFocusInactive_) {
2210         TAG_LOGI(AceLogTag::ACE_FOCUS, "focus cannot be deactived automaticly by pointer event");
2211         return false;
2212     }
2213 
2214     if (isFocusActive_ == isFocusActive) {
2215         return false;
2216     }
2217     TAG_LOGI(AceLogTag::ACE_FOCUS, "Pipeline focus turns to %{public}s", isFocusActive ? "active" : "inactive");
2218     isFocusActive_ = isFocusActive;
2219     for (auto& pair : isFocusActiveUpdateEvents_) {
2220         if (pair.second) {
2221             pair.second(isFocusActive_);
2222         }
2223     }
2224     CHECK_NULL_RETURN(rootNode_, false);
2225     auto rootFocusHub = rootNode_->GetFocusHub();
2226     CHECK_NULL_RETURN(rootFocusHub, false);
2227     if (isFocusActive_) {
2228         return rootFocusHub->PaintAllFocusState();
2229     }
2230     rootFocusHub->ClearAllFocusState();
2231     return true;
2232 }
2233 
OnTouchEvent(const TouchEvent & point,bool isSubPipe,bool isEventsPassThrough)2234 void PipelineContext::OnTouchEvent(const TouchEvent& point, bool isSubPipe, bool isEventsPassThrough)
2235 {
2236     OnTouchEvent(point, rootNode_, isSubPipe, isEventsPassThrough);
2237 }
2238 
OnMouseEvent(const MouseEvent & event)2239 void PipelineContext::OnMouseEvent(const MouseEvent& event)
2240 {
2241     OnMouseEvent(event, rootNode_);
2242 }
2243 
OnAxisEvent(const AxisEvent & event)2244 void PipelineContext::OnAxisEvent(const AxisEvent& event)
2245 {
2246     OnAxisEvent(event, rootNode_);
2247 }
2248 
OnTouchEvent(const TouchEvent & point,const RefPtr<FrameNode> & node,bool isSubPipe,bool isEventsPassThrough)2249 void PipelineContext::OnTouchEvent(
2250     const TouchEvent& point, const RefPtr<FrameNode>& node, bool isSubPipe, bool isEventsPassThrough)
2251 {
2252     CHECK_RUN_ON(UI);
2253 
2254     HandlePenHoverOut(point);
2255 
2256 #ifdef UICAST_COMPONENT_SUPPORTED
2257     do {
2258         auto container = Container::Current();
2259         CHECK_NULL_BREAK(container);
2260         auto distributedUI = container->GetDistributedUI();
2261         CHECK_NULL_BREAK(distributedUI);
2262         if (distributedUI->IsSinkMode()) {
2263             distributedUI->BypassEvent(point, isSubPipe);
2264             return;
2265         }
2266     } while (false);
2267 #endif
2268 
2269     SerializedGesture etsSerializedGesture;
2270     if (point.type != TouchType::DOWN) {
2271         HandleEtsCardTouchEvent(point, etsSerializedGesture);
2272     }
2273 
2274     auto oriPoint = point;
2275     auto scalePoint = point.CreateScalePoint(GetViewScale());
2276     eventManager_->CheckDownEvent(scalePoint);
2277     ResSchedReport::GetInstance().OnTouchEvent(scalePoint);
2278 
2279     if (scalePoint.type != TouchType::MOVE && scalePoint.type != TouchType::PULL_MOVE &&
2280         scalePoint.type != TouchType::HOVER_MOVE) {
2281         eventManager_->GetEventTreeRecord(EventTreeType::TOUCH).AddTouchPoint(scalePoint);
2282         if (SystemProperties::GetAceCommercialLogEnabled() || scalePoint.isPrivacyMode) {
2283             TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
2284                 "InputTracking id:%{public}d, fingerId:%{public}d, type=%{public}d, inject=%{public}d, "
2285                 "isPrivacyMode=%{public}d",
2286                 scalePoint.touchEventId, scalePoint.id, (int)scalePoint.type, scalePoint.isInjected,
2287                 scalePoint.isPrivacyMode);
2288         } else {
2289             TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
2290                 "InputTracking id:%{public}d, fingerId:%{public}d, x=%{public}.3f, y=%{public}.3f type=%{public}d, "
2291                 "inject=%{public}d",
2292                 scalePoint.touchEventId, scalePoint.id, scalePoint.x, scalePoint.y, (int)scalePoint.type,
2293                 scalePoint.isInjected);
2294         }
2295     }
2296 
2297     if (scalePoint.type == TouchType::MOVE) {
2298         for (auto listenerItem : listenerVector_) {
2299             if (listenerItem) {
2300                 listenerItem->OnTouchEvent();
2301             }
2302         }
2303     }
2304 
2305     eventManager_->SetInstanceId(GetInstanceId());
2306     if (scalePoint.type != TouchType::MOVE && historyPointsById_.find(scalePoint.id) != historyPointsById_.end()) {
2307         historyPointsById_.erase(scalePoint.id);
2308     }
2309     if (scalePoint.type == TouchType::DOWN) {
2310         // Set focus state inactive while touch down event received
2311         SetIsFocusActive(false, FocusActiveReason::POINTER_EVENT);
2312         TouchRestrict touchRestrict { TouchRestrict::NONE };
2313         touchRestrict.sourceType = point.sourceType;
2314         touchRestrict.touchEvent = point;
2315         touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
2316 
2317         eventManager_->TouchTest(scalePoint, node, touchRestrict, GetPluginEventOffset(), viewScale_, isSubPipe);
2318         if (!touchRestrict.childTouchTestList.empty()) {
2319             scalePoint.childTouchTestList = touchRestrict.childTouchTestList;
2320         }
2321         auto touchTestResults = eventManager_->touchTestResults_;
2322         if (StylusDetectorMgr::GetInstance()->IsNeedInterceptedTouchEvent(
2323             scalePoint, eventManager_->touchTestResults_)) {
2324             eventManager_->ClearTouchTestTargetForPenStylus(scalePoint);
2325             return;
2326         }
2327 
2328         HandleEtsCardTouchEvent(oriPoint, etsSerializedGesture);
2329 
2330         if (etsSerializedGesture.data.size() != 0) {
2331             GestureGroup rebirth(GestureMode::Exclusive);
2332             rebirth.Deserialize(etsSerializedGesture.data.data());
2333             auto recognizer = rebirth.CreateRecognizer();
2334             if (recognizer) {
2335                 recognizer->SetInnerFlag(true);
2336                 recognizer->BeginReferee(scalePoint.id, true);
2337                 std::list<RefPtr<NGGestureRecognizer>> combined;
2338                 combined.emplace_back(recognizer);
2339                 for (auto iter = touchTestResults[point.id].begin();
2340                     iter != touchTestResults[point.id].end(); iter++) {
2341                     auto outRecognizer = AceType::DynamicCast<NGGestureRecognizer>(*iter);
2342                     if (outRecognizer) {
2343                         combined.emplace_back(outRecognizer);
2344                         touchTestResults[point.id].erase(iter);
2345                         break;
2346                     }
2347                 }
2348                 auto exclusiveRecognizer = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(combined));
2349                 exclusiveRecognizer->AttachFrameNode(node);
2350                 exclusiveRecognizer->BeginReferee(scalePoint.id);
2351                 touchTestResults[point.id].emplace_back(exclusiveRecognizer);
2352                 eventManager_->touchTestResults_ = touchTestResults;
2353                 eventManager_->SetInnerFlag(true);
2354             }
2355         }
2356         if (IsFormRender() && touchTestResults.find(point.id) != touchTestResults.end()) {
2357             for (const auto& touchResult : touchTestResults[point.id]) {
2358                 auto recognizer = AceType::DynamicCast<NG::RecognizerGroup>(touchResult);
2359                 if (recognizer) {
2360                     auto gesture = recognizer->CreateGestureFromRecognizer();
2361                     if (gesture) {
2362                         serializedGesture_.data = std::vector<char>(gesture->SizeofMe());
2363                         gesture->Serialize(serializedGesture_.data.data());
2364                     }
2365                     break;
2366                 }
2367             }
2368         }
2369         for (const auto& weakContext : touchPluginPipelineContext_) {
2370             auto pipelineContext = DynamicCast<OHOS::Ace::PipelineBase>(weakContext.Upgrade());
2371             if (!pipelineContext) {
2372                 continue;
2373             }
2374             auto pluginPoint =
2375                 point.UpdateScalePoint(viewScale_, static_cast<float>(pipelineContext->GetPluginEventOffset().GetX()),
2376                     static_cast<float>(pipelineContext->GetPluginEventOffset().GetY()), point.id);
2377             // eventManager_ instance Id may changed.
2378             pipelineContext->OnTouchEvent(pluginPoint, true);
2379         }
2380 
2381         // restore instance Id.
2382         eventManager_->SetInstanceId(GetInstanceId());
2383     }
2384     auto rootOffset = GetRootRect().GetOffset();
2385     eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
2386 
2387     if (isSubPipe) {
2388         return;
2389     }
2390 
2391     // Currently, SetupRootElement is executed later than InitializeCallback in AceContainer.
2392     // We need to check whether accessibilityManagerNG_ is created.
2393     if (accessibilityManagerNG_ != nullptr) {
2394         accessibilityManagerNG_->HandleAccessibilityHoverEvent(node, scalePoint);
2395     }
2396 
2397     if (scalePoint.type == TouchType::MOVE) {
2398         if (isEventsPassThrough) {
2399             scalePoint.isPassThroughMode = true;
2400             eventManager_->FlushTouchEventsEnd({ scalePoint });
2401             eventManager_->DispatchTouchEvent(scalePoint);
2402             hasIdleTasks_ = true;
2403             RequestFrame();
2404             return;
2405         }
2406         if (!eventManager_->GetInnerFlag()) {
2407             auto mockPoint = point;
2408             mockPoint.type = TouchType::CANCEL;
2409             HandleEtsCardTouchEvent(mockPoint, etsSerializedGesture);
2410             RemoveEtsCardTouchEventCallback(mockPoint.id);
2411         }
2412         touchEvents_.emplace_back(point);
2413         hasIdleTasks_ = true;
2414         RequestFrame();
2415         return;
2416     }
2417 
2418     if (scalePoint.type == TouchType::UP) {
2419         lastTouchTime_ = GetTimeFromExternalTimer();
2420         CompensateTouchMoveEvent(scalePoint);
2421         if (thpExtraMgr_ != nullptr) {
2422             const uint32_t delay = 800; // 800: ms
2423             taskExecutor_->RemoveTask(TaskExecutor::TaskType::UI, "NotifyResponseRegionChanged");
2424             auto task = [weak = WeakClaim(this)]() {
2425                 auto pipeline = weak.Upgrade();
2426                 CHECK_NULL_VOID(pipeline);
2427                 pipeline->NotifyResponseRegionChanged(pipeline->GetRootElement());
2428             };
2429             taskExecutor_->PostDelayedTask(task, TaskExecutor::TaskType::UI, delay, "NotifyResponseRegionChanged");
2430         }
2431     }
2432 
2433     eventManager_->DispatchTouchEvent(scalePoint);
2434 
2435     if ((scalePoint.type == TouchType::UP) || (scalePoint.type == TouchType::CANCEL)) {
2436         // need to reset touchPluginPipelineContext_ for next touch down event.
2437         touchPluginPipelineContext_.clear();
2438         RemoveEtsCardTouchEventCallback(point.id);
2439         ResetDraggingStatus(scalePoint, node);
2440     }
2441     if (scalePoint.type != TouchType::MOVE) {
2442         auto lastDispatchTime = eventManager_->GetLastDispatchTime();
2443         lastDispatchTime.erase(scalePoint.id);
2444         eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
2445         auto idToTouchPoint = eventManager_->GetIdToTouchPoint();
2446         idToTouchPoint.erase(scalePoint.id);
2447         eventManager_->SetIdToTouchPoint(std::move(idToTouchPoint));
2448     }
2449 
2450     hasIdleTasks_ = true;
2451     RequestFrame();
2452 }
2453 
CompensateTouchMoveEventFromUnhandledEvents(const TouchEvent & event)2454 bool PipelineContext::CompensateTouchMoveEventFromUnhandledEvents(const TouchEvent& event)
2455 {
2456     std::vector<TouchEvent> history;
2457     if (!touchEvents_.empty()) {
2458         for (auto iter = touchEvents_.begin(); iter != touchEvents_.end();) {
2459             auto movePoint = (*iter).CreateScalePoint(GetViewScale());
2460             if (event.id == movePoint.id) {
2461                 history.emplace_back(movePoint);
2462                 iter = touchEvents_.erase(iter);
2463             } else {
2464                 auto& pointers = iter->pointers;
2465                 for (auto pointerIter = pointers.begin(); pointerIter != pointers.end();) {
2466                     if (pointerIter->id == event.id) {
2467                         pointerIter = pointers.erase(pointerIter);
2468                     } else {
2469                         ++pointerIter;
2470                     }
2471                 }
2472                 ++iter;
2473             }
2474         }
2475         if (!history.empty()) {
2476             TouchEvent lastMoveEvent(history.back());
2477             lastMoveEvent.history.swap(history);
2478             eventManager_->SetLastMoveBeforeUp(event.sourceType == SourceType::MOUSE);
2479             eventManager_->DispatchTouchEvent(lastMoveEvent);
2480             eventManager_->SetLastMoveBeforeUp(false);
2481         } else {
2482             TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
2483                 "Finger id: %{public}d, not found unhandled move event, compensate failed.", event.id);
2484         }
2485         return true;
2486     }
2487     return false;
2488 }
2489 
CompensateTouchMoveEvent(const TouchEvent & event)2490 void PipelineContext::CompensateTouchMoveEvent(const TouchEvent& event)
2491 {
2492     if (event.type != TouchType::UP) {
2493         // If not up, no need to compensate touch move event.
2494         return;
2495     }
2496     if (!CompensateTouchMoveEventFromUnhandledEvents(event)) {
2497         // Compensate touch move event with all touch move Event before up has been handled.
2498         auto lastEventIter = eventManager_->GetIdToTouchPoint().find(event.id);
2499         if (lastEventIter != eventManager_->GetIdToTouchPoint().end()) {
2500             auto iter = eventManager_->GetLastDispatchTime().find(lastEventIter->first);
2501             if (iter != eventManager_->GetLastDispatchTime().end()) {
2502                 ACE_SCOPED_TRACE("CompensateTouchMoveEvent last move event time: %s last dispatch time: %s",
2503                     std::to_string(static_cast<uint64_t>(lastEventIter->second.time.time_since_epoch().count()))
2504                         .c_str(),
2505                     std::to_string(iter->second).c_str());
2506                 if (static_cast<uint64_t>(lastEventIter->second.time.time_since_epoch().count()) > iter->second) {
2507                     eventManager_->SetLastMoveBeforeUp(event.sourceType == SourceType::MOUSE);
2508                     eventManager_->DispatchTouchEvent(lastEventIter->second);
2509                     eventManager_->SetLastMoveBeforeUp(false);
2510                 }
2511             }
2512         }
2513     }
2514 
2515     auto lastEventIter = eventManager_->GetIdToTouchPoint().find(event.id);
2516     if (lastEventIter != eventManager_->GetIdToTouchPoint().end()) {
2517         ACE_SCOPED_TRACE("Finger id: %d process last move event eventId: %d", lastEventIter->first,
2518             lastEventIter->second.touchEventId);
2519     }
2520 }
2521 
ResetDraggingStatus(const TouchEvent & touchPoint,const RefPtr<FrameNode> & node)2522 void PipelineContext::ResetDraggingStatus(const TouchEvent& touchPoint, const RefPtr<FrameNode>& node)
2523 {
2524     auto manager = GetDragDropManager();
2525     CHECK_NULL_VOID(manager);
2526     manager->ResetDraggingStatus(touchPoint);
2527 }
2528 
OnSurfaceDensityChanged(double density)2529 void PipelineContext::OnSurfaceDensityChanged(double density)
2530 {
2531     CHECK_RUN_ON(UI);
2532     if (!NearEqual(density, density_)) {
2533         isDensityChanged_ = true;
2534     }
2535     density_ = density;
2536     if (!NearZero(viewScale_)) {
2537         dipScale_ = density_ / viewScale_;
2538     }
2539     if (isDensityChanged_) {
2540         UIObserverHandler::GetInstance().NotifyDensityChange(density_);
2541         PipelineBase::OnSurfaceDensityChanged(density);
2542     }
2543 }
2544 
DumpPageViewData(const RefPtr<FrameNode> & node,RefPtr<ViewDataWrap> viewDataWrap,bool skipSubAutoFillContainer,bool needsRecordData)2545 bool PipelineContext::DumpPageViewData(const RefPtr<FrameNode>& node, RefPtr<ViewDataWrap> viewDataWrap,
2546     bool skipSubAutoFillContainer, bool needsRecordData)
2547 {
2548     CHECK_NULL_RETURN(viewDataWrap, false);
2549     RefPtr<FrameNode> pageNode = nullptr;
2550     RefPtr<FrameNode> dumpNode = nullptr;
2551     if (node == nullptr) {
2552         if (stageManager_) {
2553             pageNode = stageManager_->GetLastPage();
2554             dumpNode = pageNode;
2555         }
2556     } else {
2557         pageNode = node->GetPageNode();
2558         dumpNode = node;
2559     }
2560     CHECK_NULL_RETURN(dumpNode, false);
2561     dumpNode->DumpViewDataPageNodes(viewDataWrap, skipSubAutoFillContainer, needsRecordData);
2562     // The page path may not be obtained in the container, use the node tag as the page path.
2563     if (node) {
2564         const auto& nodeTag = node->GetTag();
2565         if (nodeTag == V2::DIALOG_ETS_TAG || nodeTag == V2::SHEET_PAGE_TAG || nodeTag == V2::MODAL_PAGE_TAG) {
2566             viewDataWrap->SetPageUrl(nodeTag);
2567             return true;
2568         }
2569     }
2570     CHECK_NULL_RETURN(pageNode, false);
2571     auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
2572     CHECK_NULL_RETURN(pagePattern, false);
2573     auto pageInfo = pagePattern->GetPageInfo();
2574     CHECK_NULL_RETURN(pageInfo, false);
2575     viewDataWrap->SetPageUrl(pageInfo->GetPageUrl());
2576     return true;
2577 }
2578 
CheckNeedAutoSave()2579 bool PipelineContext::CheckNeedAutoSave()
2580 {
2581     CHECK_NULL_RETURN(stageManager_, false);
2582     auto pageNode = stageManager_->GetLastPage();
2583     CHECK_NULL_RETURN(pageNode, false);
2584     return pageNode->NeedRequestAutoSave();
2585 }
2586 
CheckOverlayFocus()2587 bool PipelineContext::CheckOverlayFocus()
2588 {
2589     CHECK_NULL_RETURN(overlayManager_, false);
2590     auto overlayNode = overlayManager_->GetOverlayNode();
2591     CHECK_NULL_RETURN(overlayNode, false);
2592     return overlayNode->GetFocusHub() && overlayNode->GetFocusHub()->IsCurrentFocus();
2593 }
2594 
NotifyFillRequestSuccess(AceAutoFillType autoFillType,RefPtr<ViewDataWrap> viewDataWrap)2595 void PipelineContext::NotifyFillRequestSuccess(AceAutoFillType autoFillType, RefPtr<ViewDataWrap> viewDataWrap)
2596 {
2597     CHECK_NULL_VOID(viewDataWrap);
2598     auto pageNodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
2599     for (const auto& item : pageNodeInfoWraps) {
2600         if (item == nullptr) {
2601             continue;
2602         }
2603         auto frameNode = DynamicCast<FrameNode>(ElementRegister::GetInstance()->GetUINodeById(item->GetId()));
2604         if (frameNode == nullptr) {
2605             TAG_LOGW(AceLogTag::ACE_AUTO_FILL, "frameNode is not found, id=%{public}d", item->GetId());
2606             continue;
2607         }
2608         frameNode->NotifyFillRequestSuccess(viewDataWrap, item, autoFillType);
2609     }
2610 }
2611 
NotifyFillRequestFailed(RefPtr<FrameNode> node,int32_t errCode,const std::string & fillContent,bool isPopup)2612 void PipelineContext::NotifyFillRequestFailed(RefPtr<FrameNode> node, int32_t errCode,
2613     const std::string& fillContent, bool isPopup)
2614 {
2615     CHECK_NULL_VOID(node);
2616     node->NotifyFillRequestFailed(errCode, fillContent, isPopup);
2617 }
2618 
OnDumpInfo(const std::vector<std::string> & params) const2619 bool PipelineContext::OnDumpInfo(const std::vector<std::string>& params) const
2620 {
2621     ACE_DCHECK(!params.empty());
2622     if (window_) {
2623         DumpLog::GetInstance().Print(1, "LastRequestVsyncTime: " + std::to_string(window_->GetLastRequestVsyncTime()));
2624 #ifdef ENABLE_ROSEN_BACKEND
2625         auto rsUIDirector = window_->GetRSUIDirector();
2626         if (rsUIDirector) {
2627             DumpLog::GetInstance().Print(1, "transactionFlags: [" + std::to_string(getpid()) + "," +
2628                 std::to_string(rsUIDirector->GetIndex()) + "]");
2629         }
2630 #endif
2631     }
2632     DumpLog::GetInstance().Print(1, "last vsyncId: " + std::to_string(GetFrameCount()));
2633     if (params[0] == "-element") {
2634         if (params.size() > 1 && params[1] == "-lastpage") {
2635             auto lastPage = stageManager_->GetLastPage();
2636             if (params.size() < USED_ID_FIND_FLAG && lastPage) {
2637                 lastPage->DumpTree(0);
2638                 DumpLog::GetInstance().OutPutBySize();
2639             }
2640             if (params.size() == USED_ID_FIND_FLAG && lastPage && !lastPage->DumpTreeById(0, params[2])) {
2641                 DumpLog::GetInstance().Print(
2642                     "There is no id matching the ID in the parameter,please check whether the id is correct");
2643             }
2644         } else {
2645             if (params.size() == USED_ID_FIND_FLAG && !rootNode_->DumpTreeById(0, params[2])) {
2646                 DumpLog::GetInstance().Print(
2647                     "There is no id matching the ID in the parameter,please check whether the id is correct");
2648             }
2649             if (params.size() < USED_ID_FIND_FLAG) {
2650                 rootNode_->DumpTree(0);
2651                 DumpLog::GetInstance().OutPutBySize();
2652             }
2653         }
2654     } else if (params[0] == "-navigation") {
2655         auto navigationDumpMgr = GetNavigationManager();
2656         if (navigationDumpMgr) {
2657             navigationDumpMgr->OnDumpInfo();
2658         }
2659     } else if (params[0] == "-focus") {
2660         if (rootNode_->GetFocusHub()) {
2661             rootNode_->GetFocusHub()->DumpFocusTree(0);
2662         }
2663     } else if (params[0] == "-focuswindowscene") {
2664         auto windowSceneNode = GetFocusedWindowSceneNode();
2665         auto windowSceneFocusHub = windowSceneNode ? windowSceneNode->GetFocusHub() : nullptr;
2666         if (windowSceneFocusHub) {
2667             windowSceneFocusHub->DumpFocusTree(0);
2668         }
2669     } else if (params[0] == "-focusmanager") {
2670         if (focusManager_) {
2671             focusManager_->DumpFocusManager();
2672         }
2673     } else if (params[0] == "-accessibility" || params[0] == "-inspector") {
2674         auto accessibilityManager = GetAccessibilityManager();
2675         if (accessibilityManager) {
2676             accessibilityManager->OnDumpInfoNG(params, windowId_);
2677         }
2678     } else if (params[0] == "-rotation" && params.size() >= 2) {
2679     } else if (params[0] == "-animationscale" && params.size() >= 2) {
2680     } else if (params[0] == "-velocityscale" && params.size() >= 2) {
2681     } else if (params[0] == "-scrollfriction" && params.size() >= 2) {
2682     } else if (params[0] == "-threadstuck" && params.size() >= 3) {
2683     } else if (params[0] == "-pipeline") {
2684         DumpPipelineInfo();
2685     } else if (params[0] == "-jsdump") {
2686         std::vector<std::string> jsParams;
2687         if (params.begin() != params.end()) {
2688             jsParams = std::vector<std::string>(params.begin() + 1, params.end());
2689         }
2690 
2691         auto stageNode = stageManager_->GetStageNode();
2692         CHECK_NULL_RETURN(stageNode, false);
2693         auto children = stageNode->GetChildren();
2694         for (const auto& pageNode : children) {
2695             auto frameNode = AceType::DynamicCast<FrameNode>(pageNode);
2696             CHECK_NULL_RETURN(frameNode, false);
2697             auto pagePattern = frameNode->GetPattern<PagePattern>();
2698             CHECK_NULL_RETURN(pagePattern, false);
2699             pagePattern->FireDumpListener(jsParams);
2700         }
2701     } else if (params[0] == "-event") {
2702         if (eventManager_) {
2703             eventManager_->DumpEvent(EventTreeType::TOUCH);
2704         }
2705         DumpUIExt();
2706     } else if (params[0] == "-postevent") {
2707         if (eventManager_) {
2708             eventManager_->DumpEvent(EventTreeType::POST_EVENT);
2709         }
2710     } else if (params[0] == "-imagecache") {
2711         if (imageCache_) {
2712             imageCache_->DumpCacheInfo();
2713         }
2714         DumpUIExt();
2715     } else if (params[0] == "-imagefilecache") {
2716         ImageFileCache::GetInstance().DumpCacheInfo();
2717         DumpUIExt();
2718     } else if (params[0] == "-allelements") {
2719         AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
2720             auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2721             auto rootNode = pipeline->GetRootElement();
2722             if (rootNode) {
2723                 DumpLog::GetInstance().Print(0, "ContainerId: " + std::to_string(Container::CurrentId()));
2724                 rootNode->DumpTree(0);
2725                 DumpLog::GetInstance().OutPutBySize();
2726             }
2727         });
2728     } else if (params[0] == "-default") {
2729         rootNode_->DumpTree(0);
2730         DumpLog::GetInstance().OutPutDefault();
2731     } else if (params[0] == "--stylus") {
2732         StylusDetectorDefault::GetInstance()->ExecuteCommand(params);
2733     } else if (params[0] == "-overlay") {
2734         if (overlayManager_) {
2735             overlayManager_->DumpOverlayInfo();
2736         }
2737     } else if (params[0] == "-simplify") {
2738         auto root = JsonUtil::Create(true);
2739         rootNode_->DumpSimplifyTree(0, root);
2740         auto json = root->ToString();
2741         json.erase(std::remove(json.begin(), json.end(), ' '), json.end());
2742         DumpLog::GetInstance().Print(json);
2743     }
2744     return true;
2745 }
2746 
DumpUIExt() const2747 void PipelineContext::DumpUIExt() const
2748 {
2749 #ifdef WINDOW_SCENE_SUPPORTED
2750     if (uiExtensionManager_) {
2751         uiExtensionManager_->DumpUIExt();
2752     }
2753 #endif
2754 }
2755 
GetCurrentFrameInfo(uint64_t recvTime,uint64_t timeStamp)2756 FrameInfo* PipelineContext::GetCurrentFrameInfo(uint64_t recvTime, uint64_t timeStamp)
2757 {
2758     if (SystemProperties::GetDumpFrameCount() == 0) {
2759         return nullptr;
2760     }
2761     if (dumpFrameInfos_.size() >= SystemProperties::GetDumpFrameCount()) {
2762         dumpFrameInfos_.pop_front();
2763     }
2764 
2765     dumpFrameInfos_.push_back({ .frameRecvTime_ = recvTime, .frameTimeStamp_ = timeStamp });
2766     return &dumpFrameInfos_.back();
2767 }
2768 
DumpPipelineInfo() const2769 void PipelineContext::DumpPipelineInfo() const
2770 {
2771     DumpLog::GetInstance().Print("PipelineInfo:");
2772     if (window_) {
2773         DumpLog::GetInstance().Print(1, "DisplayRefreshRate: " + std::to_string(window_->GetRefreshRate()));
2774         DumpLog::GetInstance().Print(1, "LastRequestVsyncTime: " + std::to_string(window_->GetLastRequestVsyncTime()));
2775         DumpLog::GetInstance().Print(1, "NowTime: " + std::to_string(GetSysTimestamp()));
2776     }
2777     if (!dumpFrameInfos_.empty()) {
2778         DumpLog::GetInstance().Print("==================================FrameTask==================================");
2779         for (const auto& info : dumpFrameInfos_) {
2780             DumpLog::GetInstance().Print("Task: " + info.GetTimeInfo());
2781             DumpLog::GetInstance().Print(1, "LayoutTask:");
2782             for (const auto& layout : info.layoutInfos_) {
2783                 DumpLog::GetInstance().Print(2, layout.ToString());
2784             }
2785             DumpLog::GetInstance().Print(1, "RenderTask:");
2786             for (const auto& layout : info.renderInfos_) {
2787                 DumpLog::GetInstance().Print(2, layout.ToString());
2788             }
2789             DumpLog::GetInstance().Print(
2790                 "==================================FrameTask==================================");
2791         }
2792     }
2793 }
2794 
CollectTouchEventsBeforeVsync(std::list<TouchEvent> & touchEvents)2795 void PipelineContext::CollectTouchEventsBeforeVsync(std::list<TouchEvent>& touchEvents)
2796 {
2797     auto targetTimeStamp = GetVsyncTime() - compensationValue_;
2798     for (auto iter = touchEvents_.begin(); iter != touchEvents_.end();) {
2799         auto timeStamp = std::chrono::duration_cast<std::chrono::nanoseconds>(iter->time.time_since_epoch()).count();
2800         if (targetTimeStamp < static_cast<uint64_t>(timeStamp)) {
2801             iter++;
2802             continue;
2803         }
2804         touchEvents.emplace_back(*iter);
2805         iter = touchEvents_.erase(iter);
2806     }
2807 }
2808 
FlushTouchEvents()2809 void PipelineContext::FlushTouchEvents()
2810 {
2811     CHECK_RUN_ON(UI);
2812     CHECK_NULL_VOID(rootNode_);
2813     {
2814         std::unordered_set<int32_t> moveEventIds;
2815         std::list<TouchEvent> touchEvents;
2816         CollectTouchEventsBeforeVsync(touchEvents);
2817         if (touchEvents.empty()) {
2818             canUseLongPredictTask_ = true;
2819             return;
2820         }
2821         canUseLongPredictTask_ = false;
2822         eventManager_->FlushTouchEventsBegin(touchEvents_);
2823         std::unordered_map<int, TouchEvent> idToTouchPoints;
2824         bool needInterpolation = true;
2825         std::unordered_map<int32_t, TouchEvent> newIdTouchPoints;
2826         for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) {
2827             auto scalePoint = (*iter).CreateScalePoint(GetViewScale());
2828             idToTouchPoints.emplace(scalePoint.id, scalePoint);
2829             idToTouchPoints[scalePoint.id].history.insert(idToTouchPoints[scalePoint.id].history.begin(), scalePoint);
2830             needInterpolation = iter->type != TouchType::MOVE ? false : true;
2831         }
2832         if (!NeedTouchInterpolation()) {
2833             needInterpolation = false;
2834         }
2835         if (needInterpolation && SystemProperties::IsNeedResampleTouchPoints()) {
2836             auto targetTimeStamp = resampleTimeStamp_;
2837             for (const auto& idIter : idToTouchPoints) {
2838                 auto stamp =
2839                     std::chrono::duration_cast<std::chrono::nanoseconds>(idIter.second.time.time_since_epoch()).count();
2840                 if (targetTimeStamp > static_cast<uint64_t>(stamp)) {
2841                     continue;
2842                 }
2843                 TouchEvent newTouchEvent;
2844                 if (eventManager_->GetResampleTouchEvent(
2845                         historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp, newTouchEvent)) {
2846                     newIdTouchPoints[idIter.first] = newTouchEvent;
2847                 }
2848                 historyPointsById_[idIter.first] = idIter.second.history;
2849             }
2850         }
2851         std::list<TouchEvent> touchPoints;
2852         for (const auto& iter : idToTouchPoints) {
2853             auto lastDispatchTime = eventManager_->GetLastDispatchTime();
2854             lastDispatchTime[iter.first] = GetVsyncTime() - compensationValue_;
2855             eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
2856             auto it = newIdTouchPoints.find(iter.first);
2857             if (it != newIdTouchPoints.end()) {
2858                 touchPoints.emplace_back(it->second);
2859             } else {
2860                 touchPoints.emplace_back(iter.second);
2861             }
2862         }
2863         auto maxSize = touchPoints.size();
2864         for (auto iter = touchPoints.rbegin(); iter != touchPoints.rend(); ++iter) {
2865             maxSize--;
2866             if (maxSize == 0) {
2867                 eventManager_->FlushTouchEventsEnd(touchPoints);
2868             }
2869             eventManager_->DispatchTouchEvent(*iter);
2870         }
2871         auto idToTouchPoint = eventManager_->GetIdToTouchPoint();
2872         idToTouchPoint = std::move(idToTouchPoints);
2873         eventManager_->SetIdToTouchPoint(std::move(idToTouchPoint));
2874     }
2875 }
2876 
OnAccessibilityHoverEvent(const TouchEvent & point,const RefPtr<NG::FrameNode> & node)2877 void PipelineContext::OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node)
2878 {
2879     CHECK_RUN_ON(UI);
2880     auto scaleEvent = point.CreateScalePoint(viewScale_);
2881     if (scaleEvent.type != TouchType::HOVER_MOVE) {
2882 #ifdef IS_RELEASE_VERSION
2883         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
2884             "OnAccessibilityHoverEvent event id:%{public}d, fingerId:%{public}d,"
2885             "type=%{public}d, "
2886             "inject=%{public}d",
2887             scaleEvent.touchEventId, scaleEvent.id, (int)scaleEvent.type, scaleEvent.isInjected);
2888 #else
2889         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
2890             "OnAccessibilityHoverEvent event id:%{public}d, fingerId:%{public}d, x=%{public}f y=%{public}f "
2891             "type=%{public}d, "
2892             "inject=%{public}d",
2893             scaleEvent.touchEventId, scaleEvent.id, scaleEvent.x, scaleEvent.y, (int)scaleEvent.type,
2894             scaleEvent.isInjected);
2895 #endif
2896     }
2897     auto targerNode = node ? node : rootNode_;
2898     if (accessibilityManagerNG_ != nullptr) {
2899         accessibilityManagerNG_->HandleAccessibilityHoverEvent(targerNode, scaleEvent);
2900     }
2901     TouchRestrict touchRestrict { TouchRestrict::NONE };
2902     touchRestrict.sourceType = scaleEvent.sourceType;
2903     // use mouse to collect accessibility hover target
2904     touchRestrict.hitTestType = SourceType::MOUSE;
2905     touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
2906     eventManager_->AccessibilityHoverTest(scaleEvent, targerNode, touchRestrict);
2907     eventManager_->DispatchAccessibilityHoverEventNG(scaleEvent);
2908     RequestFrame();
2909 }
2910 
OnPenHoverEvent(const TouchEvent & point,const RefPtr<NG::FrameNode> & node)2911 void PipelineContext::OnPenHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node)
2912 {
2913     CHECK_RUN_ON(UI);
2914     auto scaleEvent = point.CreateScalePoint(viewScale_);
2915     if (scaleEvent.type != TouchType::MOVE) {
2916         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
2917             "OnPenHoverEvent event id:%{public}d, fingerId:%{public}d "
2918             "type=%{public}d, "
2919             "inject=%{public}d",
2920             scaleEvent.touchEventId, scaleEvent.id, (int)scaleEvent.type,
2921             scaleEvent.isInjected);
2922     }
2923 
2924     auto targerNode = node ? node : rootNode_;
2925     TouchRestrict touchRestrict { TouchRestrict::NONE };
2926     touchRestrict.sourceType = scaleEvent.sourceType;
2927     touchRestrict.touchEvent.sourceTool = scaleEvent.sourceTool;
2928     touchRestrict.touchEvent.type = scaleEvent.type;
2929     touchRestrict.touchEvent.force = scaleEvent.force;
2930 
2931     // use mouse to collect pen hover target
2932     touchRestrict.hitTestType = SourceType::MOUSE;
2933     touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
2934     eventManager_->PenHoverTest(scaleEvent, targerNode, touchRestrict);
2935     eventManager_->DispatchPenHoverEventNG(scaleEvent);
2936     eventManager_->DispatchPenHoverMoveEventNG(scaleEvent);
2937     RequestFrame();
2938 }
2939 
HandlePenHoverOut(const TouchEvent & point)2940 void PipelineContext::HandlePenHoverOut(const TouchEvent& point)
2941 {
2942     if (point.sourceTool != SourceTool::PEN || point.type != TouchType::DOWN || NearZero(point.force)) {
2943         return;
2944     }
2945 
2946     CHECK_RUN_ON(UI);
2947     auto oriPoint = point;
2948     oriPoint.type = TouchType::PROXIMITY_OUT;
2949 
2950     TouchTestResult testResult;
2951     eventManager_->UpdatePenHoverNode(oriPoint, testResult);
2952     eventManager_->DispatchPenHoverEventNG(oriPoint);
2953 }
2954 
OnMouseEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)2955 void PipelineContext::OnMouseEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
2956 {
2957     CHECK_RUN_ON(UI);
2958     if (!lastMouseEvent_) {
2959         lastMouseEvent_ = std::make_unique<MouseEvent>();
2960     }
2961     lastMouseEvent_->x = event.x;
2962     lastMouseEvent_->y = event.y;
2963     lastMouseEvent_->button = event.button;
2964     lastMouseEvent_->action = event.action;
2965     lastMouseEvent_->sourceType = event.sourceType;
2966     lastMouseEvent_->time = event.time;
2967     lastMouseEvent_->touchEventId = event.touchEventId;
2968 
2969     if (event.button == MouseButton::RIGHT_BUTTON && event.action == MouseAction::PRESS) {
2970         // Mouse right button press event set focus inactive here.
2971         // Mouse left button press event will set focus inactive in touch process.
2972         SetIsFocusActive(false, FocusActiveReason::POINTER_EVENT);
2973     }
2974 
2975     auto manager = GetDragDropManager();
2976     if (manager) {
2977         if (event.button == MouseButton::RIGHT_BUTTON &&
2978             (event.action == MouseAction::PRESS || event.action == MouseAction::PULL_UP)) {
2979             manager->SetIsDragCancel(true);
2980         } else {
2981             manager->SetIsDragCancel(false);
2982         }
2983     } else {
2984         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "InputTracking id:%{public}d, OnMouseEvent GetDragDropManager is null",
2985             event.touchEventId);
2986     }
2987 
2988     auto container = Container::Current();
2989     if (((event.action == MouseAction::RELEASE || event.action == MouseAction::PRESS ||
2990              event.action == MouseAction::MOVE) &&
2991             (event.button == MouseButton::LEFT_BUTTON || event.pressedButtons == MOUSE_PRESS_LEFT)) ||
2992         event.action == MouseAction::CANCEL) {
2993         auto touchPoint = event.CreateTouchPoint();
2994         if (event.pullAction == MouseAction::PULL_MOVE) {
2995             touchPoint.pullType = TouchType::PULL_MOVE;
2996         }
2997         OnTouchEvent(touchPoint, node);
2998     } else {
2999         auto touchPoint = event.CreateTouchPoint();
3000         auto scalePoint = touchPoint.CreateScalePoint(GetViewScale());
3001         auto rootOffset = GetRootRect().GetOffset();
3002         eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
3003     }
3004 
3005     CHECK_NULL_VOID(node);
3006     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3007     TouchRestrict touchRestrict { TouchRestrict::NONE };
3008     touchRestrict.sourceType = event.sourceType;
3009     touchRestrict.hitTestType = SourceType::MOUSE;
3010     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3011     eventManager_->MouseTest(scaleEvent, node, touchRestrict);
3012     eventManager_->DispatchMouseEventNG(scaleEvent);
3013     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
3014     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
3015     accessibilityManagerNG_->HandleAccessibilityHoverEvent(node, scaleEvent);
3016     RequestFrame();
3017 }
3018 
FlushMouseEvent()3019 void PipelineContext::FlushMouseEvent()
3020 {
3021     if (!lastMouseEvent_ || lastMouseEvent_->action == MouseAction::WINDOW_LEAVE) {
3022         return;
3023     }
3024     auto container = Container::Current();
3025     if (container) {
3026         int32_t sourceType = 0;
3027         auto result = container->GetCurPointerEventSourceType(sourceType);
3028         if (result) {
3029             TAG_LOGI(AceLogTag::ACE_MOUSE,
3030                 "FlushMouseEvent: last pointer event id %{public}d sourceType:%{public}d last mouse event "
3031                 "time:%{public}" PRId64 " current time %{public}" PRId64 "",
3032                 lastMouseEvent_->touchEventId, sourceType,
3033                 static_cast<int64_t>(lastMouseEvent_->time.time_since_epoch().count()), GetSysTimestamp());
3034         }
3035     }
3036     MouseEvent event;
3037     event.x = lastMouseEvent_->x;
3038     event.y = lastMouseEvent_->y;
3039     event.time = lastMouseEvent_->time;
3040     event.action = MouseAction::MOVE;
3041     event.button = MouseButton::NONE_BUTTON;
3042     event.sourceType = SourceType::MOUSE;
3043 
3044     CHECK_RUN_ON(UI);
3045     CHECK_NULL_VOID(rootNode_);
3046     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3047     TouchRestrict touchRestrict { TouchRestrict::NONE };
3048     touchRestrict.sourceType = event.sourceType;
3049     touchRestrict.hitTestType = SourceType::MOUSE;
3050     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3051     eventManager_->MouseTest(scaleEvent, rootNode_, touchRestrict);
3052     eventManager_->DispatchMouseEventNG(scaleEvent);
3053     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
3054     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
3055 }
3056 
ChangeMouseStyle(int32_t nodeId,MouseFormat format,int32_t windowId,bool isByPass,MouseStyleChangeReason reason)3057 bool PipelineContext::ChangeMouseStyle(int32_t nodeId, MouseFormat format, int32_t windowId, bool isByPass,
3058     MouseStyleChangeReason reason)
3059 {
3060     auto mouseStyleManager = eventManager_->GetMouseStyleManager();
3061     CHECK_NULL_RETURN(mouseStyleManager, false);
3062     mouseStyleManager->SetMouseFormat(windowId, nodeId, format, isByPass, reason);
3063     RequestFrame();
3064     return true;
3065 }
3066 
ReDispatch(KeyEvent & keyEvent)3067 void PipelineContext::ReDispatch(KeyEvent& keyEvent)
3068 {
3069     CHECK_NULL_VOID(eventManager_);
3070     TAG_LOGD(AceLogTag::ACE_WEB, "Web ReDispach key event: code:" SEC_PLD(%{public}d) "/action:%{public}d.",
3071         SEC_PARAM(keyEvent.code), keyEvent.action);
3072     eventManager_->ReDispatch(keyEvent);
3073 }
3074 
OnNonPointerEvent(const NonPointerEvent & event)3075 bool PipelineContext::OnNonPointerEvent(const NonPointerEvent& event)
3076 {
3077     return eventManager_->OnNonPointerEvent(event);
3078 }
3079 
RequestFocus(const std::string & targetNodeId,bool isSyncRequest)3080 bool PipelineContext::RequestFocus(const std::string& targetNodeId, bool isSyncRequest)
3081 {
3082     auto rootNode = GetFocusedWindowSceneNode();
3083     if (!rootNode) {
3084         rootNode = rootNode_;
3085     }
3086     CHECK_NULL_RETURN(rootNode, false);
3087     auto focusHub = rootNode->GetFocusHub();
3088     CHECK_NULL_RETURN(focusHub, false);
3089     auto currentFocusChecked = focusHub->RequestFocusImmediatelyById(targetNodeId, isSyncRequest);
3090     if (!isSubPipeline_ || currentFocusChecked) {
3091         return currentFocusChecked;
3092     }
3093     auto parentPipelineBase = parentPipeline_.Upgrade();
3094     CHECK_NULL_RETURN(parentPipelineBase, false);
3095     auto parentPipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentPipelineBase);
3096     CHECK_NULL_RETURN(parentPipelineContext, false);
3097     return parentPipelineContext->RequestFocus(targetNodeId, isSyncRequest);
3098 }
3099 
AddDirtyFocus(const RefPtr<FrameNode> & node)3100 void PipelineContext::AddDirtyFocus(const RefPtr<FrameNode>& node)
3101 {
3102     CHECK_RUN_ON(UI);
3103     CHECK_NULL_VOID(node);
3104     if (node->GetFocusType() == FocusType::NODE) {
3105         dirtyFocusNode_ = WeakClaim(RawPtr(node));
3106     } else {
3107         dirtyFocusScope_ = WeakClaim(RawPtr(node));
3108     }
3109     RequestFrame();
3110 }
3111 
AddDirtyRequestFocus(const RefPtr<FrameNode> & node)3112 void PipelineContext::AddDirtyRequestFocus(const RefPtr<FrameNode>& node)
3113 {
3114     CHECK_RUN_ON(UI);
3115     CHECK_NULL_VOID(node);
3116     dirtyRequestFocusNode_ = WeakPtr<FrameNode>(node);
3117     RequestFrame();
3118 }
3119 
RootLostFocus(BlurReason reason) const3120 void PipelineContext::RootLostFocus(BlurReason reason) const
3121 {
3122     CHECK_NULL_VOID(rootNode_);
3123     auto focusHub = rootNode_->GetFocusHub();
3124     CHECK_NULL_VOID(focusHub);
3125     focusHub->LostFocus(reason);
3126     CHECK_NULL_VOID(overlayManager_);
3127     overlayManager_->HideAllMenus();
3128 }
3129 
ConvertAxisToMouse(const AxisEvent & event)3130 MouseEvent ConvertAxisToMouse(const AxisEvent& event)
3131 {
3132     MouseEvent result;
3133     result.x = event.x;
3134     result.y = event.y;
3135     result.action = MouseAction::MOVE;
3136     result.button = MouseButton::NONE_BUTTON;
3137     result.time = event.time;
3138     result.deviceId = event.deviceId;
3139     result.sourceType = event.sourceType;
3140     result.sourceTool = event.sourceTool;
3141     result.touchEventId = event.touchEventId;
3142     result.pointerEvent = event.pointerEvent;
3143     result.screenX = event.screenX;
3144     result.screenY = event.screenY;
3145     return result;
3146 }
3147 
OnAxisEvent(const AxisEvent & event,const RefPtr<FrameNode> & node)3148 void PipelineContext::OnAxisEvent(const AxisEvent& event, const RefPtr<FrameNode>& node)
3149 {
3150     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3151 
3152     auto dragManager = GetDragDropManager();
3153     if (dragManager && !dragManager->IsDragged()) {
3154         if (event.action == AxisAction::BEGIN) {
3155             isBeforeDragHandleAxis_ = true;
3156             TouchRestrict touchRestrict { TouchRestrict::NONE };
3157             touchRestrict.sourceType = event.sourceType;
3158             touchRestrict.hitTestType = SourceType::TOUCH;
3159             touchRestrict.inputEventType = InputEventType::AXIS;
3160             // If received rotate event, no need to touchtest.
3161             if (!event.isRotationEvent) {
3162                 eventManager_->TouchTest(scaleEvent, node, touchRestrict);
3163             }
3164         }
3165         eventManager_->DispatchTouchEvent(scaleEvent);
3166     } else if (isBeforeDragHandleAxis_ && event.action == AxisAction::END) {
3167         eventManager_->DispatchTouchEvent(scaleEvent);
3168         isBeforeDragHandleAxis_ = false;
3169     }
3170     // when api >= 15, do not block end and cancel action.
3171     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_FIFTEEN)) {
3172         if (event.action != AxisAction::NONE) {
3173             eventManager_->AxisTest(scaleEvent, node);
3174             eventManager_->DispatchAxisEventNG(scaleEvent);
3175         }
3176     } else {
3177         if (event.action == AxisAction::BEGIN || event.action == AxisAction::UPDATE) {
3178             eventManager_->AxisTest(scaleEvent, node);
3179             eventManager_->DispatchAxisEventNG(scaleEvent);
3180         }
3181     }
3182     if (event.action == AxisAction::BEGIN || event.action == AxisAction::CANCEL || event.action == AxisAction::END) {
3183         eventManager_->GetEventTreeRecord(EventTreeType::TOUCH).AddAxis(scaleEvent);
3184     }
3185 
3186     auto mouseEvent = ConvertAxisToMouse(event);
3187     OnMouseEvent(mouseEvent, node);
3188 }
3189 
HasDifferentDirectionGesture() const3190 bool PipelineContext::HasDifferentDirectionGesture() const
3191 {
3192     CHECK_NULL_RETURN(eventManager_, false);
3193     return eventManager_->HasDifferentDirectionGesture();
3194 }
3195 
AddVisibleAreaChangeNode(const int32_t nodeId)3196 void PipelineContext::AddVisibleAreaChangeNode(const int32_t nodeId)
3197 {
3198     onVisibleAreaChangeNodeIds_.emplace(nodeId);
3199 }
3200 
AddVisibleAreaChangeNode(const RefPtr<FrameNode> & node,const std::vector<double> & ratios,const VisibleRatioCallback & callback,bool isUserCallback,bool isCalculateInnerClip)3201 void PipelineContext::AddVisibleAreaChangeNode(const RefPtr<FrameNode>& node,
3202     const std::vector<double>& ratios, const VisibleRatioCallback& callback, bool isUserCallback,
3203     bool isCalculateInnerClip)
3204 {
3205     CHECK_NULL_VOID(node);
3206     VisibleCallbackInfo addInfo;
3207     addInfo.callback = callback;
3208     addInfo.isCurrentVisible = false;
3209     onVisibleAreaChangeNodeIds_.emplace(node->GetId());
3210     if (isUserCallback) {
3211         node->SetVisibleAreaUserCallback(ratios, addInfo);
3212     } else {
3213         node->SetVisibleAreaInnerCallback(ratios, addInfo, isCalculateInnerClip);
3214     }
3215 }
3216 
RemoveVisibleAreaChangeNode(int32_t nodeId)3217 void PipelineContext::RemoveVisibleAreaChangeNode(int32_t nodeId)
3218 {
3219     onVisibleAreaChangeNodeIds_.erase(nodeId);
3220 }
3221 
HandleVisibleAreaChangeEvent(uint64_t nanoTimestamp)3222 void PipelineContext::HandleVisibleAreaChangeEvent(uint64_t nanoTimestamp)
3223 {
3224     ACE_FUNCTION_TRACE();
3225     if (onVisibleAreaChangeNodeIds_.empty()) {
3226         return;
3227     }
3228     auto nodes = FrameNode::GetNodesById(onVisibleAreaChangeNodeIds_);
3229     for (auto&& frameNode : nodes) {
3230         frameNode->TriggerVisibleAreaChangeCallback(nanoTimestamp);
3231     }
3232 }
3233 
AddOnAreaChangeNode(int32_t nodeId)3234 void PipelineContext::AddOnAreaChangeNode(int32_t nodeId)
3235 {
3236     onAreaChangeNodeIds_.emplace(nodeId);
3237     isOnAreaChangeNodesCacheVaild_ = false;
3238 }
3239 
RemoveOnAreaChangeNode(int32_t nodeId)3240 void PipelineContext::RemoveOnAreaChangeNode(int32_t nodeId)
3241 {
3242     onAreaChangeNodeIds_.erase(nodeId);
3243     isOnAreaChangeNodesCacheVaild_ = false;
3244 }
3245 
HasOnAreaChangeNode(int32_t nodeId)3246 bool PipelineContext::HasOnAreaChangeNode(int32_t nodeId)
3247 {
3248     return onAreaChangeNodeIds_.find(nodeId) != onAreaChangeNodeIds_.end();
3249 }
3250 
HandleOnAreaChangeEvent(uint64_t nanoTimestamp)3251 void PipelineContext::HandleOnAreaChangeEvent(uint64_t nanoTimestamp)
3252 {
3253     ACE_FUNCTION_TRACE();
3254     if (onAreaChangeNodeIds_.empty()) {
3255         return;
3256     }
3257     auto nodes = FrameNode::GetNodesById(onAreaChangeNodeIds_);
3258     for (auto&& frameNode : nodes) {
3259         frameNode->TriggerOnAreaChangeCallback(nanoTimestamp);
3260     }
3261     UpdateFormLinkInfos();
3262 }
3263 
UpdateFormLinkInfos()3264 void PipelineContext::UpdateFormLinkInfos()
3265 {
3266     if (formLinkInfoUpdateHandler_ && !formLinkInfoMap_.empty()) {
3267         std::vector<std::string> formLinkInfos;
3268         for (auto iter = formLinkInfoMap_.rbegin(); iter != formLinkInfoMap_.rend(); ++iter) {
3269             auto info = iter->second;
3270             formLinkInfos.push_back(info);
3271         }
3272         formLinkInfoUpdateHandler_(formLinkInfos);
3273     }
3274 }
3275 
OnShow()3276 void PipelineContext::OnShow()
3277 {
3278     CHECK_RUN_ON(UI);
3279     onShow_ = true;
3280     window_->OnShow();
3281     PerfMonitor::GetPerfMonitor()->SetAppForeground(true);
3282     RequestFrame();
3283     FlushWindowStateChangedCallback(true);
3284     AccessibilityEvent event;
3285     event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
3286     event.type = AccessibilityEventType::PAGE_CHANGE;
3287     SendEventToAccessibility(event);
3288 }
3289 
OnHide()3290 void PipelineContext::OnHide()
3291 {
3292     CHECK_RUN_ON(UI);
3293     auto dragDropManager = GetDragDropManager();
3294     if (dragDropManager && dragDropManager->IsItemDragging()) {
3295         dragDropManager->CancelItemDrag();
3296     }
3297     onShow_ = false;
3298     window_->OnHide();
3299     PerfMonitor::GetPerfMonitor()->SetAppForeground(false);
3300     RequestFrame();
3301     OnVirtualKeyboardAreaChange(Rect());
3302     FlushWindowStateChangedCallback(false);
3303     auto rootNode = GetRootElement();
3304     CHECK_NULL_VOID(rootNode);
3305     rootNode->OnAccessibilityEvent(AccessibilityEventType::PAGE_CLOSE);
3306 }
3307 
WindowFocus(bool isFocus)3308 void PipelineContext::WindowFocus(bool isFocus)
3309 {
3310     CHECK_RUN_ON(UI);
3311     onFocus_ = isFocus;
3312     if (!isFocus) {
3313         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window id: %{public}d lost focus.", windowId_);
3314         RestoreDefault();
3315         RootLostFocus(BlurReason::WINDOW_BLUR);
3316         NotifyPopupDismiss();
3317     } else {
3318         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window id: %{public}d get focus.", windowId_);
3319         isWindowHasFocused_ = true;
3320         InputMethodManager::GetInstance()->SetWindowFocus(true);
3321     }
3322     GetOrCreateFocusManager()->WindowFocus(isFocus);
3323     FlushWindowFocusChangedCallback(isFocus);
3324 }
3325 
ContainerModalUnFocus()3326 void PipelineContext::ContainerModalUnFocus()
3327 {
3328     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3329         return;
3330     }
3331     CHECK_NULL_VOID(rootNode_);
3332     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3333     CHECK_NULL_VOID(containerNode);
3334     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3335     CHECK_NULL_VOID(containerPattern);
3336     containerPattern->OnWindowForceUnfocused();
3337 }
3338 
ShowContainerTitle(bool isShow,bool hasDeco,bool needUpdate)3339 void PipelineContext::ShowContainerTitle(bool isShow, bool hasDeco, bool needUpdate)
3340 {
3341     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3342         return;
3343     }
3344     CHECK_NULL_VOID(rootNode_);
3345     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3346     CHECK_NULL_VOID(containerNode);
3347     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3348     CHECK_NULL_VOID(containerPattern);
3349     containerPattern->ShowTitle(isShow, hasDeco, needUpdate);
3350     isShowTitle_ = isShow && hasDeco;
3351 }
3352 
UpdateTitleInTargetPos(bool isShow,int32_t height)3353 void PipelineContext::UpdateTitleInTargetPos(bool isShow, int32_t height)
3354 {
3355     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3356         return;
3357     }
3358     CHECK_NULL_VOID(rootNode_);
3359     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3360     CHECK_NULL_VOID(containerNode);
3361     auto containerPattern = containerNode->GetPattern<ContainerModalPatternEnhance>();
3362     CHECK_NULL_VOID(containerPattern);
3363     containerPattern->UpdateTitleInTargetPos(isShow, height);
3364 }
3365 
SetContainerWindow(bool isShow)3366 void PipelineContext::SetContainerWindow(bool isShow)
3367 {
3368 #ifdef ENABLE_ROSEN_BACKEND
3369     if (!IsJsCard()) {
3370         auto window = GetWindow();
3371         if (window) {
3372             auto rsUIDirector = window->GetRSUIDirector();
3373             if (rsUIDirector) {
3374                 // set container window show state to render service
3375                 rsUIDirector->SetContainerWindow(isShow, density_);
3376             }
3377         }
3378     }
3379 #endif
3380 }
3381 
SetAppBgColor(const Color & color)3382 void PipelineContext::SetAppBgColor(const Color& color)
3383 {
3384     appBgColor_ = color;
3385 #ifdef ENABLE_ROSEN_BACKEND
3386     if (!IsJsCard()) {
3387         auto window = GetWindow();
3388         if (window) {
3389             auto rsUIDirector = window->GetRSUIDirector();
3390             if (rsUIDirector) {
3391                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
3392             }
3393         }
3394     }
3395 #endif
3396     CHECK_NULL_VOID(stageManager_);
3397     auto stage = stageManager_->GetStageNode();
3398     CHECK_NULL_VOID(stage);
3399     auto renderContext = stage->GetRenderContext();
3400     CHECK_NULL_VOID(renderContext);
3401     renderContext->UpdateBackgroundColor(color);
3402 }
3403 
SetAppTitle(const std::string & title)3404 void PipelineContext::SetAppTitle(const std::string& title)
3405 {
3406     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3407         return;
3408     }
3409     CHECK_NULL_VOID(rootNode_);
3410     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3411     CHECK_NULL_VOID(containerNode);
3412     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3413     CHECK_NULL_VOID(containerPattern);
3414     containerPattern->SetAppTitle(title);
3415 }
3416 
SetAppIcon(const RefPtr<PixelMap> & icon)3417 void PipelineContext::SetAppIcon(const RefPtr<PixelMap>& icon)
3418 {
3419     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3420         return;
3421     }
3422     CHECK_NULL_VOID(rootNode_);
3423     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3424     CHECK_NULL_VOID(containerNode);
3425     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3426     CHECK_NULL_VOID(containerPattern);
3427     containerPattern->SetAppIcon(icon);
3428 }
3429 
FlushReload(const ConfigurationChange & configurationChange,bool fullUpdate)3430 void PipelineContext::FlushReload(const ConfigurationChange& configurationChange, bool fullUpdate)
3431 {
3432     AnimationOption option;
3433     const int32_t duration = 400;
3434     option.SetDuration(duration);
3435     option.SetCurve(Curves::FRICTION);
3436     RecycleManager::Notify(configurationChange);
3437     AnimationUtils::Animate(option, [weak = WeakClaim(this), configurationChange,
3438         weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager_)), fullUpdate]() {
3439         auto pipeline = weak.Upgrade();
3440         CHECK_NULL_VOID(pipeline);
3441         if (configurationChange.IsNeedUpdate()) {
3442             auto rootNode = pipeline->GetRootElement();
3443             rootNode->UpdateConfigurationUpdate(configurationChange);
3444             auto overlay = weakOverlayManager.Upgrade();
3445             if (overlay) {
3446                 overlay->ReloadBuilderNodeConfig();
3447             }
3448         }
3449         if (fullUpdate) {
3450             CHECK_NULL_VOID(pipeline->stageManager_);
3451             pipeline->SetIsReloading(true);
3452             pipeline->stageManager_->ReloadStage();
3453             pipeline->SetIsReloading(false);
3454             pipeline->FlushUITasks();
3455         }
3456     });
3457     auto stage = stageManager_->GetStageNode();
3458     CHECK_NULL_VOID(stage);
3459     auto renderContext = stage->GetRenderContext();
3460     CHECK_NULL_VOID(renderContext);
3461     renderContext->UpdateWindowBlur();
3462 }
3463 
Destroy()3464 void PipelineContext::Destroy()
3465 {
3466     CHECK_RUN_ON(UI);
3467     SetDestroyed();
3468     rootNode_->DetachFromMainTree();
3469     std::unordered_set<UINode*> nodeSet;
3470     std::swap(nodeSet, attachedNodeSet_);
3471     for (auto& node : nodeSet) {
3472         node->DetachFromMainTree();
3473     }
3474     rootNode_->FireCustomDisappear();
3475     taskScheduler_->CleanUp();
3476     scheduleTasks_.clear();
3477     dirtyNodes_.clear();
3478     rootNode_.Reset();
3479     accessibilityManagerNG_.Reset();
3480     stageManager_.Reset();
3481     if (overlayManager_) {
3482         overlayManager_->ClearUIExtensionNode();
3483     }
3484     overlayManager_.Reset();
3485     sharedTransitionManager_.Reset();
3486     dragDropManager_.Reset();
3487     TAG_LOGI(AceLogTag::ACE_DRAG, "PipelineContext::Destroy Reset dragDropManager_");
3488     focusManager_.Reset();
3489     selectOverlayManager_.Reset();
3490     fullScreenManager_.Reset();
3491     touchEvents_.clear();
3492     buildFinishCallbacks_.clear();
3493     onWindowStateChangedCallbacks_.clear();
3494     onWindowFocusChangedCallbacks_.clear();
3495     nodesToNotifyMemoryLevel_.clear();
3496     dirtyFocusNode_.Reset();
3497     dirtyFocusScope_.Reset();
3498     needRenderNode_.clear();
3499     dirtyRequestFocusNode_.Reset();
3500     if (textFieldManager_ && textFieldManager_->GetImeShow()) {
3501         InputMethodManager::GetInstance()->CloseKeyboardInPipelineDestroy();
3502     }
3503 #ifdef WINDOW_SCENE_SUPPORTED
3504     uiExtensionManager_.Reset();
3505 #endif
3506     PipelineBase::Destroy();
3507 }
3508 
AddBuildFinishCallBack(std::function<void ()> && callback)3509 void PipelineContext::AddBuildFinishCallBack(std::function<void()>&& callback)
3510 {
3511     buildFinishCallbacks_.emplace_back(std::move(callback));
3512 }
3513 
AddWindowStateChangedCallback(int32_t nodeId)3514 void PipelineContext::AddWindowStateChangedCallback(int32_t nodeId)
3515 {
3516     if (!CheckThreadSafe()) {
3517         LOGW("AddWindowStateChangedCallback doesn't run on UI thread!");
3518     }
3519     onWindowStateChangedCallbacks_.emplace(nodeId);
3520 }
3521 
RemoveWindowStateChangedCallback(int32_t nodeId)3522 void PipelineContext::RemoveWindowStateChangedCallback(int32_t nodeId)
3523 {
3524     if (!CheckThreadSafe()) {
3525         LOGW("RemoveWindowStateChangedCallback doesn't run on UI thread!");
3526     }
3527     onWindowStateChangedCallbacks_.erase(nodeId);
3528 }
3529 
FlushWindowStateChangedCallback(bool isShow)3530 void PipelineContext::FlushWindowStateChangedCallback(bool isShow)
3531 {
3532     if (!CheckThreadSafe()) {
3533         LOGW("FlushWindowStateChangedCallback doesn't run on UI thread!");
3534     }
3535     auto iter = onWindowStateChangedCallbacks_.begin();
3536     while (iter != onWindowStateChangedCallbacks_.end()) {
3537         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
3538         if (!node) {
3539             iter = onWindowStateChangedCallbacks_.erase(iter);
3540         } else {
3541             if (isShow) {
3542                 node->OnWindowShow();
3543             } else {
3544                 node->OnWindowHide();
3545             }
3546             ++iter;
3547         }
3548     }
3549     HandleVisibleAreaChangeEvent(GetTimeFromExternalTimer());
3550     HandleSubwindow(isShow);
3551 }
3552 
AddWindowFocusChangedCallback(int32_t nodeId)3553 void PipelineContext::AddWindowFocusChangedCallback(int32_t nodeId)
3554 {
3555     onWindowFocusChangedCallbacks_.emplace(nodeId);
3556 }
3557 
RemoveWindowFocusChangedCallback(int32_t nodeId)3558 void PipelineContext::RemoveWindowFocusChangedCallback(int32_t nodeId)
3559 {
3560     onWindowFocusChangedCallbacks_.erase(nodeId);
3561 }
3562 
FlushWindowFocusChangedCallback(bool isFocus)3563 void PipelineContext::FlushWindowFocusChangedCallback(bool isFocus)
3564 {
3565     auto iter = onWindowFocusChangedCallbacks_.begin();
3566     while (iter != onWindowFocusChangedCallbacks_.end()) {
3567         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
3568         if (!node) {
3569             iter = onWindowFocusChangedCallbacks_.erase(iter);
3570         } else {
3571             if (isFocus) {
3572                 node->OnWindowFocused();
3573             } else {
3574                 node->OnWindowUnfocused();
3575             }
3576             ++iter;
3577         }
3578     }
3579 }
3580 
AddWindowSizeChangeCallback(int32_t nodeId)3581 void PipelineContext::AddWindowSizeChangeCallback(int32_t nodeId)
3582 {
3583     onWindowSizeChangeCallbacks_.emplace_back(nodeId);
3584 }
3585 
RemoveWindowSizeChangeCallback(int32_t nodeId)3586 void PipelineContext::RemoveWindowSizeChangeCallback(int32_t nodeId)
3587 {
3588     onWindowSizeChangeCallbacks_.remove(nodeId);
3589 }
3590 
AddNavigationNode(int32_t pageId,WeakPtr<UINode> navigationNode)3591 void PipelineContext::AddNavigationNode(int32_t pageId, WeakPtr<UINode> navigationNode)
3592 {
3593     CHECK_RUN_ON(UI);
3594     pageToNavigationNodes_[pageId].push_back(navigationNode);
3595 }
3596 
RemoveNavigationNode(int32_t pageId,int32_t nodeId)3597 void PipelineContext::RemoveNavigationNode(int32_t pageId, int32_t nodeId)
3598 {
3599     CHECK_RUN_ON(UI);
3600     auto it = pageToNavigationNodes_.find(pageId);
3601     if (it != pageToNavigationNodes_.end() && !it->second.empty()) {
3602         for (auto iter = it->second.begin(); iter != it->second.end();) {
3603             auto navigationNode = AceType::DynamicCast<NavigationGroupNode>((*iter).Upgrade());
3604             if (navigationNode && navigationNode->GetId() == nodeId) {
3605                 iter = it->second.erase(iter);
3606             } else {
3607                 iter++;
3608             }
3609         }
3610     }
3611 }
3612 
FirePageChanged(int32_t pageId,bool isOnShow)3613 void PipelineContext::FirePageChanged(int32_t pageId, bool isOnShow)
3614 {
3615     CHECK_RUN_ON(UI);
3616     for (auto navigationNode : pageToNavigationNodes_[pageId]) {
3617         NavigationPattern::FireNavigationChange(navigationNode.Upgrade(), isOnShow, true);
3618     }
3619 }
3620 
FlushWindowSizeChangeCallback(int32_t width,int32_t height,WindowSizeChangeReason type)3621 void PipelineContext::FlushWindowSizeChangeCallback(int32_t width, int32_t height, WindowSizeChangeReason type)
3622 {
3623     auto iter = onWindowSizeChangeCallbacks_.begin();
3624     while (iter != onWindowSizeChangeCallbacks_.end()) {
3625         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
3626         if (!node) {
3627             iter = onWindowSizeChangeCallbacks_.erase(iter);
3628         } else {
3629             node->OnWindowSizeChanged(width, height, type);
3630             ++iter;
3631         }
3632     }
3633 }
3634 
RequireSummary()3635 void PipelineContext::RequireSummary()
3636 {
3637     auto manager = GetDragDropManager();
3638     if (!manager) {
3639         TAG_LOGW(AceLogTag::ACE_DRAG, "require summary, dragDropManager is null");
3640         return;
3641     }
3642     manager->RequireSummary();
3643 }
3644 
OnDragEvent(const DragPointerEvent & pointerEvent,DragEventAction action,const RefPtr<NG::FrameNode> & node)3645 void PipelineContext::OnDragEvent(const DragPointerEvent& pointerEvent, DragEventAction action,
3646     const RefPtr<NG::FrameNode>& node)
3647 {
3648     auto manager = GetDragDropManager();
3649     CHECK_NULL_VOID(manager);
3650     std::string extraInfo;
3651     auto container = Container::Current();
3652     if (container && container->IsScenceBoardWindow()) {
3653         if (!manager->IsDragged() && manager->IsWindowConsumed()) {
3654             manager->SetIsWindowConsumed(false);
3655             return;
3656         }
3657     }
3658     if (action == DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER) {
3659         manager->RequireSummary();
3660         manager->OnDragStart(pointerEvent.GetPoint());
3661         return;
3662     }
3663     if (action == DragEventAction::DRAG_EVENT_OUT) {
3664         manager->OnDragMoveOut(pointerEvent);
3665         manager->ClearSummary();
3666         manager->ClearExtraInfo();
3667         manager->SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
3668         return;
3669     }
3670 
3671     if (action == DragEventAction::DRAG_EVENT_START) {
3672         manager->ResetPreTargetFrameNode(GetInstanceId());
3673         manager->RequireSummaryIfNecessary(pointerEvent);
3674         manager->SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
3675         TAG_LOGI(AceLogTag::ACE_DRAG, "start drag, current windowId is %{public}d", container->GetWindowId());
3676     }
3677     extraInfo = manager->GetExtraInfo();
3678     if (action == DragEventAction::DRAG_EVENT_END) {
3679         manager->OnDragEnd(pointerEvent, extraInfo, node);
3680         return;
3681     }
3682     if (action == DragEventAction::DRAG_EVENT_MOVE) {
3683         manager->DoDragMoveAnimate(pointerEvent);
3684     }
3685     manager->OnDragMove(pointerEvent, extraInfo, node);
3686 }
3687 
AddNodesToNotifyMemoryLevel(int32_t nodeId)3688 void PipelineContext::AddNodesToNotifyMemoryLevel(int32_t nodeId)
3689 {
3690     nodesToNotifyMemoryLevel_.emplace_back(nodeId);
3691 }
3692 
RemoveNodesToNotifyMemoryLevel(int32_t nodeId)3693 void PipelineContext::RemoveNodesToNotifyMemoryLevel(int32_t nodeId)
3694 {
3695     nodesToNotifyMemoryLevel_.remove(nodeId);
3696 }
3697 
NotifyMemoryLevel(int32_t level)3698 void PipelineContext::NotifyMemoryLevel(int32_t level)
3699 {
3700     auto iter = nodesToNotifyMemoryLevel_.begin();
3701     while (iter != nodesToNotifyMemoryLevel_.end()) {
3702         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
3703         if (!node) {
3704             iter = nodesToNotifyMemoryLevel_.erase(iter);
3705         } else {
3706             node->OnNotifyMemoryLevel(level);
3707             ++iter;
3708         }
3709     }
3710 }
AddPredictTask(PredictTask && task)3711 void PipelineContext::AddPredictTask(PredictTask&& task)
3712 {
3713     taskScheduler_->AddPredictTask(std::move(task));
3714     RequestFrame();
3715 }
3716 
AddFrameCallback(FrameCallbackFunc && frameCallbackFunc,FrameCallbackFunc && idleCallbackFunc,int64_t delayMillis)3717 void PipelineContext::AddFrameCallback(FrameCallbackFunc&& frameCallbackFunc, FrameCallbackFunc&& idleCallbackFunc,
3718     int64_t delayMillis)
3719 {
3720     if (delayMillis <= 0) {
3721         if (frameCallbackFunc != nullptr) {
3722             frameCallbackFuncs_.emplace_back(std::move(frameCallbackFunc));
3723         }
3724         if (idleCallbackFunc != nullptr) {
3725             idleCallbackFuncs_.emplace_back(std::move(idleCallbackFunc));
3726         }
3727         RequestFrame();
3728         return;
3729     }
3730     auto taskScheduler = GetTaskExecutor();
3731     CHECK_NULL_VOID(taskScheduler);
3732     if (frameCallbackFunc != nullptr) {
3733         taskScheduler->PostDelayedTask(
3734             [weak = WeakClaim(this), callbackFunc = std::move(frameCallbackFunc)]() -> void {
3735                 auto pipeline = weak.Upgrade();
3736                 CHECK_NULL_VOID(pipeline);
3737                 auto callback = const_cast<FrameCallbackFunc&>(callbackFunc);
3738                 pipeline->frameCallbackFuncs_.emplace_back(std::move(callback));
3739                 pipeline->RequestFrame();
3740             },
3741             TaskExecutor::TaskType::UI, delayMillis, "ArkUIPostFrameCallbackFuncDelayed");
3742     }
3743     if (idleCallbackFunc != nullptr) {
3744         taskScheduler->PostDelayedTask(
3745             [weak = WeakClaim(this), callbackFunc = std::move(idleCallbackFunc)]() -> void {
3746                 auto pipeline = weak.Upgrade();
3747                 CHECK_NULL_VOID(pipeline);
3748                 auto callback = const_cast<FrameCallbackFunc&>(callbackFunc);
3749                 pipeline->idleCallbackFuncs_.emplace_back(std::move(callback));
3750                 pipeline->RequestFrame();
3751             },
3752             TaskExecutor::TaskType::UI, delayMillis, "ArkUIPostIdleCallbackFuncDelayed");
3753     }
3754 }
3755 
TriggerIdleCallback(int64_t deadline)3756 void PipelineContext::TriggerIdleCallback(int64_t deadline)
3757 {
3758     if (idleCallbackFuncs_.empty()) {
3759         return;
3760     }
3761     int64_t currentTime = GetSysTimestamp();
3762     if (deadline - currentTime < MIN_IDLE_TIME) {
3763         RequestFrame();
3764         return;
3765     }
3766     decltype(idleCallbackFuncs_) tasks(std::move(idleCallbackFuncs_));
3767     for (const auto& idleCallbackFunc : tasks) {
3768         idleCallbackFunc(deadline - currentTime);
3769         currentTime = GetSysTimestamp();
3770     }
3771 }
3772 
OnIdle(int64_t deadline)3773 void PipelineContext::OnIdle(int64_t deadline)
3774 {
3775     int64_t currentTime = GetSysTimestamp();
3776     if (deadline == 0) {
3777         int64_t lastTaskEndTimestamp = window_->GetLastVsyncEndTimestamp();
3778         if (eventManager_) {
3779             lastTaskEndTimestamp = std::max(lastTaskEndTimestamp, eventManager_->GetLastTouchEventEndTimestamp());
3780         }
3781         if (lastTaskEndTimestamp > 0 && currentTime > lastTaskEndTimestamp
3782             && currentTime - lastTaskEndTimestamp > VSYNC_PERIOD_COUNT * window_->GetVSyncPeriod()) {
3783             auto frontend = weakFrontend_.Upgrade();
3784             if (frontend) {
3785                 frontend->NotifyUIIdle();
3786             }
3787         }
3788     }
3789     if (deadline == 0 || isWindowAnimation_) {
3790         canUseLongPredictTask_ = false;
3791         return;
3792     }
3793     if (canUseLongPredictTask_) {
3794         // check new incoming event after vsync.
3795         if (!touchEvents_.empty()) {
3796             canUseLongPredictTask_ = false;
3797         }
3798     }
3799     CHECK_RUN_ON(UI);
3800     ACE_SCOPED_TRACE("OnIdle, targettime:%" PRId64 "", deadline);
3801     taskScheduler_->FlushPredictTask(deadline - TIME_THRESHOLD, canUseLongPredictTask_);
3802     canUseLongPredictTask_ = false;
3803     if (currentTime < deadline) {
3804         ElementRegister::GetInstance()->CallJSCleanUpIdleTaskFunc();
3805     }
3806     TriggerIdleCallback(deadline);
3807 }
3808 
Finish(bool) const3809 void PipelineContext::Finish(bool /* autoFinish */) const
3810 {
3811     CHECK_RUN_ON(UI);
3812     if (finishEventHandler_) {
3813         finishEventHandler_();
3814     }
3815 }
3816 
AddAfterLayoutTask(std::function<void ()> && task,bool isFlushInImplicitAnimationTask)3817 void PipelineContext::AddAfterLayoutTask(std::function<void()>&& task, bool isFlushInImplicitAnimationTask)
3818 {
3819     taskScheduler_->AddAfterLayoutTask(std::move(task), isFlushInImplicitAnimationTask);
3820 }
3821 
AddPersistAfterLayoutTask(std::function<void ()> && task)3822 void PipelineContext::AddPersistAfterLayoutTask(std::function<void()>&& task)
3823 {
3824     taskScheduler_->AddPersistAfterLayoutTask(std::move(task));
3825 }
3826 
AddAfterRenderTask(std::function<void ()> && task)3827 void PipelineContext::AddAfterRenderTask(std::function<void()>&& task)
3828 {
3829     taskScheduler_->AddAfterRenderTask(std::move(task));
3830 }
3831 
AddSafeAreaPaddingProcessTask(FrameNode * node)3832 void PipelineContext::AddSafeAreaPaddingProcessTask(FrameNode* node)
3833 {
3834     taskScheduler_->AddSafeAreaPaddingProcessTask(node);
3835 }
3836 
RemoveSafeAreaPaddingProcessTask(FrameNode * node)3837 void PipelineContext::RemoveSafeAreaPaddingProcessTask(FrameNode* node)
3838 {
3839     taskScheduler_->RemoveSafeAreaPaddingProcessTask(node);
3840 }
3841 
FlushSafeAreaPaddingProcess()3842 void PipelineContext::FlushSafeAreaPaddingProcess()
3843 {
3844     taskScheduler_->FlushSafeAreaPaddingProcess();
3845 }
3846 
RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)3847 void PipelineContext::RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)
3848 {
3849     auto child = nodeInfo->GetChild();
3850     while (child->IsValid()) {
3851         auto key = child->GetKey();
3852         auto value = child->GetString();
3853         restoreNodeInfo_.try_emplace(StringUtils::StringToInt(key), value);
3854         child = child->GetNext();
3855     }
3856 }
3857 
GetStoredNodeInfo()3858 std::unique_ptr<JsonValue> PipelineContext::GetStoredNodeInfo()
3859 {
3860     auto jsonNodeInfo = JsonUtil::Create(true);
3861     auto iter = storeNode_.begin();
3862     while (iter != storeNode_.end()) {
3863         auto node = (iter->second).Upgrade();
3864         if (node) {
3865             std::string info = node->ProvideRestoreInfo();
3866             if (!info.empty()) {
3867                 jsonNodeInfo->Put(std::to_string(iter->first).c_str(), info.c_str());
3868             }
3869         }
3870         ++iter;
3871     }
3872     return jsonNodeInfo;
3873 }
3874 
StoreNode(int32_t restoreId,const WeakPtr<FrameNode> & node)3875 void PipelineContext::StoreNode(int32_t restoreId, const WeakPtr<FrameNode>& node)
3876 {
3877     auto ret = storeNode_.try_emplace(restoreId, node);
3878     if (!ret.second) {
3879         storeNode_[restoreId] = node;
3880     }
3881 }
3882 
GetRestoreInfo(int32_t restoreId,std::string & restoreInfo)3883 bool PipelineContext::GetRestoreInfo(int32_t restoreId, std::string& restoreInfo)
3884 {
3885     auto iter = restoreNodeInfo_.find(restoreId);
3886     if (iter != restoreNodeInfo_.end()) {
3887         restoreInfo = iter->second;
3888         restoreNodeInfo_.erase(iter);
3889         return true;
3890     }
3891     return false;
3892 }
3893 
SetContainerButtonHide(bool hideSplit,bool hideMaximize,bool hideMinimize,bool hideClose)3894 void PipelineContext::SetContainerButtonHide(bool hideSplit, bool hideMaximize, bool hideMinimize, bool hideClose)
3895 {
3896     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3897         LOGW("Set app icon failed, Window modal is not container.");
3898         return;
3899     }
3900     CHECK_NULL_VOID(rootNode_);
3901     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3902     CHECK_NULL_VOID(containerNode);
3903     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3904     CHECK_NULL_VOID(containerPattern);
3905     containerPattern->SetContainerButtonHide(hideSplit, hideMaximize, hideMinimize, hideClose);
3906 }
3907 
EnableContainerModalGesture(bool isEnable)3908 void PipelineContext::EnableContainerModalGesture(bool isEnable)
3909 {
3910     CHECK_NULL_VOID(rootNode_);
3911     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3912     if (!containerNode) {
3913         LOGW("container node is null when set event on gesture row");
3914         return;
3915     }
3916     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3917     CHECK_NULL_VOID(containerPattern);
3918     containerPattern->EnableContainerModalGesture(isEnable);
3919 }
3920 
GetContainerFloatingTitleVisible()3921 bool PipelineContext::GetContainerFloatingTitleVisible()
3922 {
3923     CHECK_NULL_RETURN(rootNode_, false);
3924     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3925     CHECK_NULL_RETURN(containerNode, false);
3926     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3927     CHECK_NULL_RETURN(containerPattern, false);
3928     return containerPattern->GetFloatingTitleVisible();
3929 }
3930 
GetContainerCustomTitleVisible()3931 bool PipelineContext::GetContainerCustomTitleVisible()
3932 {
3933     CHECK_NULL_RETURN(rootNode_, false);
3934     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3935     CHECK_NULL_RETURN(containerNode, false);
3936     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3937     CHECK_NULL_RETURN(containerPattern, false);
3938     return containerPattern->GetCustomTitleVisible();
3939 }
3940 
GetContainerControlButtonVisible()3941 bool PipelineContext::GetContainerControlButtonVisible()
3942 {
3943     CHECK_NULL_RETURN(rootNode_, false);
3944     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3945     CHECK_NULL_RETURN(containerNode, false);
3946     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3947     CHECK_NULL_RETURN(containerPattern, false);
3948     return containerPattern->GetControlButtonVisible();
3949 }
3950 
AddFontNodeNG(const WeakPtr<UINode> & node)3951 void PipelineContext::AddFontNodeNG(const WeakPtr<UINode>& node)
3952 {
3953     if (fontManager_) {
3954         fontManager_->AddFontNodeNG(node);
3955     }
3956 }
3957 
RemoveFontNodeNG(const WeakPtr<UINode> & node)3958 void PipelineContext::RemoveFontNodeNG(const WeakPtr<UINode>& node)
3959 {
3960     if (fontManager_) {
3961         fontManager_->RemoveFontNodeNG(node);
3962     }
3963 }
3964 
SetWindowSceneConsumed(bool isConsumed)3965 void PipelineContext::SetWindowSceneConsumed(bool isConsumed)
3966 {
3967     isWindowSceneConsumed_ = isConsumed;
3968 }
3969 
IsWindowSceneConsumed()3970 bool PipelineContext::IsWindowSceneConsumed()
3971 {
3972     return isWindowSceneConsumed_;
3973 }
3974 
SetCloseButtonStatus(bool isEnabled)3975 void PipelineContext::SetCloseButtonStatus(bool isEnabled)
3976 {
3977     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3978         return;
3979     }
3980     CHECK_NULL_VOID(rootNode_);
3981     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3982     CHECK_NULL_VOID(containerNode);
3983     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3984     CHECK_NULL_VOID(containerPattern);
3985     containerPattern->SetCloseButtonStatus(isEnabled);
3986 }
3987 
AnimateOnSafeAreaUpdate()3988 void PipelineContext::AnimateOnSafeAreaUpdate()
3989 {
3990     // complete other layout tasks before animation
3991     FlushUITasks();
3992     AnimationOption option;
3993     option.SetCurve(safeAreaManager_->GetSafeAreaCurve());
3994     AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
3995         auto self = weak.Upgrade();
3996         CHECK_NULL_VOID(self);
3997         self->SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_AVOID_AREA);
3998         self->FlushUITasks();
3999     });
4000 }
4001 
HandleSubwindow(bool isShow)4002 void PipelineContext::HandleSubwindow(bool isShow)
4003 {
4004     // When the main window is applied to the background,
4005     // there are sub windows that do not immediately hide, such as Toast floating window
4006     if (!isShow) {
4007         overlayManager_->ClearToastInSubwindow();
4008     }
4009 }
4010 
AddIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node,const std::function<void (bool)> & eventCallback)4011 void PipelineContext::AddIsFocusActiveUpdateEvent(
4012     const RefPtr<FrameNode>& node, const std::function<void(bool)>& eventCallback)
4013 {
4014     CHECK_NULL_VOID(node);
4015     isFocusActiveUpdateEvents_.insert_or_assign(node->GetId(), eventCallback);
4016 }
4017 
RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node)4018 void PipelineContext::RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode>& node)
4019 {
4020     CHECK_NULL_VOID(node);
4021     auto iter = isFocusActiveUpdateEvents_.find(node->GetId());
4022     if (iter != isFocusActiveUpdateEvents_.end()) {
4023         isFocusActiveUpdateEvents_.erase(iter);
4024     }
4025 }
4026 
GetNavigationController(const std::string & id)4027 std::shared_ptr<NavigationController> PipelineContext::GetNavigationController(const std::string& id)
4028 {
4029     std::lock_guard lock(navigationMutex_);
4030     auto iter = navigationNodes_.find(id);
4031     if (iter == navigationNodes_.end()) {
4032         return nullptr;
4033     }
4034 
4035     auto navigationGroupNode = iter->second.Upgrade();
4036     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
4037 
4038     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
4039     CHECK_NULL_RETURN(navigationPattern, nullptr);
4040     return navigationPattern->GetNavigationController();
4041 }
4042 
AddOrReplaceNavigationNode(const std::string & id,const WeakPtr<FrameNode> & node)4043 void PipelineContext::AddOrReplaceNavigationNode(const std::string& id, const WeakPtr<FrameNode>& node)
4044 {
4045     std::lock_guard lock(navigationMutex_);
4046     auto frameNode = node.Upgrade();
4047     CHECK_NULL_VOID(frameNode);
4048     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
4049     CHECK_NULL_VOID(navigationGroupNode);
4050     auto oldId = navigationGroupNode->GetCurId();
4051     if (!oldId.empty() && navigationNodes_.find(oldId) != navigationNodes_.end()) {
4052         navigationNodes_.erase(oldId);
4053     }
4054 
4055     if (!id.empty()) {
4056         navigationNodes_[id] = node;
4057     }
4058 }
4059 
DeleteNavigationNode(const std::string & id)4060 void PipelineContext::DeleteNavigationNode(const std::string& id)
4061 {
4062     std::lock_guard lock(navigationMutex_);
4063     if (!id.empty() && navigationNodes_.find(id) != navigationNodes_.end()) {
4064         navigationNodes_.erase(id);
4065     }
4066 }
4067 
SetCursor(int32_t cursorValue)4068 void PipelineContext::SetCursor(int32_t cursorValue)
4069 {
4070     if (cursorValue >= 0 && cursorValue <= static_cast<int32_t>(MouseFormat::RUNNING)) {
4071         auto mouseFormat = static_cast<MouseFormat>(cursorValue);
4072         auto mouseStyleManager = eventManager_->GetMouseStyleManager();
4073         CHECK_NULL_VOID(mouseStyleManager);
4074         mouseStyleManager->SetUserSetCursor(true);
4075         ChangeMouseStyle(-1, mouseFormat, GetFocusWindowId(),
4076             false, MouseStyleChangeReason::USER_SET_MOUSESTYLE);
4077     }
4078 }
4079 
RestoreDefault(int32_t windowId)4080 void PipelineContext::RestoreDefault(int32_t windowId)
4081 {
4082     ChangeMouseStyle(-1, MouseFormat::DEFAULT, windowId > 0 ? windowId : GetFocusWindowId(),
4083         false, MouseStyleChangeReason::USER_SET_MOUSESTYLE);
4084     auto mouseStyleManager = eventManager_->GetMouseStyleManager();
4085     CHECK_NULL_VOID(mouseStyleManager);
4086     mouseStyleManager->SetUserSetCursor(false);
4087 }
4088 
GetCurrentExtraInfo()4089 std::string PipelineContext::GetCurrentExtraInfo()
4090 {
4091     auto node = activeNode_.Upgrade();
4092     return node ? node->GetCurrentCustomNodeInfo() : std::string();
4093 }
4094 
OpenFrontendAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)4095 void PipelineContext::OpenFrontendAnimation(
4096     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
4097 {
4098     // push false to show we already open a animation closure.
4099     pendingFrontendAnimation_.push(false);
4100 
4101     // flush ui tasks before open animation closure.
4102     if (!isReloading_ && !IsLayouting()) {
4103         FlushUITasks();
4104     }
4105     auto wrapFinishCallback = GetWrappedAnimationCallback(finishCallback);
4106     if (IsFormRender()) {
4107         SetIsFormAnimation(true);
4108         if (!IsFormAnimationFinishCallback()) {
4109             SetFormAnimationStartTime(GetMicroTickCount());
4110         }
4111     }
4112     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
4113 }
4114 
CloseFrontendAnimation()4115 void PipelineContext::CloseFrontendAnimation()
4116 {
4117     if (pendingFrontendAnimation_.empty()) {
4118         return;
4119     }
4120 
4121     if (pendingFrontendAnimation_.top()) {
4122         if (!isReloading_ && !IsLayouting()) {
4123             FlushUITasks();
4124         } else if (IsLayouting()) {
4125             TAG_LOGW(AceLogTag::ACE_ANIMATION,
4126                 "IsLayouting, CloseFrontendAnimation has tasks not flushed, maybe some layout animation not generated");
4127         }
4128     }
4129     if (!pendingFrontendAnimation_.empty()) {
4130         pendingFrontendAnimation_.pop();
4131     }
4132     AnimationUtils::CloseImplicitAnimation();
4133 }
4134 
SetContainerModalTitleVisible(bool customTitleSettedShow,bool floatingTitleSettedShow)4135 void PipelineContext::SetContainerModalTitleVisible(bool customTitleSettedShow, bool floatingTitleSettedShow)
4136 {
4137     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4138         return;
4139     }
4140     CHECK_NULL_VOID(rootNode_);
4141     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4142     CHECK_NULL_VOID(containerNode);
4143     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4144     CHECK_NULL_VOID(containerPattern);
4145     containerPattern->SetContainerModalTitleVisible(customTitleSettedShow, floatingTitleSettedShow);
4146     customTitleSettedShow_ = customTitleSettedShow;
4147 }
4148 
SetContainerModalTitleHeight(int32_t height)4149 void PipelineContext::SetContainerModalTitleHeight(int32_t height)
4150 {
4151     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4152         return;
4153     }
4154     CHECK_NULL_VOID(rootNode_);
4155     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4156     CHECK_NULL_VOID(containerNode);
4157     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4158     CHECK_NULL_VOID(containerPattern);
4159     containerPattern->SetContainerModalTitleHeight(height);
4160 }
4161 
GetContainerModalTitleHeight()4162 int32_t PipelineContext::GetContainerModalTitleHeight()
4163 {
4164     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4165         return -1;
4166     }
4167     CHECK_NULL_RETURN(rootNode_, -1);
4168     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4169     CHECK_NULL_RETURN(containerNode, -1);
4170     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4171     CHECK_NULL_RETURN(containerPattern, -1);
4172     return containerPattern->GetContainerModalTitleHeight();
4173 }
4174 
GetContainerModalNode()4175 RefPtr<FrameNode> PipelineContext::GetContainerModalNode()
4176 {
4177     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4178         return nullptr;
4179     }
4180     CHECK_NULL_RETURN(rootNode_, nullptr);
4181     return AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4182 }
4183 
DoKeyboardAvoidAnimate(const KeyboardAnimationConfig & keyboardAnimationConfig,float keyboardHeight,const std::function<void ()> & func)4184 void PipelineContext::DoKeyboardAvoidAnimate(const KeyboardAnimationConfig& keyboardAnimationConfig,
4185     float keyboardHeight, const std::function<void()>& func)
4186 {
4187     if (isDoKeyboardAvoidAnimate_) {
4188         AnimationOption option = AnimationUtil::CreateKeyboardAnimationOption(keyboardAnimationConfig, keyboardHeight);
4189         Animate(option, option.GetCurve(), func);
4190     } else {
4191         func();
4192     }
4193 }
4194 
GetCustomTitleHeight()4195 Dimension PipelineContext::GetCustomTitleHeight()
4196 {
4197     auto containerModal = GetContainerModalNode();
4198     CHECK_NULL_RETURN(containerModal, Dimension());
4199     return containerModal->GetPattern<ContainerModalPattern>()->GetCustomTitleHeight();
4200 }
4201 
GetContainerModalButtonsRect(RectF & containerModal,RectF & buttons)4202 bool PipelineContext::GetContainerModalButtonsRect(RectF& containerModal, RectF& buttons)
4203 {
4204     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4205         return false;
4206     }
4207     CHECK_NULL_RETURN(rootNode_, false);
4208     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4209     CHECK_NULL_RETURN(containerNode, false);
4210     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4211     CHECK_NULL_RETURN(containerPattern, false);
4212     return containerPattern->GetContainerModalButtonsRect(containerModal, buttons);
4213 }
4214 
SubscribeContainerModalButtonsRectChange(std::function<void (RectF & containerModal,RectF & buttons)> && callback)4215 void PipelineContext::SubscribeContainerModalButtonsRectChange(
4216     std::function<void(RectF& containerModal, RectF& buttons)>&& callback)
4217 {
4218     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4219         return;
4220     }
4221     CHECK_NULL_VOID(rootNode_);
4222     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4223     CHECK_NULL_VOID(containerNode);
4224     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4225     CHECK_NULL_VOID(containerPattern);
4226     containerPattern->SubscribeContainerModalButtonsRectChange(std::move(callback));
4227 }
4228 
GetWindowPaintRectWithoutMeasureAndLayout(RectInt & rect)4229 void PipelineContext::GetWindowPaintRectWithoutMeasureAndLayout(RectInt& rect)
4230 {
4231     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4232         return;
4233     }
4234     CHECK_NULL_VOID(rootNode_);
4235     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
4236     CHECK_NULL_VOID(containerNode);
4237     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4238     CHECK_NULL_VOID(containerPattern);
4239     containerPattern->GetWindowPaintRectWithoutMeasureAndLayout(rect);
4240 }
4241 
IsDragging() const4242 bool PipelineContext::IsDragging() const
4243 {
4244     if (!dragDropManager_) {
4245         return false;
4246     }
4247     bool isDragging = dragDropManager_->IsDragging();
4248     isDragging = (isDragging || dragDropManager_->IsMSDPDragging());
4249     return isDragging;
4250 }
4251 
SetIsDragging(bool isDragging)4252 void PipelineContext::SetIsDragging(bool isDragging)
4253 {
4254     if (!eventManager_) {
4255         return;
4256     }
4257     eventManager_->SetIsDragging(isDragging);
4258 }
4259 
ResetDragging()4260 void PipelineContext::ResetDragging()
4261 {
4262     CHECK_NULL_VOID(dragDropManager_);
4263     dragDropManager_->ResetDragging();
4264 }
4265 
GetPostEventManager()4266 const RefPtr<PostEventManager>& PipelineContext::GetPostEventManager()
4267 {
4268     return postEventManager_;
4269 }
4270 
GetSerializedGesture() const4271 const SerializedGesture& PipelineContext::GetSerializedGesture() const
4272 {
4273     return serializedGesture_;
4274 }
4275 
PrintVsyncInfoIfNeed() const4276 bool PipelineContext::PrintVsyncInfoIfNeed() const
4277 {
4278     if (dumpFrameInfos_.empty()) {
4279         return false;
4280     }
4281     auto lastFrameInfo = dumpFrameInfos_.back();
4282     const uint64_t timeout = 1000000000; // unit is ns, 1s
4283     if (lastFrameInfo.frameRecvTime_ < window_->GetLastRequestVsyncTime() &&
4284         static_cast<uint64_t>(GetSysTimestamp()) - window_->GetLastRequestVsyncTime() >= timeout) {
4285         LOGW("lastRequestVsyncTime is %{public}" PRIu64 ", now time is %{public}" PRId64
4286              ", timeout, window foreground:%{public}d, lastReceiveVsync info:%{public}s",
4287             window_->GetLastRequestVsyncTime(), GetSysTimestamp(), onShow_, lastFrameInfo.GetTimeInfo().c_str());
4288         return true;
4289     }
4290     return false;
4291 }
4292 
StopWindowAnimation()4293 void PipelineContext::StopWindowAnimation()
4294 {
4295     isWindowAnimation_ = false;
4296     if (taskScheduler_ && !taskScheduler_->IsPredictTaskEmpty()) {
4297         RequestFrame();
4298     }
4299 }
4300 
AddSyncGeometryNodeTask(std::function<void ()> && task)4301 void PipelineContext::AddSyncGeometryNodeTask(std::function<void()>&& task)
4302 {
4303     taskScheduler_->AddSyncGeometryNodeTask(std::move(task));
4304 }
4305 
FlushSyncGeometryNodeTasks()4306 void PipelineContext::FlushSyncGeometryNodeTasks()
4307 {
4308     taskScheduler_->FlushSyncGeometryNodeTasks();
4309 }
4310 
SetUIExtensionImeShow(bool imeShow)4311 void PipelineContext::SetUIExtensionImeShow(bool imeShow)
4312 {
4313     textFieldManager_->SetUIExtensionImeShow(imeShow);
4314 }
4315 
SetOverlayNodePositions(std::vector<Ace::RectF> rects)4316 void PipelineContext::SetOverlayNodePositions(std::vector<Ace::RectF> rects)
4317 {
4318     overlayNodePositions_ = rects;
4319 }
4320 
SetCallBackNode(const WeakPtr<NG::FrameNode> & node)4321 void PipelineContext::SetCallBackNode(const WeakPtr<NG::FrameNode>& node)
4322 {
4323     auto frameNode = node.Upgrade();
4324     CHECK_NULL_VOID(frameNode);
4325     auto pipelineContext = frameNode->GetContext();
4326     CHECK_NULL_VOID(pipelineContext);
4327     pipelineContext->UpdateCurrentActiveNode(node);
4328 }
4329 
GetOverlayNodePositions()4330 std::vector<Ace::RectF> PipelineContext::GetOverlayNodePositions()
4331 {
4332     return overlayNodePositions_;
4333 }
4334 
RegisterOverlayNodePositionsUpdateCallback(const std::function<void (std::vector<Ace::RectF>)> && callback)4335 void PipelineContext::RegisterOverlayNodePositionsUpdateCallback(
4336     const std::function<void(std::vector<Ace::RectF>)>&& callback)
4337 {
4338     overlayNodePositionUpdateCallback_ = std::move(callback);
4339 }
4340 
TriggerOverlayNodePositionsUpdateCallback(std::vector<Ace::RectF> rects)4341 void PipelineContext::TriggerOverlayNodePositionsUpdateCallback(std::vector<Ace::RectF> rects)
4342 {
4343     if (overlayNodePositionUpdateCallback_) {
4344         overlayNodePositionUpdateCallback_(rects);
4345     }
4346 }
4347 
IsContainerModalVisible()4348 bool PipelineContext::IsContainerModalVisible()
4349 {
4350     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4351         return false;
4352     }
4353     auto windowManager = GetWindowManager();
4354     bool isFloatingWindow = windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
4355     return isShowTitle_ && isFloatingWindow && customTitleSettedShow_;
4356 }
4357 
CheckNeedUpdateBackgroundColor(Color & color)4358 void PipelineContext::CheckNeedUpdateBackgroundColor(Color& color)
4359 {
4360     if (!isFormRender_ || (renderingMode_ != RENDERING_SINGLE_COLOR)) {
4361         return;
4362     }
4363     Color replaceColor = color.ChangeAlpha(SINGLECOLOR_UPDATE_ALPHA);
4364     color = replaceColor;
4365 }
4366 
CheckNeedDisableUpdateBackgroundImage()4367 bool PipelineContext::CheckNeedDisableUpdateBackgroundImage()
4368 {
4369     if (!isFormRender_ || (renderingMode_ != RENDERING_SINGLE_COLOR)) {
4370         return false;
4371     }
4372     return true;
4373 }
4374 
ChangeDarkModeBrightness()4375 void PipelineContext::ChangeDarkModeBrightness()
4376 {
4377     auto windowManager = GetWindowManager();
4378     CHECK_NULL_VOID(windowManager);
4379     auto mode = windowManager->GetWindowMode();
4380     auto container = Container::CurrentSafely();
4381     CHECK_NULL_VOID(container);
4382     auto percent = SystemProperties::GetDarkModeBrightnessPercent();
4383     auto stage = stageManager_->GetStageNode();
4384     CHECK_NULL_VOID(stage);
4385     auto renderContext = stage->GetRenderContext();
4386     CHECK_NULL_VOID(renderContext);
4387     CalcDimension dimension;
4388     dimension.SetValue(1);
4389     if (SystemProperties::GetColorMode() == ColorMode::DARK && appBgColor_.ColorToString().compare("#FF000000") == 0 &&
4390         mode != WindowMode::WINDOW_MODE_FULLSCREEN && !container->IsUIExtensionWindow() &&
4391         !container->IsDynamicRender() && !container->IsFormRender() && !IsJsCard()) {
4392         if (!onFocus_ && mode == WindowMode::WINDOW_MODE_FLOATING) {
4393             dimension.SetValue(1 + percent.second);
4394         } else {
4395             dimension.SetValue(1 + percent.first);
4396         }
4397     }
4398     renderContext->UpdateFrontBrightness(dimension);
4399 }
4400 
PreLayout(uint64_t nanoTimestamp,uint32_t frameCount)4401 void PipelineContext::PreLayout(uint64_t nanoTimestamp, uint32_t frameCount)
4402 {
4403     FlushVsync(nanoTimestamp, frameCount);
4404 }
4405 
CheckAndLogLastReceivedTouchEventInfo(int32_t eventId,TouchType type)4406 void PipelineContext::CheckAndLogLastReceivedTouchEventInfo(int32_t eventId, TouchType type)
4407 {
4408     eventManager_->CheckAndLogLastReceivedTouchEventInfo(eventId, type);
4409 }
4410 
CheckAndLogLastConsumedTouchEventInfo(int32_t eventId,TouchType type)4411 void PipelineContext::CheckAndLogLastConsumedTouchEventInfo(int32_t eventId, TouchType type)
4412 {
4413     eventManager_->CheckAndLogLastConsumedTouchEventInfo(eventId, type);
4414 }
4415 
CheckAndLogLastReceivedMouseEventInfo(int32_t eventId,MouseAction action)4416 void PipelineContext::CheckAndLogLastReceivedMouseEventInfo(int32_t eventId, MouseAction action)
4417 {
4418     eventManager_->CheckAndLogLastReceivedMouseEventInfo(eventId, action);
4419 }
4420 
CheckAndLogLastConsumedMouseEventInfo(int32_t eventId,MouseAction action)4421 void PipelineContext::CheckAndLogLastConsumedMouseEventInfo(int32_t eventId, MouseAction action)
4422 {
4423     eventManager_->CheckAndLogLastConsumedMouseEventInfo(eventId, action);
4424 }
4425 
CheckAndLogLastReceivedAxisEventInfo(int32_t eventId,AxisAction action)4426 void PipelineContext::CheckAndLogLastReceivedAxisEventInfo(int32_t eventId, AxisAction action)
4427 {
4428     eventManager_->CheckAndLogLastReceivedAxisEventInfo(eventId, action);
4429 }
4430 
CheckAndLogLastConsumedAxisEventInfo(int32_t eventId,AxisAction action)4431 void PipelineContext::CheckAndLogLastConsumedAxisEventInfo(int32_t eventId, AxisAction action)
4432 {
4433     eventManager_->CheckAndLogLastConsumedAxisEventInfo(eventId, action);
4434 }
4435 
RegisterTouchEventListener(const std::shared_ptr<ITouchEventCallback> & listener)4436 void PipelineContext::RegisterTouchEventListener(const std::shared_ptr<ITouchEventCallback>& listener)
4437 {
4438     if (!listener) {
4439         return;
4440     }
4441     listenerVector_.emplace_back(listener);
4442 }
4443 
UnregisterTouchEventListener(const WeakPtr<NG::Pattern> & pattern)4444 void PipelineContext::UnregisterTouchEventListener(const WeakPtr<NG::Pattern>& pattern)
4445 {
4446     for (auto iter = listenerVector_.begin(); iter != listenerVector_.end();) {
4447         auto patternPtr = (*iter)->GetPatternFromListener();
4448         if (patternPtr.Invalid() || patternPtr == pattern) {
4449             iter = listenerVector_.erase(iter);
4450         } else {
4451             iter++;
4452         }
4453     }
4454 }
4455 
FlushFrameCallback(uint64_t nanoTimestamp)4456 void PipelineContext::FlushFrameCallback(uint64_t nanoTimestamp)
4457 {
4458     if (!frameCallbackFuncs_.empty()) {
4459         decltype(frameCallbackFuncs_) tasks(std::move(frameCallbackFuncs_));
4460         for (const auto& frameCallbackFunc : tasks) {
4461             frameCallbackFunc(nanoTimestamp);
4462         }
4463     }
4464 }
4465 
RegisterFocusCallback()4466 void PipelineContext::RegisterFocusCallback()
4467 {
4468     focusManager_->AddFocusListener([](const WeakPtr<FocusHub>& last, const RefPtr<FocusHub>& current,
4469         FocusReason focusReason) {
4470         CHECK_NULL_VOID(current);
4471         auto node = current->GetFrameNode();
4472         CHECK_NULL_VOID(node);
4473         InputMethodManager::GetInstance()->OnFocusNodeChange(node, focusReason);
4474     });
4475 }
4476 
AddFrameNodeChangeListener(const WeakPtr<FrameNode> & node)4477 void PipelineContext::AddFrameNodeChangeListener(const WeakPtr<FrameNode>& node)
4478 {
4479     CHECK_NULL_VOID(node.Upgrade());
4480     if (std::find(changeInfoListeners_.begin(), changeInfoListeners_.end(), node) == changeInfoListeners_.end()) {
4481         changeInfoListeners_.push_back(node);
4482     }
4483 }
4484 
RemoveFrameNodeChangeListener(int32_t nodeId)4485 void PipelineContext::RemoveFrameNodeChangeListener(int32_t nodeId)
4486 {
4487     if (changeInfoListeners_.empty()) {
4488         return;
4489     }
4490     changeInfoListeners_.remove_if([nodeId](const WeakPtr<FrameNode>& node) {
4491         return !node.Upgrade() || nodeId == node.Upgrade()->GetId();
4492     });
4493 }
4494 
AddChangedFrameNode(const WeakPtr<FrameNode> & node)4495 bool PipelineContext::AddChangedFrameNode(const WeakPtr<FrameNode>& node)
4496 {
4497     CHECK_NULL_RETURN(node.Upgrade(), false);
4498     if (changeInfoListeners_.empty()) {
4499         return false;
4500     }
4501     if (std::find(changedNodes_.begin(), changedNodes_.end(), node) == changedNodes_.end()) {
4502         changedNodes_.push_back(node);
4503     }
4504     return true;
4505 }
4506 
RemoveChangedFrameNode(int32_t nodeId)4507 void PipelineContext::RemoveChangedFrameNode(int32_t nodeId)
4508 {
4509     if (changedNodes_.empty()) {
4510         return;
4511     }
4512     changedNodes_.remove_if([nodeId](const WeakPtr<FrameNode>& node) {
4513         return !node.Upgrade() || nodeId == node.Upgrade()->GetId();
4514     });
4515 }
4516 
FlushNodeChangeFlag()4517 void PipelineContext::FlushNodeChangeFlag()
4518 {
4519     ACE_FUNCTION_TRACE();
4520     if (!changeInfoListeners_.empty()) {
4521         for (const auto& it : changeInfoListeners_) {
4522             auto listener = it.Upgrade();
4523             if (listener) {
4524                 listener->ProcessFrameNodeChangeFlag();
4525             }
4526         }
4527     }
4528     CleanNodeChangeFlag();
4529 }
4530 
CleanNodeChangeFlag()4531 void PipelineContext::CleanNodeChangeFlag()
4532 {
4533     auto cleanNodes = std::move(changedNodes_);
4534     changedNodes_.clear();
4535     for (const auto& it : cleanNodes) {
4536         auto changeNode = it.Upgrade();
4537         if (changeNode) {
4538             changeNode->ClearChangeInfoFlag();
4539         }
4540     }
4541 }
4542 
GetInspectorTree()4543 void PipelineContext::GetInspectorTree()
4544 {
4545 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
4546     bool needThrow = false;
4547     NG::InspectorFilter filter;
4548     filter.AddFilterAttr("content");
4549     auto nodeInfos = NG::Inspector::GetInspector(false, filter, needThrow);
4550     UiSessionManager::GetInstance().AddValueForTree(0, nodeInfos);
4551 #endif
4552     rootNode_->GetInspectorValue();
4553 }
4554 
NotifyAllWebPattern(bool isRegister)4555 void PipelineContext::NotifyAllWebPattern(bool isRegister)
4556 {
4557     rootNode_->NotifyWebPattern(isRegister);
4558 }
4559 
4560 #if defined(SUPPORT_TOUCH_TARGET_TEST)
4561 
OnTouchTargetHitTest(const TouchEvent & point,bool isSubPipe,const std::string & target)4562 bool PipelineContext::OnTouchTargetHitTest(const TouchEvent& point, bool isSubPipe, const std::string& target)
4563 {
4564     auto scalePoint = point.CreateScalePoint(GetViewScale());
4565     if (scalePoint.type == TouchType::DOWN) {
4566         TouchRestrict touchRestrict { TouchRestrict::NONE };
4567         touchRestrict.sourceType = point.sourceType;
4568         touchRestrict.touchEvent = point;
4569         bool isTouchTarget = eventManager_->TouchTargetHitTest(
4570             scalePoint, rootNode_, touchRestrict, GetPluginEventOffset(), viewScale_, isSubPipe, target);
4571         return isTouchTarget;
4572     }
4573     return false;
4574 }
4575 #endif
4576 
UpdateHalfFoldHoverStatus(int32_t windowWidth,int32_t windowHeight)4577 void PipelineContext::UpdateHalfFoldHoverStatus(int32_t windowWidth, int32_t windowHeight)
4578 {
4579     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_THIRTEEN)) {
4580         isHalfFoldHoverStatus_ = false;
4581         return;
4582     }
4583     auto container = Container::Current();
4584     CHECK_NULL_VOID(container);
4585     bool isFoldable = container->IsFoldable();
4586     if (!isFoldable && !SystemProperties::IsSmallFoldProduct()) {
4587         isHalfFoldHoverStatus_ = false;
4588         return;
4589     }
4590     auto displayInfo = container->GetDisplayInfo();
4591     CHECK_NULL_VOID(displayInfo);
4592     auto windowManager = GetWindowManager();
4593     auto windowMode = windowManager->GetWindowMode();
4594     auto isHalfFolded = displayInfo->GetFoldStatus() == FoldStatus::HALF_FOLD;
4595     auto displayWidth = displayInfo->GetWidth();
4596     auto displayHeight = displayInfo->GetHeight();
4597     auto isFullScreen = windowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
4598         (NearEqual(displayWidth, windowWidth) && NearEqual(displayHeight, windowHeight));
4599     if (!isFullScreen || !isHalfFolded) {
4600         isHalfFoldHoverStatus_ = false;
4601         return;
4602     }
4603     auto rotation = displayInfo->GetRotation();
4604     if (SystemProperties::IsSmallFoldProduct()) {
4605         isHalfFoldHoverStatus_ = rotation == Rotation::ROTATION_0 || rotation == Rotation::ROTATION_180;
4606     } else {
4607         isHalfFoldHoverStatus_ = rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270;
4608     }
4609 }
4610 
OnHalfFoldHoverChangedCallback()4611 void PipelineContext::OnHalfFoldHoverChangedCallback()
4612 {
4613     for (auto&& [id, callback] : halfFoldHoverChangedCallbackMap_) {
4614         if (callback) {
4615             callback(isHalfFoldHoverStatus_);
4616         }
4617     }
4618 }
4619 
StartFoldStatusDelayTask(FoldStatus foldStatus)4620 void PipelineContext::StartFoldStatusDelayTask(FoldStatus foldStatus)
4621 {
4622     if (foldStatusDelayTask_) {
4623         foldStatusDelayTask_.Cancel();
4624     }
4625     foldStatusDelayTask_.Reset([weak = WeakClaim(this)]() {
4626         auto context = weak.Upgrade();
4627         CHECK_NULL_VOID(context);
4628         context->UpdateHalfFoldHoverProperty(context->GetRootWidth(), context->GetRootHeight());
4629         context->OnHalfFoldHoverChangedCallback();
4630     });
4631     taskExecutor_->PostDelayedTask(
4632         foldStatusDelayTask_, TaskExecutor::TaskType::UI, DELAY_TIME, "ArkUIHalfFoldHoverStatusChange");
4633 }
4634 
CatchInteractiveAnimations(const std::function<void ()> & animationCallback)4635 bool PipelineContext::CatchInteractiveAnimations(const std::function<void()>& animationCallback)
4636 {
4637     CHECK_NULL_RETURN(navigationMgr_, false);
4638     if (navigationMgr_->IsInteractive()) {
4639         return navigationMgr_->AddInteractiveAnimation(animationCallback);
4640     }
4641     return false;
4642 }
4643 
GetResponseRegion(const RefPtr<FrameNode> & rootNode)4644 std::string PipelineContext::GetResponseRegion(const RefPtr<FrameNode>& rootNode)
4645 {
4646     CHECK_NULL_RETURN(rootNode, "");
4647     std::vector<RectF> responseRegionList;
4648     rootNode->GetResponseRegionListByTraversal(responseRegionList);
4649     std::string responseRegionStrOrigin;
4650     std::string responseRegionStrFilter;
4651     for (const auto& rect : responseRegionList) {
4652         int32_t left = static_cast<int32_t>(rect.Left());
4653         int32_t top = static_cast<int32_t>(rect.Top());
4654         int32_t width = static_cast<int32_t>(rect.Width());
4655         int32_t height = static_cast<int32_t>(rect.Height());
4656         int32_t right = static_cast<int32_t>(rect.Right());
4657         int32_t bottom = static_cast<int32_t>(rect.Bottom());
4658         std::string rectStr = std::to_string(left) + "," +
4659                               std::to_string(top) + "," +
4660                               std::to_string(right) + "," +
4661                               std::to_string(bottom);
4662 
4663         responseRegionStrOrigin += rectStr + "#";
4664         if (thpExtraMgr_ && width <= thpExtraMgr_->GetWidth() && height <= thpExtraMgr_->GetHeight()) {
4665             responseRegionStrFilter += rectStr + "#";
4666         }
4667     }
4668     if (!responseRegionStrFilter.empty()) {
4669         responseRegionStrFilter.pop_back();
4670     }
4671     LOGD("THP_UpdateViewsLocation origin responseRegion = %{public}s", responseRegionStrOrigin.c_str());
4672     return responseRegionStrFilter;
4673 }
4674 
NotifyResponseRegionChanged(const RefPtr<FrameNode> & rootNode)4675 void PipelineContext::NotifyResponseRegionChanged(const RefPtr<FrameNode>& rootNode)
4676 {
4677     ACE_FUNCTION_TRACE();
4678     if (!thpExtraMgr_) {
4679         return;
4680     }
4681     std::string responseRegion = GetResponseRegion(rootNode);
4682     std::string parameters = "thp#Location#" + responseRegion;
4683     LOGD("THP_UpdateViewsLocation responseRegion = %{public}s", parameters.c_str());
4684     thpExtraMgr_->ThpExtraRunCommand("THP_UpdateViewsLocation", parameters.c_str());
4685 }
4686 
CheckThreadSafe() const4687 bool PipelineContext::CheckThreadSafe() const
4688 {
4689     CHECK_NULL_RETURN(taskExecutor_, true);
4690     if (!isFormRender_ && !taskExecutor_->WillRunOnCurrentThread(OHOS::Ace::TaskExecutor::TaskType::UI)) {
4691         OHOS::Ace::LogBacktrace();
4692         return false;
4693     }
4694     return true;
4695 }
4696 
AdjustVsyncTimeStamp(uint64_t nanoTimestamp)4697 uint64_t PipelineContext::AdjustVsyncTimeStamp(uint64_t nanoTimestamp)
4698 {
4699     auto period = window_->GetVSyncPeriod();
4700     if (period > 0 && recvTime_ > static_cast<int64_t>(nanoTimestamp) + MAX_MISS_COUNT * period) {
4701         return static_cast<uint64_t>(recvTime_ - ((recvTime_ - static_cast<int64_t>(nanoTimestamp)) % period));
4702     }
4703     return nanoTimestamp;
4704 }
4705 
FlushModifierAnimation(uint64_t nanoTimestamp)4706 bool PipelineContext::FlushModifierAnimation(uint64_t nanoTimestamp)
4707 {
4708     auto animationTimeStamp = AdjustVsyncTimeStamp(nanoTimestamp);
4709     if (animationTimeStamp < animationTimeStamp_) {
4710         ACE_SCOPED_TRACE("skip ModifierAnimation");
4711         TAG_LOGW(AceLogTag::ACE_ANIMATION,
4712             "Time decreases, skip ModifierAnimation, lastTime:%{public}" PRIu64 ", nowTime:%{public}" PRIu64,
4713             animationTimeStamp_, animationTimeStamp);
4714         return true;
4715     }
4716     animationTimeStamp_ = animationTimeStamp;
4717     return window_->FlushAnimation(animationTimeStamp);
4718 }
4719 
RegisterAttachedNode(UINode * uiNode)4720 void PipelineContext::RegisterAttachedNode(UINode* uiNode)
4721 {
4722     attachedNodeSet_.emplace(uiNode);
4723 }
4724 
RemoveAttachedNode(UINode * uiNode)4725 void PipelineContext::RemoveAttachedNode(UINode* uiNode)
4726 {
4727     attachedNodeSet_.erase(uiNode);
4728 }
4729 
ScopedLayout(PipelineContext * pipeline)4730 ScopedLayout::ScopedLayout(PipelineContext* pipeline)
4731 {
4732     if (!pipeline) {
4733         return;
4734     }
4735     // save flag before measure
4736     pipeline_ = pipeline;
4737     isLayouting_ = pipeline_->IsLayouting();
4738     pipeline_->SetIsLayouting(true);
4739 }
4740 
~ScopedLayout()4741 ScopedLayout::~ScopedLayout()
4742 {
4743     if (!pipeline_) {
4744         return;
4745     }
4746     // set layout flag back
4747     pipeline_->SetIsLayouting(isLayouting_);
4748 }
4749 
GetBundleName()4750 std::string PipelineContext::GetBundleName()
4751 {
4752     auto container = Container::GetContainer(instanceId_);
4753     CHECK_NULL_RETURN(container, "");
4754     return container->GetBundleName();
4755 }
4756 
GetModuleName()4757 std::string PipelineContext::GetModuleName()
4758 {
4759     auto container = Container::GetContainer(instanceId_);
4760     CHECK_NULL_RETURN(container, "");
4761     return container->GetModuleName();
4762 }
4763 } // namespace OHOS::Ace::NG
4764