• 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 #include "transaction/rs_transaction_proxy.h"
26 #endif
27 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
28 
29 #include "frameworks/core/components_ng/base/inspector.h"
30 #include "base/geometry/ng/offset_t.h"
31 #include "base/geometry/ng/rect_t.h"
32 #include "base/log/ace_performance_monitor.h"
33 #include "base/log/ace_trace.h"
34 #include "base/log/ace_tracker.h"
35 #include "base/log/dump_log.h"
36 #include "base/log/dump_recorder.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/resource/resource_manager.h"
48 #include "core/common/stylus/stylus_detector_default.h"
49 #include "core/common/stylus/stylus_detector_mgr.h"
50 #include "core/common/text_field_manager.h"
51 #include "core/components_ng/base/view_advanced_register.h"
52 #include "core/components_ng/pattern/container_modal/container_modal_view_factory.h"
53 #include "core/components_ng/pattern/container_modal/enhance/container_modal_pattern_enhance.h"
54 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
55 #include "core/components_ng/pattern/navigation/nav_bar_node.h"
56 #include "core/components_ng/pattern/root/root_pattern.h"
57 #include "core/components_ng/pattern/text_field/text_field_manager.h"
58 #ifdef WINDOW_SCENE_SUPPORTED
59 #include "core/components_ng/pattern/window_scene/scene/window_scene_layout_manager.h"
60 #endif
61 #include "core/image/image_file_cache.h"
62 #include "core/pipeline/pipeline_context.h"
63 #ifdef COMPONENT_TEST_ENABLED
64 #include "component_test/pipeline_status.h"
65 #endif // COMPONENT_TEST_ENABLED
66 #include "interfaces/inner_api/ace_kit/src/view/ui_context_impl.h"
67 
68 namespace {
69 constexpr uint64_t ONE_MS_IN_NS = 1 * 1000 * 1000;
70 constexpr int32_t TIME_THRESHOLD = 2 * 1000000; // 3 millisecond
71 constexpr int32_t PLATFORM_VERSION_TEN = 10;
72 constexpr int32_t MILLISECONDS_TO_NANOSECONDS = 1000000; // Milliseconds to nanoseconds
73 constexpr int32_t VSYNC_PERIOD_COUNT = 5;
74 constexpr int32_t MIN_IDLE_TIME = 1000;
75 constexpr uint8_t SINGLECOLOR_UPDATE_ALPHA = 75;
76 constexpr int8_t RENDERING_SINGLE_COLOR = 1;
77 constexpr int32_t DELAY_TIME = 500;
78 constexpr int32_t PARAM_NUM = 2;
79 constexpr int32_t MAX_MISS_COUNT = 3;
80 constexpr int32_t MAX_FLUSH_COUNT = 2;
81 constexpr int32_t MAX_RECORD_SECOND = 15;
82 constexpr int32_t DEFAULT_RECORD_SECOND = 5;
83 constexpr int32_t SECOND_TO_MILLISEC = 1000;
84 } // namespace
85 
86 namespace OHOS::Ace::NG {
87 namespace {
88 constexpr Dimension CARET_AVOID_OFFSET = 24.0_vp;
89 
ShouldAddToHistory(std::vector<TouchEvent> & history,const TouchEvent & event,const TouchEvent & movePoint)90 void ShouldAddToHistory (
91     std::vector<TouchEvent>& history, const TouchEvent& event, const TouchEvent& movePoint)
92 {
93 #ifdef ARKUI_WEARABLE
94     if (event.x != movePoint.x || event.y != movePoint.y) {
95         history.emplace_back(movePoint);
96     }
97 #else
98     history.emplace_back(movePoint);
99 #endif
100 }
101 
GetDepthFromParams(const std::vector<std::string> & params)102 int32_t GetDepthFromParams(const std::vector<std::string>& params)
103 {
104     int32_t depth = 0;
105     std::string prefix = "dcDepth_";
106     for (const auto& param : params) {
107         if (param.find(prefix) == 0) {
108             std::string suffix = param.substr(prefix.length());
109             int32_t suffixInt = StringUtils::StringToInt(suffix);
110             if (suffixInt != 0) {
111                 depth = suffixInt;
112                 break;
113             }
114         }
115     }
116 
117     return depth;
118 }
119 } // namespace
120 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,RefPtr<PlatformResRegister> platformResRegister,const RefPtr<Frontend> & frontend,int32_t instanceId)121 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
122     RefPtr<AssetManager> assetManager, RefPtr<PlatformResRegister> platformResRegister,
123     const RefPtr<Frontend>& frontend, int32_t instanceId)
124     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId, platformResRegister)
125 {
126     window_->OnHide();
127     if (navigationMgr_) {
128         navigationMgr_->SetPipelineContext(WeakClaim(this));
129     }
130     if (avoidInfoMgr_) {
131         avoidInfoMgr_->SetPipelineContext(WeakClaim(this));
132         avoidInfoMgr_->SetInstanceId(instanceId);
133     }
134 #ifdef WINDOW_SCENE_SUPPORTED
135     if (uiExtensionManager_) {
136         uiExtensionManager_->SetPipelineContext(WeakClaim(this));
137         uiExtensionManager_->SetInstanceId(instanceId);
138     }
139 #endif
140 }
141 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)142 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
143     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
144     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId)
145 {
146     window_->OnHide();
147     if (navigationMgr_) {
148         navigationMgr_->SetPipelineContext(WeakClaim(this));
149     }
150     if (avoidInfoMgr_) {
151         avoidInfoMgr_->SetPipelineContext(WeakClaim(this));
152         avoidInfoMgr_->SetInstanceId(instanceId);
153     }
154 #ifdef WINDOW_SCENE_SUPPORTED
155     if (uiExtensionManager_) {
156         uiExtensionManager_->SetPipelineContext(WeakClaim(this));
157         uiExtensionManager_->SetInstanceId(instanceId);
158     }
159 #endif
160 }
161 
PipelineContext()162 PipelineContext::PipelineContext()
163 {
164     if (navigationMgr_) {
165         navigationMgr_->SetPipelineContext(WeakClaim(this));
166     }
167     if (avoidInfoMgr_) {
168         avoidInfoMgr_->SetPipelineContext(WeakClaim(this));
169     }
170 #ifdef WINDOW_SCENE_SUPPORTED
171     if (uiExtensionManager_) {
172         uiExtensionManager_->SetPipelineContext(WeakClaim(this));
173     }
174 #endif
175 }
176 
GetCurrentPageNameCallback()177 std::string PipelineContext::GetCurrentPageNameCallback()
178 {
179     CHECK_NULL_RETURN(stageManager_, "");
180     RefPtr<FrameNode> pageNode = stageManager_->GetLastPage();
181     CHECK_NULL_RETURN(pageNode, "");
182     auto pagePattern = pageNode->GetPattern<PagePattern>();
183     CHECK_NULL_RETURN(pagePattern, "");
184     CHECK_NULL_RETURN(pagePattern->GetPageInfo(), "");
185     int32_t pageId = pagePattern->GetPageInfo()->GetPageId();
186     RefPtr<NavigationGroupNode> navigationNode = nullptr;
187     CHECK_RUN_ON(UI);
188     auto it = pageToNavigationNodes_.find(pageId);
189     if (it == pageToNavigationNodes_.end() || it->second.empty()) {
190         return "";
191     }
192 
193     for (auto iter = it->second.begin(); iter != it->second.end() && !navigationNode; ++iter) {
194         navigationNode = AceType::DynamicCast<NavigationGroupNode>((*iter).Upgrade());
195     }
196 
197     CHECK_NULL_RETURN(navigationNode, "");
198     CHECK_NULL_RETURN(navigationNode->GetPattern(), "");
199     auto pattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
200     CHECK_NULL_RETURN(pattern, "");
201     const auto& navDestinationNodes = pattern->GetAllNavDestinationNodes();
202     int32_t size = static_cast<int32_t>(navDestinationNodes.size());
203     if (size == 0) {
204         return "";
205     }
206     auto pageNameObj = navDestinationNodes.back();
207     std::string pageName = std::get<0>(pageNameObj);
208     return pageName;
209 }
210 
GetCurrentContext()211 RefPtr<PipelineContext> PipelineContext::GetCurrentContext()
212 {
213     auto currentContainer = Container::Current();
214     CHECK_NULL_RETURN(currentContainer, nullptr);
215     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
216 }
217 
GetCurrentContextSafely()218 RefPtr<PipelineContext> PipelineContext::GetCurrentContextSafely()
219 {
220     auto currentContainer = Container::CurrentSafely();
221     CHECK_NULL_RETURN(currentContainer, nullptr);
222     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
223 }
224 
GetCurrentContextSafelyWithCheck()225 RefPtr<PipelineContext> PipelineContext::GetCurrentContextSafelyWithCheck()
226 {
227     auto currentContainer = Container::CurrentSafelyWithCheck();
228     CHECK_NULL_RETURN(currentContainer, nullptr);
229     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
230 }
231 
GetCurrentContextPtrSafely()232 PipelineContext* PipelineContext::GetCurrentContextPtrSafely()
233 {
234     auto currentContainer = Container::CurrentSafely();
235     CHECK_NULL_RETURN(currentContainer, nullptr);
236     const auto& base = currentContainer->GetPipelineContext();
237     CHECK_NULL_RETURN(base, nullptr);
238     return DynamicCast<PipelineContext>(RawPtr(base));
239 }
240 
GetCurrentContextPtrSafelyWithCheck()241 PipelineContext* PipelineContext::GetCurrentContextPtrSafelyWithCheck()
242 {
243     auto currentContainer = Container::CurrentSafelyWithCheck();
244     CHECK_NULL_RETURN(currentContainer, nullptr);
245     const auto& base = currentContainer->GetPipelineContext();
246     CHECK_NULL_RETURN(base, nullptr);
247     return DynamicCast<PipelineContext>(RawPtr(base));
248 }
249 
GetMainPipelineContext()250 RefPtr<PipelineContext> PipelineContext::GetMainPipelineContext()
251 {
252     auto pipeline = PipelineBase::GetMainPipelineContext();
253     CHECK_NULL_RETURN(pipeline, nullptr);
254     return DynamicCast<PipelineContext>(pipeline);
255 }
256 
NeedSoftKeyboard()257 bool PipelineContext::NeedSoftKeyboard()
258 {
259     auto needSoftKeyboard = InputMethodManager::GetInstance()->NeedSoftKeyboard();
260     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "window switch need keyboard %d", needSoftKeyboard);
261     return needSoftKeyboard;
262 }
263 
GetContextByContainerId(int32_t containerId)264 RefPtr<PipelineContext> PipelineContext::GetContextByContainerId(int32_t containerId)
265 {
266     auto preContainer = Container::GetContainer(containerId);
267     CHECK_NULL_RETURN(preContainer, nullptr);
268     return DynamicCast<PipelineContext>(preContainer->GetPipelineContext());
269 }
270 
GetCurrentRootWidth()271 float PipelineContext::GetCurrentRootWidth()
272 {
273     auto context = GetCurrentContext();
274     CHECK_NULL_RETURN(context, 0.0f);
275     return static_cast<float>(context->rootWidth_);
276 }
277 
GetCurrentRootHeight()278 float PipelineContext::GetCurrentRootHeight()
279 {
280     auto context = GetCurrentContext();
281     CHECK_NULL_RETURN(context, 0.0f);
282     return static_cast<float>(context->rootHeight_);
283 }
284 
AddDirtyPropertyNode(const RefPtr<FrameNode> & dirtyNode)285 void PipelineContext::AddDirtyPropertyNode(const RefPtr<FrameNode>& dirtyNode)
286 {
287     if (!CheckThreadSafe()) {
288         LOGW("AddDirtyPropertyNode doesn't run on UI thread!");
289     }
290     dirtyPropertyNodes_.emplace(dirtyNode);
291     hasIdleTasks_ = true;
292     RequestFrame();
293 }
294 
AddDirtyCustomNode(const RefPtr<UINode> & dirtyNode)295 void PipelineContext::AddDirtyCustomNode(const RefPtr<UINode>& dirtyNode)
296 {
297     CHECK_RUN_ON(UI);
298     CHECK_NULL_VOID(dirtyNode);
299     auto customNode = DynamicCast<CustomNode>(dirtyNode);
300     if (customNode && !dirtyNode->GetInspectorIdValue("").empty()) {
301         ACE_BUILD_TRACE_BEGIN("AddDirtyCustomNode[%s][self:%d][parent:%d][key:%s]",
302             customNode->GetJSViewName().c_str(),
303             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0,
304             dirtyNode->GetInspectorIdValue("").c_str());
305         ACE_BUILD_TRACE_END()
306     } else if (customNode) {
307         ACE_BUILD_TRACE_BEGIN("AddDirtyCustomNode[%s][self:%d][parent:%d]",
308             customNode->GetJSViewName().c_str(),
309             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0);
310         ACE_BUILD_TRACE_END()
311     }
312     dirtyNodes_.emplace(dirtyNode);
313     hasIdleTasks_ = true;
314     RequestFrame();
315 }
316 
AddDirtyLayoutNode(const RefPtr<FrameNode> & dirty)317 void PipelineContext::AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty)
318 {
319     CHECK_RUN_ON(UI);
320     CHECK_NULL_VOID(dirty);
321     if (IsDestroyed()) {
322         LOGW("Cannot add dirty layout node as the pipeline context is destroyed.");
323         return;
324     }
325     if (!dirty->GetInspectorIdValue("").empty()) {
326         ACE_BUILD_TRACE_BEGIN("AddDirtyLayoutNode[%s][self:%d][parent:%d][key:%s]",
327             dirty->GetTag().c_str(),
328             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
329             dirty->GetInspectorIdValue("").c_str());
330         ACE_BUILD_TRACE_END()
331     } else {
332         ACE_BUILD_TRACE_BEGIN("AddDirtyLayoutNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
333             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
334         ACE_BUILD_TRACE_END()
335     }
336     if (!dirty->IsOnMainTree() && predictNode_) {
337         predictNode_->AddPredictLayoutNode(dirty);
338         return;
339     }
340     taskScheduler_->AddDirtyLayoutNode(dirty);
341     ForceLayoutForImplicitAnimation();
342 #ifdef UICAST_COMPONENT_SUPPORTED
343     do {
344         auto container = Container::Current();
345         CHECK_NULL_BREAK(container);
346         auto distributedUI = container->GetDistributedUI();
347         CHECK_NULL_BREAK(distributedUI);
348         distributedUI->AddDirtyLayoutNode(dirty->GetId());
349     } while (false);
350 #endif
351     hasIdleTasks_ = true;
352     if (dirty->GetTag() == V2::ROOT_ETS_TAG && isFirstRootLayout_) {
353         isFirstRootLayout_ = false;
354         LOGI("Root node request first frame.");
355     }
356     RequestFrame();
357 }
358 
AddLayoutNode(const RefPtr<FrameNode> & layoutNode)359 void PipelineContext::AddLayoutNode(const RefPtr<FrameNode>& layoutNode)
360 {
361     taskScheduler_->AddLayoutNode(layoutNode);
362 }
363 
AddDirtyRenderNode(const RefPtr<FrameNode> & dirty)364 void PipelineContext::AddDirtyRenderNode(const RefPtr<FrameNode>& dirty)
365 {
366     CHECK_RUN_ON(UI);
367     CHECK_NULL_VOID(dirty);
368     if (IsDestroyed()) {
369         LOGW("Cannot add dirty render node as the pipeline context is destroyed.");
370         return;
371     }
372     if (!dirty->GetInspectorIdValue("").empty()) {
373         ACE_BUILD_TRACE_BEGIN("AddDirtyRenderNode[%s][self:%d][parent:%d][key:%s]", dirty->GetTag().c_str(),
374             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
375             dirty->GetInspectorIdValue("").c_str());
376         ACE_BUILD_TRACE_END()
377     } else {
378         ACE_BUILD_TRACE_BEGIN("AddDirtyRenderNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
379             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
380         ACE_BUILD_TRACE_END()
381     }
382     taskScheduler_->AddDirtyRenderNode(dirty);
383     ForceRenderForImplicitAnimation();
384 #ifdef UICAST_COMPONENT_SUPPORTED
385     do {
386         auto container = Container::Current();
387         CHECK_NULL_BREAK(container);
388         auto distributedUI = container->GetDistributedUI();
389         CHECK_NULL_BREAK(distributedUI);
390         distributedUI->AddDirtyRenderNode(dirty->GetId());
391     } while (false);
392 #endif
393     hasIdleTasks_ = true;
394     RequestFrame();
395 }
396 
AddDirtyFreezeNode(FrameNode * node)397 void PipelineContext::AddDirtyFreezeNode(FrameNode* node)
398 {
399     dirtyFreezeNode_.emplace_back(WeakClaim(node));
400     hasIdleTasks_ = true;
401     RequestFrame();
402 }
403 
FlushFreezeNode()404 void PipelineContext::FlushFreezeNode()
405 {
406     std::set<RefPtr<FrameNode>, NodeCompare<RefPtr<FrameNode>>> dirtyFreezeNodeSet;
407     auto dirtyFreezeNodes = std::move(dirtyFreezeNode_);
408     dirtyFreezeNode_.clear();
409     for (auto&& weakNode : dirtyFreezeNodes) {
410         auto node = weakNode.Upgrade();
411         if (node) {
412             dirtyFreezeNodeSet.emplace(node);
413         }
414     }
415     //Process parentNode before childNode
416     for (auto&& node : dirtyFreezeNodeSet) {
417         node->ProcessFreezeNode();
418     }
419 }
420 
AddPendingDeleteCustomNode(const RefPtr<CustomNode> & node)421 void PipelineContext::AddPendingDeleteCustomNode(const RefPtr<CustomNode>& node)
422 {
423     pendingDeleteCustomNode_.push(node);
424     RequestFrame();
425 }
426 
FlushPendingDeleteCustomNode()427 void PipelineContext::FlushPendingDeleteCustomNode()
428 {
429     auto pendingStack = std::move(pendingDeleteCustomNode_);
430     while (!pendingStack.empty()) {
431         auto node = pendingStack.top();
432         pendingStack.pop();
433         if (AceType::InstanceOf<NG::CustomNode>(node)) {
434             auto customNode = AceType::DynamicCast<NG::CustomNode>(node);
435             customNode->FireOnDisappear();
436             customNode->Reset();
437         }
438     }
439 }
440 
FlushDirtyPropertyNodes()441 void PipelineContext::FlushDirtyPropertyNodes()
442 {
443     // node api property diff before ets update.
444     if (!CheckThreadSafe()) {
445         LOGW("FlushDirtyNodeUpdate doesn't run on UI thread!");
446     }
447     decltype(dirtyPropertyNodes_) dirtyPropertyNodes(std::move(dirtyPropertyNodes_));
448     dirtyPropertyNodes_.clear();
449     for (const auto& node : dirtyPropertyNodes) {
450         node->ProcessPropertyDiff();
451     }
452 }
453 
FlushDirtyNodeUpdate()454 void PipelineContext::FlushDirtyNodeUpdate()
455 {
456     CHECK_RUN_ON(UI);
457     ACE_FUNCTION_TRACE();
458     if (FrameReport::GetInstance().GetEnable()) {
459         FrameReport::GetInstance().BeginFlushBuild();
460     }
461 
462     // freeze node unlock before build begin.
463     FlushFreezeNode();
464 
465     FlushDirtyPropertyNodes();
466 
467     FlushPendingDeleteCustomNode();
468 
469     if (!ViewStackProcessor::GetInstance()->IsEmpty() && !dirtyNodes_.empty()) {
470         ACE_SCOPED_TRACE("Error update, node stack non-empty");
471         LOGW("stack is not empty when call FlushDirtyNodeUpdate, node may be mounted to incorrect pos!");
472     }
473     // SomeTimes, customNode->Update may add some dirty custom nodes to dirtyNodes_,
474     // use maxFlushTimes to avoid dead cycle.
475     int maxFlushTimes = 3;
476     while (!dirtyNodes_.empty() && maxFlushTimes > 0) {
477         ArkUIPerfMonitor::GetInstance().RecordStateMgmtNode(dirtyNodes_.size());
478         decltype(dirtyNodes_) dirtyNodes(std::move(dirtyNodes_));
479         for (const auto& node : dirtyNodes) {
480             if (AceType::InstanceOf<NG::CustomNodeBase>(node)) {
481                 auto customNode = AceType::DynamicCast<NG::CustomNodeBase>(node);
482                 ACE_SCOPED_TRACE("CustomNodeUpdate name:%s,id:%d", customNode->GetJSViewName().c_str(), node->GetId());
483                 customNode->Update();
484             }
485         }
486         --maxFlushTimes;
487     }
488 
489     if (FrameReport::GetInstance().GetEnable()) {
490         FrameReport::GetInstance().EndFlushBuild();
491     }
492 }
493 
AddScheduleTask(const RefPtr<ScheduleTask> & task)494 uint32_t PipelineContext::AddScheduleTask(const RefPtr<ScheduleTask>& task)
495 {
496     CHECK_RUN_ON(UI);
497     scheduleTasks_.try_emplace(++nextScheduleTaskId_, task);
498     RequestFrame();
499     return nextScheduleTaskId_;
500 }
501 
RemoveScheduleTask(uint32_t id)502 void PipelineContext::RemoveScheduleTask(uint32_t id)
503 {
504     CHECK_RUN_ON(UI);
505     scheduleTasks_.erase(id);
506 }
507 
FlushOnceVsyncTask()508 void PipelineContext::FlushOnceVsyncTask()
509 {
510     if (onceVsyncListener_ != nullptr) {
511         onceVsyncListener_();
512         onceVsyncListener_ = nullptr;
513     }
514 }
515 
FlushDragEvents()516 void PipelineContext::FlushDragEvents()
517 {
518     auto manager = GetDragDropManager();
519     if (!manager) {
520         TAG_LOGE(AceLogTag::ACE_DRAG, "GetDragDrapManager error, manager is nullptr");
521         dragEvents_.clear();
522         return;
523     }
524     if (!manager->IsDragFwkShow()) {
525         manager->DoDragMoveAnimate(manager->GetDragAnimationPointerEvent());
526     }
527     std::string extraInfo = manager->GetExtraInfo();
528     std::unordered_set<int32_t> moveEventIds;
529     decltype(dragEvents_) dragEvents(std::move(dragEvents_));
530     if (dragEvents.empty()) {
531         canUseLongPredictTask_ = true;
532         nodeToPointEvent_.clear();
533         return ;
534     }
535     canUseLongPredictTask_ = false;
536     for (auto iter = dragEvents.begin(); iter != dragEvents.end(); ++iter) {
537         FlushDragEvents(manager, extraInfo, iter->first, iter->second);
538     }
539 }
540 
FlushDragEvents(const RefPtr<DragDropManager> & manager,std::string extraInfo,const RefPtr<FrameNode> & node,const std::list<DragPointerEvent> & pointEvent)541 void PipelineContext::FlushDragEvents(const RefPtr<DragDropManager>& manager,
542     std::string extraInfo,
543     const RefPtr<FrameNode>& node,
544     const std::list<DragPointerEvent>& pointEvent)
545 {
546     std::unordered_map<int, DragPointerEvent> idToPoints;
547     bool needInterpolation = true;
548     std::unordered_map<int32_t, DragPointerEvent> newIdPoints;
549     for (auto iter = pointEvent.rbegin(); iter != pointEvent.rend(); ++iter) {
550         idToPoints.emplace(iter->pointerId, *iter);
551         idToPoints[iter->pointerId].history.insert(idToPoints[iter->pointerId].history.begin(), *iter);
552         needInterpolation = iter->action != PointerAction::PULL_MOVE ? false : true;
553     }
554     if (!NeedTouchInterpolation()) {
555         needInterpolation = false;
556     }
557     if (needInterpolation) {
558         auto targetTimeStamp = resampleTimeStamp_;
559         for (const auto &idIter : idToPoints) {
560             auto stamp =
561                 std::chrono::duration_cast<std::chrono::nanoseconds>(idIter.second.time.time_since_epoch()).count();
562             if (targetTimeStamp > static_cast<uint64_t>(stamp)) {
563                 LOGI("Skip interpolation when there is no touch event after interpolation time point. "
564                         "(last stamp:%{public}" PRIu64 ", target stamp:%{public}" PRIu64 ")",
565                     static_cast<uint64_t>(stamp), targetTimeStamp);
566                 continue;
567             }
568             DragPointerEvent newPointerEvent = eventManager_->GetResamplePointerEvent(
569                 historyPointsEventById_[idIter.first], idIter.second.history, targetTimeStamp);
570             if (newPointerEvent.x != 0 && newPointerEvent.y != 0) {
571                 newIdPoints[idIter.first] = newPointerEvent;
572             }
573             historyPointsEventById_[idIter.first] = idIter.second.history;
574         }
575     }
576     FlushDragEvents(manager, newIdPoints, extraInfo, idToPoints, node);
577 }
578 
FlushDragEvents(const RefPtr<DragDropManager> & manager,std::unordered_map<int32_t,DragPointerEvent> newIdPoints,std::string & extraInfo,std::unordered_map<int,DragPointerEvent> & idToPoints,const RefPtr<FrameNode> & node)579 void PipelineContext::FlushDragEvents(const RefPtr<DragDropManager>& manager,
580     std::unordered_map<int32_t, DragPointerEvent> newIdPoints,
581     std::string& extraInfo,
582     std::unordered_map<int, DragPointerEvent> &idToPoints,
583     const RefPtr<FrameNode>& node)
584 {
585     std::map<RefPtr<FrameNode>, std::vector<DragPointerEvent>> nodeToPointEvent;
586     std::list<DragPointerEvent> dragPoint;
587     for (const auto& iter : idToPoints) {
588         auto lastDispatchTime = eventManager_->GetLastDispatchTime();
589         lastDispatchTime[iter.first] = GetVsyncTime();
590         eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
591         auto it = newIdPoints.find(iter.first);
592         if (it != newIdPoints.end()) {
593             dragPoint.emplace_back(it->second);
594             nodeToPointEvent[node].emplace_back(it->second);
595         } else {
596             dragPoint.emplace_back(iter.second);
597             nodeToPointEvent[node].emplace_back(iter.second);
598         }
599     }
600     for (auto iter = dragPoint.rbegin(); iter != dragPoint.rend(); ++iter) {
601         manager->OnDragMove(*iter, extraInfo, node);
602     }
603     nodeToPointEvent_ = std::move(nodeToPointEvent);
604 }
605 
FlushVsync(uint64_t nanoTimestamp,uint32_t frameCount)606 void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount)
607 {
608     CHECK_RUN_ON(UI);
609     if (IsDestroyed()) {
610         LOGW("Cannot flush vsync as the pipeline context is destroyed.");
611         return;
612     }
613     SetVsyncTime(nanoTimestamp);
614     ACE_SCOPED_TRACE_COMMERCIAL("UIVsyncTask[timestamp:%" PRIu64 "][vsyncID:%" PRIu64 "][instanceID:%d]",
615         nanoTimestamp, static_cast<uint64_t>(frameCount), instanceId_);
616     window_->Lock();
617     static const std::string abilityName = AceApplicationInfo::GetInstance().GetProcessName().empty()
618                                                ? AceApplicationInfo::GetInstance().GetPackageName()
619                                                : AceApplicationInfo::GetInstance().GetProcessName();
620     window_->RecordFrameTime(nanoTimestamp, abilityName);
621     uint64_t vsyncPeriod = static_cast<uint64_t>(window_->GetVSyncPeriod());
622     uint64_t timeStamp = (nanoTimestamp > vsyncPeriod) ? (nanoTimestamp - vsyncPeriod + ONE_MS_IN_NS) : ONE_MS_IN_NS;
623     resampleTimeStamp_ = (timeStamp > compensationValue_) ? (timeStamp - compensationValue_) : 0;
624 #ifdef UICAST_COMPONENT_SUPPORTED
625     do {
626         auto container = Container::Current();
627         CHECK_NULL_BREAK(container);
628         auto distributedUI = container->GetDistributedUI();
629         CHECK_NULL_BREAK(distributedUI);
630         distributedUI->ApplyOneUpdate();
631     } while (false);
632 #endif
633     ProcessDelayTasks();
634     DispatchDisplaySync(nanoTimestamp);
635     FlushAnimation(nanoTimestamp);
636     FlushFrameCallback(nanoTimestamp);
637     auto hasRunningAnimation = FlushModifierAnimation(nanoTimestamp);
638     FlushTouchEvents();
639     FlushDragEvents();
640     FlushFrameCallbackFromCAPI(nanoTimestamp, frameCount);
641     FlushBuild();
642     if (isFormRender_ && drawDelegate_ && rootNode_) {
643         auto renderContext = AceType::DynamicCast<NG::RenderContext>(rootNode_->GetRenderContext());
644         drawDelegate_->DrawRSFrame(renderContext);
645         drawDelegate_ = nullptr;
646     }
647     if (!taskScheduler_->isEmpty()) {
648 #if !defined(PREVIEW)
649         LayoutInspector::SupportInspector();
650 #endif
651     }
652 
653     taskScheduler_->StartRecordFrameInfo(GetCurrentFrameInfo(recvTime_, nanoTimestamp));
654     taskScheduler_->FlushTask();
655     UIObserverHandler::GetInstance().HandleLayoutDoneCallBack();
656     // flush correct rect again
657     taskScheduler_->FlushPersistAfterLayoutTask();
658     taskScheduler_->FinishRecordFrameInfo();
659     FlushNodeChangeFlag();
660     FlushAnimationClosure();
661     TryCallNextFrameLayoutCallback();
662 
663 #ifdef UICAST_COMPONENT_SUPPORTED
664     do {
665         auto container = Container::Current();
666         CHECK_NULL_BREAK(container);
667         auto distributedUI = container->GetDistributedUI();
668         CHECK_NULL_BREAK(distributedUI);
669         distributedUI->OnTreeUpdate();
670     } while (false);
671 #endif
672 
673     if (hasRunningAnimation || window_->HasUIRunningAnimation()) {
674         RequestFrame();
675     }
676     window_->FlushModifier();
677     FlushFrameRate();
678     if (dragWindowVisibleCallback_) {
679         dragWindowVisibleCallback_();
680         dragWindowVisibleCallback_ = nullptr;
681     }
682     if (isFirstFlushMessages_) {
683         isFirstFlushMessages_ = false;
684         LOGI("ArkUi flush first frame messages.");
685     }
686 #ifdef ENABLE_ROSEN_BACKEND
687     auto isCmdEmpty = false;
688     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
689     if (transactionProxy != nullptr) {
690         isCmdEmpty = transactionProxy->IsEmpty();
691     }
692 #endif
693     FlushMessages();
694     FlushWindowPatternInfo();
695     InspectDrew();
696     UIObserverHandler::GetInstance().HandleDrawCommandSendCallBack();
697     if (onShow_ && onFocus_ && isWindowHasFocused_) {
698         auto isDynamicRender = Container::Current() == nullptr ? false : Container::Current()->IsDynamicRender();
699         if ((!isFormRender_) || isDynamicRender) {
700             FlushFocusView();
701             FlushFocus();
702             FlushFocusScroll();
703         }
704     }
705 #ifdef ENABLE_ROSEN_BACKEND
706     if (!isCmdEmpty) {
707         HandleOnAreaChangeEvent(nanoTimestamp);
708         HandleVisibleAreaChangeEvent(nanoTimestamp);
709     }
710 #else
711     HandleOnAreaChangeEvent(nanoTimestamp);
712     HandleVisibleAreaChangeEvent(nanoTimestamp);
713 #endif
714     FlushMouseEventInVsync();
715     eventManager_->FlushCursorStyleRequests();
716     if (isNeedFlushAnimationStartTime_) {
717         window_->FlushAnimationStartTime(animationTimeStamp_);
718         isNeedFlushAnimationStartTime_ = false;
719     }
720     needRenderNode_.clear();
721     taskScheduler_->FlushAfterRenderTask();
722     window_->FlushLayoutSize(width_, height_);
723     if (IsFocusWindowIdSetted()) {
724         FireAllUIExtensionEvents();
725     }
726     FireAccessibilityEvents();
727     // Keep the call sent at the end of the function
728     ResSchedReport::GetInstance().LoadPageEvent(ResDefine::LOAD_PAGE_COMPLETE_EVENT);
729     TriggerFrameDumpFuncIfExist();
730     window_->Unlock();
731 #ifdef COMPONENT_TEST_ENABLED
732     ComponentTest::UpdatePipelineStatus();
733 #endif // COMPONENT_TEST_ENABLED
734 }
735 
FlushMouseEventVoluntarily()736 void PipelineContext::FlushMouseEventVoluntarily()
737 {
738     if (!lastMouseEvent_ || lastMouseEvent_->action == MouseAction::WINDOW_LEAVE) {
739         return;
740     }
741     CHECK_RUN_ON(UI);
742     CHECK_NULL_VOID(rootNode_);
743 
744     MouseEvent event;
745     if (isNeedFlushMouseEvent_ == MockFlushEventType::REJECT) {
746         event.mockFlushEvent = true;
747     }
748     event.x = lastMouseEvent_->x;
749     event.y = lastMouseEvent_->y;
750     event.time = lastMouseEvent_->time;
751     event.action = MouseAction::MOVE;
752     event.button = MouseButton::NONE_BUTTON;
753     event.sourceType = SourceType::MOUSE;
754     event.deviceId = lastMouseEvent_->deviceId;
755     event.sourceTool = SourceTool::MOUSE;
756 
757     auto scaleEvent = event.CreateScaleEvent(viewScale_);
758     TouchRestrict touchRestrict { TouchRestrict::NONE };
759     touchRestrict.sourceType = event.sourceType;
760     touchRestrict.hitTestType = SourceType::MOUSE;
761     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
762 
763     eventManager_->MouseTest(scaleEvent, rootNode_, touchRestrict);
764     eventManager_->DispatchMouseEventNG(scaleEvent);
765     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
766     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
767 }
768 
FlushWindowPatternInfo()769 void PipelineContext::FlushWindowPatternInfo()
770 {
771 #ifdef WINDOW_SCENE_SUPPORTED
772     OTHER_DURATION();
773     auto container = Container::Current();
774     CHECK_NULL_VOID(container);
775     if (!container->IsScenceBoardWindow()) {
776         return;
777     }
778     auto screenNode = screenNode_.Upgrade();
779     if (!screenNode) {
780         return;
781     }
782     ACE_SCOPED_TRACE("FlushWindowPatternInfo");
783     auto instance = WindowSceneLayoutManager::GetInstance();
784     if (instance != nullptr) {
785         instance->FlushWindowPatternInfo(screenNode);
786     }
787 #endif
788 }
789 
InspectDrew()790 void PipelineContext::InspectDrew()
791 {
792     CHECK_RUN_ON(UI);
793     if (!needRenderNode_.empty()) {
794         auto needRenderNode = std::move(needRenderNode_);
795         for (auto&& nodeWeak : needRenderNode) {
796             auto node = nodeWeak.Upgrade();
797             if (!node) {
798                 return;
799             }
800             if (node->GetInspectorId().has_value()) {
801                 OnDrawCompleted(node->GetInspectorId()->c_str());
802             }
803             auto eventHub = node->GetEventHub<NG::EventHub>();
804             CHECK_NULL_VOID(eventHub);
805             eventHub->FireDrawCompletedNDKCallback(this);
806         }
807     }
808 }
809 
ProcessDelayTasks()810 void PipelineContext::ProcessDelayTasks()
811 {
812     if (delayedTasks_.empty()) {
813         return;
814     }
815     auto currentTimeStamp = GetSysTimestamp();
816     auto delayedTasks = std::move(delayedTasks_);
817     auto result = std::remove_if(delayedTasks.begin(), delayedTasks.end(), [this, currentTimeStamp](const auto& task) {
818         if (task.timeStamp + static_cast<int64_t>(task.time) * MILLISECONDS_TO_NANOSECONDS > currentTimeStamp) {
819             delayedTasks_.emplace_back(task);
820             return true;
821         }
822         return false;
823     });
824     delayedTasks.erase(result, delayedTasks.end());
825     std::for_each(delayedTasks.begin(), delayedTasks.end(), [this](auto& delayedTask) {
826         if (delayedTask.task) {
827             delayedTask.task();
828         }
829     });
830 }
831 
DispatchDisplaySync(uint64_t nanoTimestamp)832 void PipelineContext::DispatchDisplaySync(uint64_t nanoTimestamp)
833 {
834     OTHER_DURATION();
835     CHECK_RUN_ON(UI);
836     ACE_FUNCTION_TRACE();
837 
838     const auto& displaySyncManager = GetOrCreateUIDisplaySyncManager();
839     if (!displaySyncManager) {
840         TAG_LOGE(AceLogTag::ACE_DISPLAY_SYNC, "[DispatchDisplaySync] displaySyncManager is nullptr.");
841         return;
842     }
843 
844     displaySyncManager->SetRefreshRateMode(window_->GetCurrentRefreshRateMode());
845     displaySyncManager->SetVsyncPeriod(window_->GetVSyncPeriod());
846 
847     if (FrameReport::GetInstance().GetEnable()) {
848         FrameReport::GetInstance().BeginFlushAnimation();
849     }
850 
851     scheduleTasks_.clear();
852     displaySyncManager->DispatchFunc(nanoTimestamp);
853 
854     if (FrameReport::GetInstance().GetEnable()) {
855         FrameReport::GetInstance().EndFlushAnimation();
856     }
857 
858     int32_t displaySyncRate = displaySyncManager->GetDisplaySyncRate();
859     frameRateManager_->SetDisplaySyncRate(displaySyncRate);
860     auto monitorVsyncRate = displaySyncManager->GetMonitorVsyncRate();
861     ArkUIPerfMonitor::GetInstance().RecordDisplaySyncRate(monitorVsyncRate);
862 }
863 
FlushAnimation(uint64_t nanoTimestamp)864 void PipelineContext::FlushAnimation(uint64_t nanoTimestamp)
865 {
866     OTHER_DURATION();
867     CHECK_RUN_ON(UI);
868     ACE_FUNCTION_TRACE();
869     if (scheduleTasks_.empty()) {
870         return;
871     }
872 }
873 
FlushModifier()874 void PipelineContext::FlushModifier()
875 {
876     window_->FlushModifier();
877 }
878 
HandleSpecialContainerNode()879 void PipelineContext::HandleSpecialContainerNode()
880 {
881     if (!SystemProperties::GetContainerDeleteFlag()) {
882         return;
883     }
884 
885     auto positionZSet = GetPositionZNodes();
886     for (auto positionZNodeId : positionZSet) {
887         auto frameNode = DynamicCast<FrameNode>(ElementRegister::GetInstance()->GetUINodeById(positionZNodeId));
888         if (!frameNode) {
889             continue;
890         }
891         auto parentNode = frameNode->GetParentFrameNode();
892         if (!parentNode) {
893             continue;
894         }
895         if (parentNode->GetRenderContext()) {
896             parentNode->GetRenderContext()->SetDrawNode();
897         }
898         std::list<RefPtr<FrameNode>> childrenList;
899         parentNode->GenerateOneDepthVisibleFrameWithTransition(childrenList);
900         for (auto& node : childrenList) {
901             if (node && node->GetRenderContext()) {
902                 node->GetRenderContext()->SetDrawNode();
903             }
904         }
905         auto overlayNode = parentNode->GetOverlayNode();
906         if (overlayNode && overlayNode->GetRenderContext()) {
907             overlayNode->GetRenderContext()->SetDrawNode();
908         }
909         auto accessibilityFocusPaintNode = parentNode->GetFocusPaintNode();
910         if (accessibilityFocusPaintNode && accessibilityFocusPaintNode->GetRenderContext()) {
911             accessibilityFocusPaintNode->GetRenderContext()->SetDrawNode();
912         }
913     }
914     ClearPositionZNodes();
915 }
916 
FlushMessages()917 void PipelineContext::FlushMessages()
918 {
919     OTHER_DURATION();
920     ACE_FUNCTION_TRACE_COMMERCIAL();
921     if (IsFreezeFlushMessage()) {
922         SetIsFreezeFlushMessage(false);
923         LOGI("Flush message is freezed.");
924         return;
925     }
926     if (navigationMgr_) {
927         navigationMgr_->CacheNavigationNodeAnimation();
928     }
929     if (!window_->GetIsRequestFrame()) {
930         ACE_SCOPED_TRACE("smart gc end with no request frame(app_start or push_page)!");
931         ResSchedReport::GetInstance().ResSchedDataReport("page_end_flush", {});
932     }
933     HandleSpecialContainerNode();
934     window_->FlushTasks();
935 }
936 
FlushUITasks(bool triggeredByImplicitAnimation)937 void PipelineContext::FlushUITasks(bool triggeredByImplicitAnimation)
938 {
939     window_->Lock();
940     if (!CheckThreadSafe()) {
941         LOGW("FlushUITasks doesn't run on UI thread!");
942     }
943     decltype(dirtyPropertyNodes_) dirtyPropertyNodes(std::move(dirtyPropertyNodes_));
944     dirtyPropertyNodes_.clear();
945     for (const auto& dirtyNode : dirtyPropertyNodes) {
946         dirtyNode->ProcessPropertyDiff();
947     }
948     taskScheduler_->FlushTaskWithCheck(triggeredByImplicitAnimation);
949     if (AnimationUtils::IsImplicitAnimationOpen()) {
950         FlushNodeChangeFlag();
951     }
952     window_->Unlock();
953 }
954 
FlushUITaskWithSingleDirtyNode(const RefPtr<FrameNode> & node)955 void PipelineContext::FlushUITaskWithSingleDirtyNode(const RefPtr<FrameNode>& node)
956 {
957     CHECK_NULL_VOID(node);
958     if (IsLayouting()) {
959         taskScheduler_->AddSingleNodeToFlush(node);
960         return;
961     }
962     auto layoutProperty = node->GetLayoutProperty();
963     CHECK_NULL_VOID(layoutProperty);
964     auto layoutConstraint = node->GetLayoutConstraint();
965     auto originLayoutingFlag = IsLayouting();
966     SetIsLayouting(true);
967     if (layoutProperty->GetLayoutRect()) {
968         node->SetActive(true, true);
969         node->Measure(std::nullopt);
970         node->Layout();
971     } else {
972         auto ancestorNodeOfFrame = node->GetAncestorNodeOfFrame(false);
973         {
974             ACE_SCOPED_TRACE("FlushUITaskWithSingleDirtyNodeMeasure[%s][self:%d][parent:%d][layoutConstraint:%s]"
975                              "[pageId:%d][depth:%d]",
976                 node->GetTag().c_str(), node->GetId(), ancestorNodeOfFrame ? ancestorNodeOfFrame->GetId() : 0,
977                 layoutConstraint.ToString().c_str(), node->GetPageId(), node->GetDepth());
978             node->Measure(layoutConstraint);
979         }
980         {
981             ACE_SCOPED_TRACE("FlushUITaskWithSingleDirtyNodeLayout[%s][self:%d][parent:%d][pageId:%d][depth:%d]",
982                 node->GetTag().c_str(), node->GetId(), ancestorNodeOfFrame ? ancestorNodeOfFrame->GetId() : 0,
983                 node->GetPageId(), node->GetDepth());
984             node->Layout();
985         }
986     }
987     SetIsLayouting(originLayoutingFlag);
988 }
989 
FlushAfterLayoutCallbackInImplicitAnimationTask()990 void PipelineContext::FlushAfterLayoutCallbackInImplicitAnimationTask()
991 {
992     if (AnimationUtils::IsImplicitAnimationOpen()) {
993         TAG_LOGD(AceLogTag::ACE_ANIMATION,
994             "Can not flush implicit animation task after layout because implicit animation is open.");
995         return;
996     }
997     window_->Lock();
998     taskScheduler_->FlushAfterLayoutCallbackInImplicitAnimationTask();
999     window_->Unlock();
1000 }
1001 
SetNeedRenderNode(const WeakPtr<FrameNode> & node)1002 void PipelineContext::SetNeedRenderNode(const WeakPtr<FrameNode>& node)
1003 {
1004     CHECK_RUN_ON(UI);
1005     needRenderNode_.insert(node);
1006 }
1007 
FlushFocus()1008 void PipelineContext::FlushFocus()
1009 {
1010     CHECK_RUN_ON(UI);
1011     ACE_FUNCTION_TRACK();
1012     ACE_FUNCTION_TRACE();
1013 
1014     FlushRequestFocus();
1015 
1016     auto focusNode = dirtyFocusNode_.Upgrade();
1017     if (!focusNode || focusNode->GetFocusType() != FocusType::NODE) {
1018         dirtyFocusNode_.Reset();
1019     } else {
1020         FlushFocusWithNode(focusNode, false);
1021         return;
1022     }
1023     auto focusScope = dirtyFocusScope_.Upgrade();
1024     if (!focusScope || focusScope->GetFocusType() != FocusType::SCOPE) {
1025         dirtyFocusScope_.Reset();
1026     } else {
1027         FlushFocusWithNode(focusScope, true);
1028         return;
1029     }
1030     GetOrCreateFocusManager()->WindowFocusMoveEnd();
1031 }
1032 
FlushFocusWithNode(RefPtr<FrameNode> focusNode,bool isScope)1033 void PipelineContext::FlushFocusWithNode(RefPtr<FrameNode> focusNode, bool isScope)
1034 {
1035     auto focusNodeHub = focusNode->GetFocusHub();
1036     if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
1037         auto unfocusableParentFocusNode = focusNodeHub->GetUnfocusableParentFocusNode().Upgrade();
1038         if (unfocusableParentFocusNode) {
1039             TAG_LOGI(AceLogTag::ACE_FOCUS,
1040                 "Request focus on %{public}s: %{public}s/%{public}d return false, unfocusable node: "
1041                 "%{public}s/%{public}d, focusable = %{public}d, shown = %{public}d, enabled = %{public}d",
1042                 isScope ? "scope" : "node", focusNode->GetTag().c_str(), focusNode->GetId(),
1043                 unfocusableParentFocusNode->GetFrameName().c_str(), unfocusableParentFocusNode->GetFrameId(),
1044                 unfocusableParentFocusNode->GetFocusable(), unfocusableParentFocusNode->IsShow(),
1045                 unfocusableParentFocusNode->IsEnabled());
1046             unfocusableParentFocusNode = nullptr;
1047         } else {
1048             TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus on %{public}s: %{public}s/%{public}d return false",
1049                 isScope ? "scope" : "node", focusNode->GetTag().c_str(), focusNode->GetId());
1050         }
1051     }
1052     dirtyFocusNode_.Reset();
1053     dirtyFocusScope_.Reset();
1054     dirtyRequestFocusNode_.Reset();
1055     GetOrCreateFocusManager()->WindowFocusMoveEnd();
1056 }
1057 
FlushRequestFocus()1058 void PipelineContext::FlushRequestFocus()
1059 {
1060     CHECK_RUN_ON(UI);
1061 
1062     auto requestFocusNode = dirtyRequestFocusNode_.Upgrade();
1063     if (!requestFocusNode) {
1064         dirtyRequestFocusNode_.Reset();
1065     } else {
1066         auto focusNodeHub = requestFocusNode->GetFocusHub();
1067         if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
1068             auto unfocusableParentFocusNode = focusNodeHub->GetUnfocusableParentFocusNode().Upgrade();
1069             if (unfocusableParentFocusNode) {
1070                 TAG_LOGI(AceLogTag::ACE_FOCUS,
1071                     "Request focus by id on node: %{public}s/%{public}d return false, unfocusable node: "
1072                     "%{public}s/%{public}d, focusable = %{public}d, shown = %{public}d, enabled = %{public}d",
1073                     requestFocusNode->GetTag().c_str(), requestFocusNode->GetId(),
1074                     unfocusableParentFocusNode->GetFrameName().c_str(), unfocusableParentFocusNode->GetFrameId(),
1075                     unfocusableParentFocusNode->GetFocusable(), unfocusableParentFocusNode->IsShow(),
1076                     unfocusableParentFocusNode->IsEnabled());
1077                 unfocusableParentFocusNode = nullptr;
1078             } else {
1079                 TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus by id on node: %{public}s/%{public}d return false",
1080                     requestFocusNode->GetTag().c_str(), requestFocusNode->GetId());
1081             }
1082         }
1083         dirtyFocusNode_.Reset();
1084         dirtyFocusScope_.Reset();
1085         dirtyRequestFocusNode_.Reset();
1086         return;
1087     }
1088 }
1089 
FlushFocusView()1090 void PipelineContext::FlushFocusView()
1091 {
1092     CHECK_NULL_VOID(focusManager_);
1093     auto lastFocusView = (focusManager_->GetLastFocusView()).Upgrade();
1094     CHECK_NULL_VOID(lastFocusView);
1095     auto lastFocusViewHub = lastFocusView->GetFocusHub();
1096     CHECK_NULL_VOID(lastFocusViewHub);
1097     ACE_SCOPED_TRACE("FlushFocusView:[%s][enable:%d][show:%d]", lastFocusViewHub->GetFrameName().c_str(),
1098         lastFocusViewHub->IsEnabled(), lastFocusViewHub->IsShow());
1099     auto container = Container::Current();
1100     if (container && (container->IsUIExtensionWindow() || container->IsDynamicRender()) &&
1101         (!lastFocusView->IsRootScopeCurrentFocus())) {
1102         lastFocusView->SetIsViewRootScopeFocused(false);
1103     }
1104     if (lastFocusView && (!lastFocusView->IsRootScopeCurrentFocus() || !lastFocusView->GetIsViewHasFocused()) &&
1105         lastFocusViewHub->IsFocusableNode()) {
1106         lastFocusView->RequestDefaultFocus();
1107         focusManager_->SetFocusViewStackState(FocusViewStackState::IDLE);
1108     }
1109 }
1110 
FlushFocusScroll()1111 void PipelineContext::FlushFocusScroll()
1112 {
1113     CHECK_NULL_VOID(focusManager_);
1114     if (!focusManager_->GetNeedTriggerScroll()) {
1115         return;
1116     }
1117     auto lastFocusStateNode = focusManager_->GetLastFocusStateNode();
1118     CHECK_NULL_VOID(lastFocusStateNode);
1119     if (!lastFocusStateNode->TriggerFocusScroll()) {
1120         focusManager_->SetNeedTriggerScroll(false);
1121     }
1122 }
1123 
FlushPipelineImmediately()1124 void PipelineContext::FlushPipelineImmediately()
1125 {
1126     CHECK_RUN_ON(UI);
1127     ACE_SCOPED_TRACE("PipelineContext::FlushPipelineImmediately, isLayouting_ %d", taskScheduler_->IsLayouting());
1128     if (!taskScheduler_->IsLayouting()) {
1129         FlushPipelineWithoutAnimation();
1130         return;
1131     }
1132     auto task = [weak = WeakClaim(this)]() {
1133         auto pipeline = weak.Upgrade();
1134         CHECK_NULL_VOID(pipeline);
1135         pipeline->FlushPipelineWithoutAnimation();
1136     };
1137     AddAfterLayoutTask(task);
1138 }
1139 
RebuildFontNode()1140 void PipelineContext::RebuildFontNode()
1141 {
1142     if (fontManager_) {
1143         fontManager_->RebuildFontNodeNG();
1144     }
1145 }
1146 
FlushPipelineWithoutAnimation()1147 void PipelineContext::FlushPipelineWithoutAnimation()
1148 {
1149     ACE_FUNCTION_TRACE();
1150     window_->Lock();
1151     FlushBuild();
1152     FlushTouchEvents();
1153     taskScheduler_->FlushTask();
1154     FlushAnimationClosure();
1155     window_->FlushModifier();
1156     FlushMessages();
1157     FlushFocus();
1158     window_->Unlock();
1159 }
1160 
FlushFrameRate()1161 void PipelineContext::FlushFrameRate()
1162 {
1163     frameRateManager_->SetAnimateRate(window_->GetAnimateExpectedRate(), window_->HasFirstFrameAnimation());
1164     int32_t currAnimatorExpectedFrameRate = GetOrCreateUIDisplaySyncManager()->GetAnimatorRate();
1165     if (frameRateManager_->IsRateChanged() || currAnimatorExpectedFrameRate != lastAnimatorExpectedFrameRate_) {
1166         auto [rate, rateType] = frameRateManager_->GetExpectedRate();
1167         ACE_SCOPED_TRACE("FlushFrameRate Expected frameRate = %d frameRateType = %d "
1168             "currAnimatorExpectedFrameRate = %d, lastAnimatorExpectedFrameRate = %d",
1169             rate, rateType, currAnimatorExpectedFrameRate, lastAnimatorExpectedFrameRate_);
1170         TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "FlushFrameRate Expected frameRate = %{public}d "
1171             "frameRateType = %{public}d currAnimatorExpectedFrameRate = %{public}d, lastRate = %{public}d",
1172             rate, rateType, currAnimatorExpectedFrameRate, lastAnimatorExpectedFrameRate_);
1173         window_->FlushFrameRate(rate, currAnimatorExpectedFrameRate, rateType);
1174         frameRateManager_->SetIsRateChanged(false);
1175         lastAnimatorExpectedFrameRate_ = currAnimatorExpectedFrameRate;
1176     }
1177 }
1178 
FlushBuild()1179 void PipelineContext::FlushBuild()
1180 {
1181     if (vsyncListener_ != nullptr) {
1182         ACE_SCOPED_TRACE("arkoala build");
1183         vsyncListener_();
1184     }
1185     FlushOnceVsyncTask();
1186     isRebuildFinished_ = false;
1187     FlushDirtyNodeUpdate();
1188     isRebuildFinished_ = true;
1189     FlushBuildFinishCallbacks();
1190 }
1191 
AddAnimationClosure(std::function<void ()> && animation)1192 void PipelineContext::AddAnimationClosure(std::function<void()>&& animation)
1193 {
1194     animationClosuresList_.emplace_back(std::move(animation));
1195 }
1196 
FlushAnimationClosure()1197 void PipelineContext::FlushAnimationClosure()
1198 {
1199     if (animationClosuresList_.empty()) {
1200         return;
1201     }
1202     window_->Lock();
1203     taskScheduler_->FlushTask();
1204 
1205     decltype(animationClosuresList_) temp(std::move(animationClosuresList_));
1206     for (const auto& animation : temp) {
1207         animation();
1208     }
1209     window_->Unlock();
1210 }
1211 
FlushBuildFinishCallbacks()1212 void PipelineContext::FlushBuildFinishCallbacks()
1213 {
1214     decltype(buildFinishCallbacks_) buildFinishCallbacks(std::move(buildFinishCallbacks_));
1215     for (const auto& func : buildFinishCallbacks) {
1216         if (func) {
1217             func();
1218         }
1219     }
1220 }
1221 
RegisterRootEvent()1222 void PipelineContext::RegisterRootEvent()
1223 {
1224     if (!IsFormRender()) {
1225         return;
1226     }
1227     auto accessibilityProperty = rootNode_->GetAccessibilityProperty<AccessibilityProperty>();
1228     if (accessibilityProperty != nullptr) {
1229         accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
1230     }
1231 
1232     // To avoid conflicts between longPress and click events on the card,
1233     // use an empty longPress event placeholder in the EtsCard scenario
1234     auto hub = rootNode_->GetOrCreateGestureEventHub();
1235     CHECK_NULL_VOID(hub);
1236     auto event = [](const GestureEvent& info) mutable {};
1237     auto longPress = AceType::MakeRefPtr<NG::LongPressEvent>(std::move(event));
1238     hub->SetLongPressEvent(longPress, false, true);
1239 }
1240 
SetupRootElement()1241 void PipelineContext::SetupRootElement()
1242 {
1243     CHECK_RUN_ON(UI);
1244     auto rootPattern = ViewAdvancedRegister::GetInstance()->GeneratePattern(V2::ROOT_ETS_TAG);
1245     if (!rootPattern) {
1246         rootPattern = MakeRefPtr<RootPattern>();
1247     }
1248     rootNode_ = FrameNode::CreateFrameNodeWithTree(
1249         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), rootPattern);
1250     rootNode_->SetHostRootId(GetInstanceId());
1251     rootNode_->SetHostPageId(-1);
1252     rootNode_->SetActive(true);
1253     RegisterRootEvent();
1254     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
1255     MeasureProperty layoutConstraint;
1256     layoutConstraint.selfIdealSize = idealSize;
1257     layoutConstraint.maxSize = idealSize;
1258     rootNode_->UpdateLayoutConstraint(layoutConstraint);
1259     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
1260     rootFocusHub->SetFocusType(FocusType::SCOPE);
1261     rootFocusHub->SetFocusable(true);
1262     window_->SetRootFrameNode(rootNode_);
1263     rootNode_->AttachToMainTree(false, this);
1264     auto stagePattern = ViewAdvancedRegister::GetInstance()->GeneratePattern(V2::STAGE_ETS_TAG);
1265     if (!stagePattern) {
1266         stagePattern = MakeRefPtr<StagePattern>();
1267     }
1268     auto stageNode = FrameNode::CreateFrameNode(
1269         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), stagePattern);
1270     RefPtr<AppBarView> appBar = AceType::MakeRefPtr<AppBarView>();
1271     auto atomicService = installationFree_ ? appBar->Create(stageNode) : nullptr;
1272     auto container = Container::Current();
1273     if (container) {
1274         container->SetAppBar(appBar);
1275     }
1276     if (windowModal_ == WindowModal::CONTAINER_MODAL) {
1277         MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
1278         rootNode_->AddChild(
1279             ContainerModalViewFactory::GetView(atomicService ? atomicService : stageNode, maximizeMode));
1280     } else {
1281         rootNode_->AddChild(atomicService ? atomicService : stageNode);
1282     }
1283 #ifdef ENABLE_ROSEN_BACKEND
1284     if (!IsJsCard() && !isFormRender_) {
1285         auto window = GetWindow();
1286         if (window) {
1287             auto rsUIDirector = window->GetRSUIDirector();
1288             if (rsUIDirector) {
1289                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
1290             }
1291         }
1292     }
1293 #endif
1294     accessibilityManagerNG_ = MakeRefPtr<AccessibilityManagerNG>();
1295     stageManager_ = ViewAdvancedRegister::GetInstance()->GenerateStageManager(stageNode);
1296     if (!stageManager_) {
1297         stageManager_ = MakeRefPtr<StageManager>(stageNode);
1298     }
1299     auto getPagePathCallback = [weakFrontend = weakFrontend_](const std::string& url) -> std::string {
1300         auto frontend = weakFrontend.Upgrade();
1301         CHECK_NULL_RETURN(frontend, "");
1302         return frontend->GetPagePathByUrl(url);
1303     };
1304     stageManager_->SetGetPagePathCallback(std::move(getPagePathCallback));
1305     auto frameNode = DynamicCast<FrameNode>(installationFree_ ? atomicService->GetParent() :
1306         stageNode->GetParent());
1307     overlayManager_ = MakeRefPtr<OverlayManager>(frameNode);
1308     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
1309     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
1310     fontManager_->AddFontObserver(selectOverlayManager_);
1311     if (!privacySensitiveManager_) {
1312         privacySensitiveManager_ = MakeRefPtr<PrivacySensitiveManager>();
1313     }
1314     postEventManager_ = MakeRefPtr<PostEventManager>();
1315     dragDropManager_ = MakeRefPtr<DragDropManager>();
1316     focusManager_ = GetOrCreateFocusManager();
1317     sharedTransitionManager_ = MakeRefPtr<SharedOverlayManager>(
1318         DynamicCast<FrameNode>(installationFree_ ? atomicService->GetParent() : stageNode->GetParent()));
1319 
1320     OnAreaChangedFunc onAreaChangedFunc = [weakOverlayManger = AceType::WeakClaim(AceType::RawPtr(overlayManager_))](
1321                                               const RectF& /* oldRect */, const OffsetF& /* oldOrigin */,
1322                                               const RectF& /* rect */, const OffsetF& /* origin */) {
1323         TAG_LOGI(AceLogTag::ACE_OVERLAY, "start OnAreaChangedFunc");
1324         auto overlay = weakOverlayManger.Upgrade();
1325         CHECK_NULL_VOID(overlay);
1326         overlay->HideAllMenus();
1327         SubwindowManager::GetInstance()->HideMenuNG(false);
1328         overlay->HideCustomPopups();
1329         SubwindowManager::GetInstance()->ClearToastInSubwindow();
1330         SubwindowManager::GetInstance()->ClearToastInSystemSubwindow();
1331         overlay->UpdateCustomKeyboardPosition();
1332     };
1333     rootNode_->SetOnAreaChangeCallback(std::move(onAreaChangedFunc));
1334     AddOnAreaChangeNode(rootNode_->GetId());
1335 }
1336 
SetOnWindowFocused(const std::function<void ()> & callback)1337 void PipelineContext::SetOnWindowFocused(const std::function<void()>& callback)
1338 {
1339     CHECK_NULL_VOID(taskExecutor_);
1340     taskExecutor_->PostTask([weak = WeakClaim(this), callback]() {
1341             auto pipeline = weak.Upgrade();
1342             CHECK_NULL_VOID(pipeline);
1343             pipeline->focusOnNodeCallback_ = callback;
1344         }, TaskExecutor::TaskType::UI, "ArkUISetOnWindowFocusedCallback");
1345 }
1346 
SetupSubRootElement()1347 void PipelineContext::SetupSubRootElement()
1348 {
1349     CHECK_RUN_ON(UI);
1350     appBgColor_ = Color::TRANSPARENT;
1351     auto rootPattern = ViewAdvancedRegister::GetInstance()->GeneratePattern(V2::ROOT_ETS_TAG);
1352     if (!rootPattern) {
1353         rootPattern = MakeRefPtr<RootPattern>();
1354     }
1355     rootNode_ = FrameNode::CreateFrameNodeWithTree(
1356         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), rootPattern);
1357     rootNode_->SetHostRootId(GetInstanceId());
1358     rootNode_->SetHostPageId(-1);
1359     rootNode_->SetActive(true);
1360     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
1361     MeasureProperty layoutConstraint;
1362     layoutConstraint.selfIdealSize = idealSize;
1363     layoutConstraint.maxSize = idealSize;
1364     rootNode_->UpdateLayoutConstraint(layoutConstraint);
1365     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
1366     rootFocusHub->SetFocusType(FocusType::SCOPE);
1367     rootFocusHub->SetFocusable(true);
1368     window_->SetRootFrameNode(rootNode_);
1369     rootNode_->AttachToMainTree(false, this);
1370 
1371 #ifdef ENABLE_ROSEN_BACKEND
1372     if (!IsJsCard()) {
1373         auto window = GetWindow();
1374         if (window) {
1375             auto rsUIDirector = window->GetRSUIDirector();
1376             if (rsUIDirector) {
1377                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
1378             }
1379         }
1380     }
1381 #endif
1382 #ifdef WINDOW_SCENE_SUPPORTED
1383     uiExtensionManager_ = MakeRefPtr<UIExtensionManager>();
1384 #endif
1385     accessibilityManagerNG_ = MakeRefPtr<AccessibilityManagerNG>();
1386     // the subwindow for overlay not need stage
1387     stageManager_ = ViewAdvancedRegister::GetInstance()->GenerateStageManager(nullptr);
1388     if (!stageManager_) {
1389         stageManager_ = MakeRefPtr<StageManager>(nullptr);
1390     }
1391     auto getPagePathCallback = [weakFrontend = weakFrontend_](const std::string& url) -> std::string {
1392         auto frontend = weakFrontend.Upgrade();
1393         CHECK_NULL_RETURN(frontend, "");
1394         return frontend->GetPagePathByUrl(url);
1395     };
1396     stageManager_->SetGetPagePathCallback(std::move(getPagePathCallback));
1397     overlayManager_ = MakeRefPtr<OverlayManager>(rootNode_);
1398     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
1399     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
1400     fontManager_->AddFontObserver(selectOverlayManager_);
1401     dragDropManager_ = MakeRefPtr<DragDropManager>();
1402     focusManager_ = GetOrCreateFocusManager();
1403     postEventManager_ = MakeRefPtr<PostEventManager>();
1404 }
1405 
GetAccessibilityManagerNG()1406 RefPtr<AccessibilityManagerNG> PipelineContext::GetAccessibilityManagerNG()
1407 {
1408     return accessibilityManagerNG_;
1409 }
1410 
SendEventToAccessibilityWithNode(const AccessibilityEvent & accessibilityEvent,const RefPtr<FrameNode> & node)1411 void PipelineContext::SendEventToAccessibilityWithNode(
1412     const AccessibilityEvent& accessibilityEvent, const RefPtr<FrameNode>& node)
1413 {
1414     auto accessibilityManager = GetAccessibilityManager();
1415     if (!accessibilityManager || !AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
1416         return;
1417     }
1418     accessibilityManager->SendEventToAccessibilityWithNode(accessibilityEvent, node, Claim(this));
1419 }
1420 
GetStageManager()1421 const RefPtr<StageManager>& PipelineContext::GetStageManager()
1422 {
1423     return stageManager_;
1424 }
1425 
GetDragDropManager()1426 const RefPtr<DragDropManager>& PipelineContext::GetDragDropManager()
1427 {
1428     return dragDropManager_;
1429 }
1430 
GetFocusManager() const1431 const RefPtr<FocusManager>& PipelineContext::GetFocusManager() const
1432 {
1433     return focusManager_;
1434 }
1435 
GetOrCreateFocusManager()1436 const RefPtr<FocusManager>& PipelineContext::GetOrCreateFocusManager()
1437 {
1438     if (!focusManager_) {
1439         focusManager_ = MakeRefPtr<FocusManager>(AceType::Claim(this));
1440         RegisterFocusCallback();
1441     }
1442     return focusManager_;
1443 }
1444 
GetSelectOverlayManager()1445 const RefPtr<SelectOverlayManager>& PipelineContext::GetSelectOverlayManager()
1446 {
1447     return selectOverlayManager_;
1448 }
1449 
GetOverlayManager()1450 const RefPtr<OverlayManager>& PipelineContext::GetOverlayManager()
1451 {
1452     return overlayManager_;
1453 }
1454 
GetFullScreenManager()1455 const RefPtr<FullScreenManager>& PipelineContext::GetFullScreenManager()
1456 {
1457     return fullScreenManager_;
1458 }
1459 
OnSurfaceChanged(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1460 void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type,
1461     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1462 {
1463     CHECK_RUN_ON(UI);
1464     width_ = width;
1465     height_ = height;
1466     if (NearEqual(rootWidth_, width) && NearEqual(rootHeight_, height) &&
1467         type == WindowSizeChangeReason::CUSTOM_ANIMATION && !isDensityChanged_) {
1468         TryCallNextFrameLayoutCallback();
1469         return;
1470     }
1471     ExecuteSurfaceChangedCallbacks(width, height, type);
1472     auto callback = [weakFrontend = weakFrontend_, width, height]() {
1473         auto frontend = weakFrontend.Upgrade();
1474         if (frontend) {
1475             frontend->OnSurfaceChanged(width, height);
1476         }
1477     };
1478     auto container = Container::Current();
1479     if (!container) {
1480         return;
1481     }
1482     if (container->IsUseStageModel()) {
1483         callback();
1484         FlushBuild();
1485     } else {
1486         taskExecutor_->PostTask(callback, TaskExecutor::TaskType::JS, "ArkUISurfaceChanged");
1487     }
1488 
1489     FlushWindowSizeChangeCallback(width, height, type);
1490     UpdateHalfFoldHoverProperty(width, height);
1491     UpdateSizeChangeReason(type, rsTransaction);
1492 
1493 #ifdef ENABLE_ROSEN_BACKEND
1494     StartWindowSizeChangeAnimate(width, height, type, rsTransaction);
1495 #else
1496     SetRootRect(width, height, 0.0);
1497 #endif
1498 }
1499 
UpdateHalfFoldHoverProperty(int32_t windowWidth,int32_t windowHeight)1500 void PipelineContext::UpdateHalfFoldHoverProperty(int32_t windowWidth, int32_t windowHeight)
1501 {
1502     isHoverModeChanged_ = false;
1503     preIsHalfFoldHoverStatus_ = isHalfFoldHoverStatus_;
1504     UpdateHalfFoldHoverStatus(windowWidth, windowHeight);
1505     if (preIsHalfFoldHoverStatus_ != isHalfFoldHoverStatus_) {
1506         isHoverModeChanged_ = true;
1507     }
1508 }
1509 
OnLayoutCompleted(const std::string & componentId)1510 void PipelineContext::OnLayoutCompleted(const std::string& componentId)
1511 {
1512     CHECK_RUN_ON(UI);
1513     auto frontend = weakFrontend_.Upgrade();
1514     if (frontend) {
1515         frontend->OnLayoutCompleted(componentId);
1516     }
1517 }
1518 
OnDrawCompleted(const std::string & componentId)1519 void PipelineContext::OnDrawCompleted(const std::string& componentId)
1520 {
1521     CHECK_RUN_ON(UI);
1522     auto frontend = weakFrontend_.Upgrade();
1523     if (frontend) {
1524         frontend->OnDrawCompleted(componentId);
1525     }
1526 }
1527 
ExecuteSurfaceChangedCallbacks(int32_t newWidth,int32_t newHeight,WindowSizeChangeReason type)1528 void PipelineContext::ExecuteSurfaceChangedCallbacks(int32_t newWidth, int32_t newHeight, WindowSizeChangeReason type)
1529 {
1530     for (auto&& [id, callback] : surfaceChangedCallbackMap_) {
1531         if (callback) {
1532             callback(newWidth, newHeight, rootWidth_, rootHeight_, type);
1533         }
1534     }
1535 }
1536 
OnSurfacePositionChanged(int32_t posX,int32_t posY)1537 void PipelineContext::OnSurfacePositionChanged(int32_t posX, int32_t posY)
1538 {
1539     for (auto&& [id, callback] : surfacePositionChangedCallbackMap_) {
1540         if (callback) {
1541             callback(posX, posY);
1542         }
1543     }
1544 }
1545 
OnFoldStatusChange(FoldStatus foldStatus)1546 void PipelineContext::OnFoldStatusChange(FoldStatus foldStatus)
1547 {
1548     for (auto&& [id, callback] : foldStatusChangedCallbackMap_) {
1549         if (callback) {
1550             callback(foldStatus);
1551         }
1552     }
1553     StartFoldStatusDelayTask(foldStatus);
1554 }
1555 
OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)1556 void PipelineContext::OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)
1557 {
1558     for (auto&& [id, callback] : foldDisplayModeChangedCallbackMap_) {
1559         if (callback) {
1560             callback(foldDisplayMode);
1561         }
1562     }
1563 }
1564 
OnTransformHintChanged(uint32_t transform)1565 void PipelineContext::OnTransformHintChanged(uint32_t transform)
1566 {
1567     for (auto&& [id, callback] : transformHintChangedCallbackMap_) {
1568         if (callback) {
1569             callback(transform);
1570         }
1571     }
1572     transform_ = transform;
1573 }
1574 
StartWindowSizeChangeAnimate(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1575 void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type,
1576     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1577 {
1578     static const bool IsWindowSizeAnimationEnabled = SystemProperties::IsWindowSizeAnimationEnabled();
1579     if (!IsWindowSizeAnimationEnabled) {
1580         SetRootRect(width, height, 0.0);
1581         return;
1582     }
1583     switch (type) {
1584         case WindowSizeChangeReason::FULL_TO_SPLIT:
1585         case WindowSizeChangeReason::FULL_TO_FLOATING: {
1586             StartFullToMultWindowAnimation(width, height, type, rsTransaction);
1587             break;
1588         }
1589         case WindowSizeChangeReason::RECOVER:
1590         case WindowSizeChangeReason::MAXIMIZE: {
1591             StartWindowMaximizeAnimation(width, height, rsTransaction);
1592             break;
1593         }
1594         case WindowSizeChangeReason::MAXIMIZE_TO_SPLIT:
1595         case WindowSizeChangeReason::SPLIT_TO_MAXIMIZE: {
1596             StartSplitWindowAnimation(width, height, type, rsTransaction);
1597             break;
1598         }
1599         case WindowSizeChangeReason::ROTATION: {
1600             safeAreaManager_->UpdateKeyboardOffset(0.0);
1601             SetRootRect(width, height, 0.0);
1602             FlushUITasks();
1603             if (textFieldManager_) {
1604                 DynamicCast<TextFieldManagerNG>(textFieldManager_)->ScrollTextFieldToSafeArea();
1605             }
1606             FlushUITasks();
1607             if (!textFieldManager_) {
1608                 break;
1609             }
1610             PostKeyboardAvoidTask();
1611             break;
1612         }
1613         case WindowSizeChangeReason::RESIZE_WITH_ANIMATION: {
1614             SetRootRect(width, height, 0.0);
1615             FlushUITasks();
1616             break;
1617         }
1618         case WindowSizeChangeReason::DRAG_START:
1619         case WindowSizeChangeReason::DRAG:
1620         case WindowSizeChangeReason::DRAG_END:
1621         case WindowSizeChangeReason::RESIZE:
1622         case WindowSizeChangeReason::UNDEFINED:
1623         default: {
1624             SetRootRect(width, height, 0.0f);
1625         }
1626     }
1627 }
1628 
PostKeyboardAvoidTask()1629 void PipelineContext::PostKeyboardAvoidTask()
1630 {
1631     auto textFieldManager = DynamicCast<TextFieldManagerNG>(textFieldManager_);
1632     CHECK_NULL_VOID(textFieldManager);
1633     if (textFieldManager->UsingCustomKeyboardAvoid()) {
1634         taskExecutor_->PostTask(
1635             [weak = WeakPtr<TextFieldManagerNG>(textFieldManager)] {
1636                 auto manager = weak.Upgrade();
1637                 CHECK_NULL_VOID(manager);
1638                 manager->TriggerCustomKeyboardAvoid();
1639             },
1640             TaskExecutor::TaskType::UI, "ArkUICustomKeyboardAvoid");
1641         return;
1642     }
1643     CHECK_NULL_VOID(textFieldManager->GetLaterAvoid());
1644     auto container = Container::Current();
1645     if (container) {
1646         auto displayInfo = container->GetDisplayInfo();
1647         if (displayInfo && textFieldManager->GetLaterOrientation() != (int32_t)displayInfo->GetRotation()) {
1648             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "orientation not match, clear laterAvoid");
1649             textFieldManager->SetLaterAvoid(false);
1650             return;
1651         }
1652     }
1653     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "after rotation set root, trigger avoid now");
1654     taskExecutor_->PostTask(
1655         [weakContext = WeakClaim(this), weakManager = WeakPtr<TextFieldManagerNG>(textFieldManager)] {
1656             auto manager = weakManager.Upgrade();
1657             CHECK_NULL_VOID(manager);
1658             auto context = weakContext.Upgrade();
1659             CHECK_NULL_VOID(context);
1660             auto keyboardRect = manager->GetLaterAvoidKeyboardRect();
1661             auto positionY = manager->GetLaterAvoidPositionY();
1662             auto height = manager->GetLaterAvoidHeight();
1663             context->OnVirtualKeyboardAreaChange(keyboardRect, positionY, height, nullptr, true);
1664             manager->SetLaterAvoid(false);
1665             manager->SetFocusFieldAlreadyTriggerWsCallback(false);
1666         },
1667         TaskExecutor::TaskType::UI, "ArkUIVirtualKeyboardAreaChange");
1668 }
1669 
StartWindowMaximizeAnimation(int32_t width,int32_t height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1670 void PipelineContext::StartWindowMaximizeAnimation(
1671     int32_t width, int32_t height, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1672 {
1673     TAG_LOGI(AceLogTag::ACE_ANIMATION,
1674         "Root node start RECOVER/MAXIMIZE animation, width = %{public}d, height = %{public}d", width, height);
1675 #ifdef ENABLE_ROSEN_BACKEND
1676     if (rsTransaction) {
1677         FlushMessages();
1678         rsTransaction->Begin();
1679     }
1680 #endif
1681     AnimationOption option;
1682     int32_t duration = 400;
1683     MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
1684     bool freeMultiWindowModeEnabled = GetWindowManager()->GetFreeMultiWindowModeEnabledState();
1685     if (maximizeMode == MaximizeMode::MODE_FULL_FILL || maximizeMode == MaximizeMode::MODE_AVOID_SYSTEM_BAR ||
1686         freeMultiWindowModeEnabled) {
1687         duration = 0;
1688     }
1689     option.SetDuration(duration);
1690     auto curve = Curves::EASE_OUT;
1691     option.SetCurve(curve);
1692     auto weak = WeakClaim(this);
1693     Animate(option, curve, [width, height, weak]() {
1694         auto pipeline = weak.Upgrade();
1695         CHECK_NULL_VOID(pipeline);
1696         pipeline->SetRootRect(width, height, 0.0);
1697         pipeline->FlushUITasks();
1698     });
1699 #ifdef ENABLE_ROSEN_BACKEND
1700     if (rsTransaction) {
1701         rsTransaction->Commit();
1702     }
1703 #endif
1704 }
1705 
StartFullToMultWindowAnimation(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1706 void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type,
1707     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1708 {
1709     TAG_LOGI(AceLogTag::ACE_ANIMATION,
1710         "Root node start multiple window animation, type = %{public}d, width = %{public}d, height = %{public}d", type,
1711         width, height);
1712 #ifdef ENABLE_ROSEN_BACKEND
1713     if (rsTransaction) {
1714         FlushMessages();
1715         rsTransaction->Begin();
1716     }
1717 #endif
1718     float response = 0.5f;
1719     float dampingFraction = 1.0f;
1720     AnimationOption option;
1721     if (type == WindowSizeChangeReason::FULL_TO_FLOATING) {
1722         response = 0.45f;
1723         dampingFraction = 0.75f;
1724     }
1725     auto springMotion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingFraction, 0);
1726     option.SetCurve(springMotion);
1727     auto weak = WeakClaim(this);
1728     Animate(option, springMotion, [width, height, weak]() {
1729         auto pipeline = weak.Upgrade();
1730         CHECK_NULL_VOID(pipeline);
1731         pipeline->SetRootRect(width, height, 0.0);
1732         pipeline->FlushUITasks();
1733     });
1734 #ifdef ENABLE_ROSEN_BACKEND
1735     if (rsTransaction) {
1736         rsTransaction->Commit();
1737     }
1738 #endif
1739 }
1740 
StartSplitWindowAnimation(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1741 void PipelineContext::StartSplitWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type,
1742     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1743 {
1744     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE,
1745         "Root node start split window animation, type = %{public}d, width = %{public}d, height = %{public}d", type,
1746         width, height);
1747 #ifdef ENABLE_ROSEN_BACKEND
1748     if (rsTransaction) {
1749         FlushMessages();
1750         rsTransaction->Begin();
1751     }
1752 #endif
1753     auto curve = AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 300.0f, 33.0f);
1754     AnimationOption option;
1755     option.SetCurve(curve);
1756     Animate(option, curve, [width, height, weak = WeakClaim(this)]() {
1757         auto pipeline = weak.Upgrade();
1758         CHECK_NULL_VOID(pipeline);
1759         pipeline->SetRootRect(width, height, 0.0);
1760         pipeline->FlushUITasks();
1761     });
1762 #ifdef ENABLE_ROSEN_BACKEND
1763     if (rsTransaction) {
1764         rsTransaction->Commit();
1765     }
1766 #endif
1767 }
1768 
SetRootRect(double width,double height,double offset)1769 void PipelineContext::SetRootRect(double width, double height, double offset)
1770 {
1771     CHECK_RUN_ON(UI);
1772     UpdateRootSizeAndScale(width, height);
1773     CHECK_NULL_VOID(rootNode_);
1774     ACE_SCOPED_TRACE("SetRootRect: origin:%s,set width:%f, height:%f, offset:%f",
1775         rootNode_->GetGeometryNode()->GetFrameRect().ToString().c_str(), width, height, offset);
1776     if (Container::CurrentId() < MIN_SUBCONTAINER_ID) {
1777         ScreenSystemManager::GetInstance().SetWindowInfo(rootWidth_, density_, dipScale_);
1778         ScreenSystemManager::GetInstance().OnSurfaceChanged(width);
1779     } else {
1780         ScreenSystemManager::GetInstance().SetWindowInfo(density_, dipScale_);
1781     }
1782     SizeF sizeF { static_cast<float>(width), static_cast<float>(height) };
1783     if (rootNode_->GetGeometryNode()->GetFrameSize() != sizeF || rootNode_->IsLayoutDirtyMarked()) {
1784         CalcSize idealSize { CalcLength(width), CalcLength(height) };
1785         MeasureProperty layoutConstraint;
1786         layoutConstraint.selfIdealSize = idealSize;
1787         layoutConstraint.maxSize = idealSize;
1788         rootNode_->UpdateLayoutConstraint(layoutConstraint);
1789         // reset parentLayoutConstraint to update itself when next measure task
1790         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1791         rootNode_->MarkDirtyNode();
1792     }
1793     if (rootNode_->GetGeometryNode()->GetFrameOffset().GetY() != offset) {
1794         OffsetF newOffset = rootNode_->GetGeometryNode()->GetFrameOffset();
1795         newOffset.SetY(static_cast<float>(offset));
1796         rootNode_->GetGeometryNode()->SetMarginFrameOffset(newOffset);
1797         auto rootContext = rootNode_->GetRenderContext();
1798         rootContext->SyncGeometryProperties(RawPtr(rootNode_->GetGeometryNode()));
1799         RequestFrame();
1800     }
1801     if (isDensityChanged_) {
1802         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1803         rootNode_->MarkForceMeasure();
1804         isDensityChanged_ = false;
1805     }
1806 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1807     // For cross-platform build, flush tasks when first resize, speed up for fisrt frame.
1808     if (window_ && rootNode_->GetRenderContext() && !NearZero(width) && !NearZero(height)) {
1809         rootNode_->GetRenderContext()->SetBounds(0.0, 0.0, width, height);
1810         window_->FlushTasks();
1811         FlushVsync(GetTimeFromExternalTimer(), 0);
1812     }
1813 #endif
1814 }
1815 
UpdateSystemSafeArea(const SafeAreaInsets & systemSafeArea,bool checkSceneBoardWindow)1816 void PipelineContext::UpdateSystemSafeArea(const SafeAreaInsets& systemSafeArea, bool checkSceneBoardWindow)
1817 {
1818     if (checkSceneBoardWindow) {
1819         safeAreaManager_->UpdateScbSystemSafeArea(systemSafeArea);
1820         return;
1821     }
1822     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1823     if (safeAreaManager_->UpdateSystemSafeArea(systemSafeArea)) {
1824         AnimateOnSafeAreaUpdate();
1825     }
1826 }
1827 
UpdateCutoutSafeArea(const SafeAreaInsets & cutoutSafeArea,bool checkSceneBoardWindow)1828 void PipelineContext::UpdateCutoutSafeArea(const SafeAreaInsets& cutoutSafeArea, bool checkSceneBoardWindow)
1829 {
1830     if (checkSceneBoardWindow) {
1831         safeAreaManager_->UpdateScbCutoutSafeArea(cutoutSafeArea);
1832         return;
1833     }
1834     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1835     if (safeAreaManager_->UpdateCutoutSafeArea(cutoutSafeArea)) {
1836         AnimateOnSafeAreaUpdate();
1837     }
1838 }
1839 
UpdateNavSafeArea(const SafeAreaInsets & navSafeArea,bool checkSceneBoardWindow)1840 void PipelineContext::UpdateNavSafeArea(const SafeAreaInsets& navSafeArea, bool checkSceneBoardWindow)
1841 {
1842     if (checkSceneBoardWindow) {
1843         safeAreaManager_->UpdateScbNavSafeArea(navSafeArea);
1844         return;
1845     }
1846     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1847     if (safeAreaManager_->UpdateNavSafeArea(navSafeArea)) {
1848         AnimateOnSafeAreaUpdate();
1849     }
1850 }
1851 
CheckAndUpdateKeyboardInset(float keyboardHeight)1852 void PipelineContext::CheckAndUpdateKeyboardInset(float keyboardHeight)
1853 {
1854     safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1855 }
1856 
UpdateOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1857 void PipelineContext::UpdateOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1858 {
1859 #ifdef WINDOW_SCENE_SUPPORTED
1860     CHECK_NULL_VOID(uiExtensionManager_);
1861     uiExtensionManager_->TransferOriginAvoidArea(avoidArea, type);
1862 #endif
1863 }
1864 
UpdateSizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1865 void PipelineContext::UpdateSizeChangeReason(
1866     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1867 {
1868 #ifdef WINDOW_SCENE_SUPPORTED
1869     CHECK_NULL_VOID(uiExtensionManager_);
1870     uiExtensionManager_->NotifySizeChangeReason(type, rsTransaction);
1871 #endif
1872 }
1873 
SetEnableKeyBoardAvoidMode(KeyBoardAvoidMode value)1874 void PipelineContext::SetEnableKeyBoardAvoidMode(KeyBoardAvoidMode value)
1875 {
1876     if (safeAreaManager_->SetKeyBoardAvoidMode(value)) {
1877         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
1878         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "keyboardAvoid Mode update:%{public}d", value);
1879     }
1880 }
1881 
GetEnableKeyBoardAvoidMode()1882 KeyBoardAvoidMode PipelineContext::GetEnableKeyBoardAvoidMode()
1883 {
1884     return safeAreaManager_->GetKeyBoardAvoidMode();
1885 }
1886 
IsEnableKeyBoardAvoidMode()1887 bool PipelineContext::IsEnableKeyBoardAvoidMode()
1888 {
1889     return safeAreaManager_->KeyboardSafeAreaEnabled();
1890 }
1891 
SetIgnoreViewSafeArea(bool value)1892 void PipelineContext::SetIgnoreViewSafeArea(bool value)
1893 {
1894     if (safeAreaManager_->SetIgnoreSafeArea(value)) {
1895         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1896     }
1897 }
1898 
SetIsLayoutFullScreen(bool value)1899 void PipelineContext::SetIsLayoutFullScreen(bool value)
1900 {
1901     if (safeAreaManager_->SetIsFullScreen(value)) {
1902         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1903     }
1904 }
1905 
SetIsNeedAvoidWindow(bool value)1906 void PipelineContext::SetIsNeedAvoidWindow(bool value)
1907 {
1908     if (safeAreaManager_->SetIsNeedAvoidWindow(value)) {
1909         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1910     }
1911 }
1912 
GetSafeArea() const1913 PipelineBase::SafeAreaInsets PipelineContext::GetSafeArea() const
1914 {
1915     return safeAreaManager_->GetSafeArea();
1916 }
1917 
GetSafeAreaWithoutProcess() const1918 PipelineBase::SafeAreaInsets PipelineContext::GetSafeAreaWithoutProcess() const
1919 {
1920     return safeAreaManager_->GetSafeAreaWithoutProcess();
1921 }
1922 
GetPageAvoidOffset()1923 float PipelineContext::GetPageAvoidOffset()
1924 {
1925     return safeAreaManager_->GetKeyboardOffset();
1926 }
1927 
CheckNeedAvoidInSubWindow()1928 bool PipelineContext::CheckNeedAvoidInSubWindow()
1929 {
1930     CHECK_NULL_RETURN(NearZero(GetPageAvoidOffset()), true);
1931     CHECK_NULL_RETURN(safeAreaManager_->KeyboardSafeAreaEnabled(), false);
1932     auto KeyboardInsetLength = safeAreaManager_->GetKeyboardInset().Length();
1933     return GreatNotEqual(KeyboardInsetLength, 0.0f);
1934 }
1935 
SyncSafeArea(SafeAreaSyncType syncType)1936 void PipelineContext::SyncSafeArea(SafeAreaSyncType syncType)
1937 {
1938     bool keyboardSafeArea =
1939         syncType == SafeAreaSyncType::SYNC_TYPE_KEYBOARD && !safeAreaManager_->KeyboardSafeAreaEnabled();
1940     CHECK_NULL_VOID(stageManager_);
1941     stageManager_->SyncPageSafeArea(keyboardSafeArea);
1942     SubwindowManager::GetInstance()->MarkDirtyDialogSafeArea();
1943     if (overlayManager_) {
1944         overlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1945     }
1946     if (selectOverlayManager_) {
1947         selectOverlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1948     }
1949     auto&& restoreNodes = safeAreaManager_->GetGeoRestoreNodes();
1950     for (auto&& wk : restoreNodes) {
1951         auto node = wk.Upgrade();
1952         if (node) {
1953             bool needMeasure = (syncType == SafeAreaSyncType::SYNC_TYPE_KEYBOARD && node->SelfExpansiveToKeyboard()) ||
1954                                (syncType == SafeAreaSyncType::SYNC_TYPE_AVOID_AREA ||
1955                                    syncType == SafeAreaSyncType::SYNC_TYPE_WINDOW_IGNORE);
1956             node->MarkDirtyNode(needMeasure ? PROPERTY_UPDATE_MEASURE : PROPERTY_UPDATE_LAYOUT);
1957         }
1958     }
1959 }
1960 
DetachNode(RefPtr<UINode> uiNode)1961 void PipelineContext::DetachNode(RefPtr<UINode> uiNode)
1962 {
1963     auto frameNode = DynamicCast<FrameNode>(uiNode);
1964     attachedNodeSet_.erase(RawPtr(uiNode));
1965     CHECK_NULL_VOID(frameNode);
1966 
1967     RemoveStoredNode(frameNode->GetRestoreId());
1968     if (frameNode->IsPrivacySensitive()) {
1969         auto privacyManager = GetPrivacySensitiveManager();
1970         privacyManager->RemoveNode(AceType::WeakClaim(AceType::RawPtr(frameNode)));
1971     }
1972 
1973     if (!CheckThreadSafe()) {
1974         LOGW("DetachNode doesn't run on UI thread!");
1975     }
1976     dirtyPropertyNodes_.erase(frameNode);
1977     needRenderNode_.erase(WeakPtr<FrameNode>(frameNode));
1978 
1979     if (dirtyFocusNode_ == frameNode) {
1980         dirtyFocusNode_.Reset();
1981     }
1982 
1983     if (dirtyFocusScope_ == frameNode) {
1984         dirtyFocusScope_.Reset();
1985     }
1986 
1987     if (dirtyRequestFocusNode_ == frameNode) {
1988         dirtyRequestFocusNode_.Reset();
1989     }
1990 
1991     if (activeNode_ == frameNode) {
1992         activeNode_.Reset();
1993     }
1994 
1995     if (focusNode_ == frameNode) {
1996         focusNode_.Reset();
1997     }
1998 }
1999 
OnVirtualKeyboardHeightChange(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,const float safeHeight,const bool supportAvoidance,bool forceChange)2000 void PipelineContext::OnVirtualKeyboardHeightChange(float keyboardHeight,
2001     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, const float safeHeight, const bool supportAvoidance,
2002     bool forceChange)
2003 {
2004     CHECK_RUN_ON(UI);
2005     // prevent repeated trigger with same keyboardHeight
2006     if (!forceChange && NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length())) {
2007         return;
2008     }
2009 
2010     ACE_FUNCTION_TRACE();
2011 #ifdef ENABLE_ROSEN_BACKEND
2012     if (rsTransaction) {
2013         FlushMessages();
2014         rsTransaction->Begin();
2015     }
2016 #endif
2017 
2018     if (supportAvoidance) {
2019         AvoidanceLogic(keyboardHeight, rsTransaction, safeHeight, supportAvoidance);
2020     } else {
2021         OriginalAvoidanceLogic(keyboardHeight, rsTransaction);
2022     }
2023 
2024 #ifdef ENABLE_ROSEN_BACKEND
2025     if (rsTransaction) {
2026         rsTransaction->Commit();
2027     }
2028 #endif
2029 }
2030 
AvoidanceLogic(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,const float safeHeight,const bool supportAvoidance)2031 void PipelineContext::AvoidanceLogic(float keyboardHeight, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction,
2032     const float safeHeight, const bool supportAvoidance)
2033 {
2034     auto func = [this, keyboardHeight, safeHeight]() mutable {
2035         safeAreaManager_->UpdateKeyboardSafeArea(static_cast<uint32_t>(keyboardHeight));
2036         keyboardHeight += safeAreaManager_->GetSafeHeight();
2037         float positionY = 0.0f;
2038         float textfieldHeight = 0.0f;
2039         float keyboardPosition = rootHeight_ - keyboardHeight;
2040         auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2041         float keyboardOffset = manager ? manager->GetClickPositionOffset() : safeAreaManager_->GetKeyboardOffset();
2042         if (manager) {
2043             positionY = static_cast<float>(manager->GetClickPosition().GetY()) - keyboardOffset;
2044             textfieldHeight = manager->GetHeight();
2045         }
2046         if (NearZero(keyboardHeight)) {
2047             safeAreaManager_->UpdateKeyboardOffset(0.0f);
2048         } else if (LessOrEqual(positionY + safeHeight + textfieldHeight, rootHeight_ - keyboardHeight)) {
2049             safeAreaManager_->UpdateKeyboardOffset(0.0f);
2050         } else if (positionY + safeHeight + textfieldHeight > rootHeight_ - keyboardHeight) {
2051             safeAreaManager_->UpdateKeyboardOffset(
2052                 -(positionY - rootHeight_ + keyboardHeight)- safeHeight - textfieldHeight);
2053         } else {
2054             safeAreaManager_->UpdateKeyboardOffset(0.0f);
2055         }
2056         safeAreaManager_->SetLastKeyboardPoistion(keyboardPosition);
2057         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
2058         CHECK_NULL_VOID(manager);
2059         manager->AvoidKeyBoardInNavigation();
2060         // layout before scrolling textfield to safeArea, because of getting correct position
2061         FlushUITasks();
2062         bool scrollResult = manager->ScrollTextFieldToSafeArea();
2063         if (scrollResult) {
2064             FlushUITasks();
2065         }
2066         MarkDirtyOverlay();
2067         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
2068 
2069         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
2070             "AvoidanceLogic keyboardHeight: %{public}f, positionY: %{public}f, safeHeight: %{public}f, "
2071             "rootHeight_ %{public}f final calculate keyboard offset is %{public}f",
2072             keyboardHeight, positionY, safeHeight, rootHeight_, safeAreaManager_->GetKeyboardOffset());
2073     };
2074     FlushUITasks();
2075     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
2076 }
2077 
OriginalAvoidanceLogic(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)2078 void PipelineContext::OriginalAvoidanceLogic(
2079     float keyboardHeight, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
2080 {
2081     auto func = [this, keyboardHeight, id = instanceId_]() mutable {
2082         ContainerScope scope(id);
2083         safeAreaManager_->UpdateKeyboardSafeArea(static_cast<uint32_t>(keyboardHeight));
2084         if (keyboardHeight > 0) {
2085             // add height of navigation bar
2086             keyboardHeight += safeAreaManager_->GetSystemSafeArea().bottom_.Length();
2087         }
2088         auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2089         float positionY = manager ? static_cast<float>(manager->GetClickPosition().GetY()) : 0.0f;
2090         float height = manager ? manager->GetHeight() : 0.0f;
2091         SizeF rootSize { static_cast<float>(rootWidth_), static_cast<float>(rootHeight_) };
2092         float keyboardOffset = manager ? manager->GetClickPositionOffset() : safeAreaManager_->GetKeyboardOffset();
2093         float positionYWithOffset = positionY - keyboardOffset;
2094         float offsetFix = (rootSize.Height() - positionYWithOffset) > 100.0f
2095                               ? keyboardHeight - (rootSize.Height() - positionYWithOffset) / 2.0f
2096                               : keyboardHeight;
2097 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
2098         if (offsetFix > 0.0f && positionYWithOffset < offsetFix) {
2099             offsetFix = keyboardHeight - (rootSize.Height() - positionYWithOffset - height);
2100         }
2101 #endif
2102         if (NearZero(keyboardHeight)) {
2103             safeAreaManager_->UpdateKeyboardOffset(0.0f);
2104         } else if (LessOrEqual(rootSize.Height() - positionYWithOffset - height, height) &&
2105                    LessOrEqual(rootSize.Height() - positionYWithOffset, keyboardHeight)) {
2106             safeAreaManager_->UpdateKeyboardOffset(-keyboardHeight);
2107         } else if (positionYWithOffset + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
2108             safeAreaManager_->UpdateKeyboardOffset(-offsetFix);
2109         } else if ((positionYWithOffset + height > rootSize.Height() - keyboardHeight &&
2110                        positionYWithOffset < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
2111                    NearZero(rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
2112             safeAreaManager_->UpdateKeyboardOffset(-height - offsetFix / 2.0f);
2113         } else {
2114             safeAreaManager_->UpdateKeyboardOffset(0.0f);
2115         }
2116         SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
2117         CHECK_NULL_VOID(manager);
2118         manager->AvoidKeyBoardInNavigation();
2119         // layout before scrolling textfield to safeArea, because of getting correct position
2120         FlushUITasks();
2121         bool scrollResult = manager->ScrollTextFieldToSafeArea();
2122         if (scrollResult) {
2123             FlushUITasks();
2124         }
2125         MarkDirtyOverlay();
2126         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
2127     };
2128     FlushUITasks();
2129     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
2130 }
2131 
OnVirtualKeyboardHeightChange(float keyboardHeight,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool forceChange)2132 void PipelineContext::OnVirtualKeyboardHeightChange(float keyboardHeight, double positionY, double height,
2133     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool forceChange)
2134 {
2135     CHECK_RUN_ON(UI);
2136     // prevent repeated trigger with same keyboardHeight
2137     CHECK_NULL_VOID(safeAreaManager_);
2138     if (keyboardHeight >= rootHeight_) {
2139         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Keyboard higher than whole rootrect, no need to avoid");
2140         return;
2141     }
2142 
2143     if (UsingCaretAvoidMode()) {
2144         OnCaretPositionChangeOrKeyboardHeightChange(keyboardHeight,
2145             positionY, height, rsTransaction, forceChange);
2146         return;
2147     }
2148 
2149     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2150     CHECK_NULL_VOID(manager);
2151     if (!forceChange && NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length()) &&
2152         prevKeyboardAvoidMode_ == safeAreaManager_->GetKeyBoardAvoidMode() && manager->PrevHasTextFieldPattern()) {
2153         safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
2154         TAG_LOGD(
2155             AceLogTag::ACE_KEYBOARD, "KeyboardHeight as same as last time, don't need to calculate keyboardOffset");
2156         return;
2157     }
2158 
2159     if (!forceChange && (NearEqual(keyboardHeight + 1, safeAreaManager_->GetKeyboardInset().Length()) ||
2160         NearEqual(keyboardHeight - 1, safeAreaManager_->GetKeyboardInset().Length())) &&
2161         prevKeyboardAvoidMode_ == safeAreaManager_->GetKeyBoardAvoidMode() && manager->PrevHasTextFieldPattern()) {
2162         TAG_LOGI(
2163             AceLogTag::ACE_KEYBOARD, "Ignore ileagal keyboard height change");
2164         return;
2165     }
2166 
2167     if (manager->UsingCustomKeyboardAvoid()) {
2168         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Using Custom Avoid Instead");
2169         return;
2170     }
2171 
2172     manager->UpdatePrevHasTextFieldPattern();
2173     prevKeyboardAvoidMode_ = safeAreaManager_->GetKeyBoardAvoidMode();
2174 
2175     ACE_FUNCTION_TRACE();
2176 #ifdef ENABLE_ROSEN_BACKEND
2177     if (rsTransaction) {
2178         FlushMessages();
2179         rsTransaction->Begin();
2180     }
2181 #endif
2182 
2183     auto weak = WeakClaim(this);
2184     auto func = [weak, keyboardHeight, positionY, height, manager]() mutable {
2185         auto context = weak.Upgrade();
2186         CHECK_NULL_VOID(context);
2187         context->SetIsLayouting(false);
2188         context->safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
2189         if (keyboardHeight > 0) {
2190             // add height of navigation bar
2191             keyboardHeight += context->safeAreaManager_->GetSystemSafeArea().bottom_.Length();
2192         }
2193 
2194         SizeF rootSize { static_cast<float>(context->rootWidth_), static_cast<float>(context->rootHeight_) };
2195 
2196         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
2197             "origin positionY: %{public}f, height %{public}f", positionY, height);
2198 
2199         float positionYWithOffset = positionY;
2200         float keyboardOffset = manager ? manager->GetClickPositionOffset() :
2201             context->safeAreaManager_->GetKeyboardOffset();
2202         float currentPos = manager->GetClickPosition().GetY() - context->GetRootRect().GetOffset().GetY() -
2203             keyboardOffset;
2204 
2205         auto onFocusField = manager->GetOnFocusTextField().Upgrade();
2206         float adjust = 0.0f;
2207         if (onFocusField && onFocusField->GetHost() && onFocusField->GetHost()->GetGeometryNode()) {
2208             auto adjustRect = onFocusField->GetHost()->GetGeometryNode()->GetParentAdjust();
2209             adjust = adjustRect.Top();
2210         }
2211         currentPos += adjust;
2212 
2213         if (!onFocusField) {
2214             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "use origin arg from the window");
2215         } else if (manager->GetIfFocusTextFieldIsInline()) {
2216             manager->GetInlineTextFieldAvoidPositionYAndHeight(positionY, height);
2217             positionYWithOffset = positionY;
2218         } else if (!NearEqual(positionY, currentPos) && !context->IsEnableKeyBoardAvoidMode()) {
2219             positionY = currentPos;
2220             positionYWithOffset = currentPos;
2221             height = manager->GetHeight();
2222         }
2223 
2224         if (rootSize.Height() - positionY - height < 0) {
2225             height = rootSize.Height() - positionY;
2226         }
2227         auto lastKeyboardOffset = context->safeAreaManager_->GetKeyboardOffset();
2228         float newKeyboardOffset = context->CalcNewKeyboardOffset(keyboardHeight,
2229             positionYWithOffset, height, rootSize, onFocusField && manager->GetIfFocusTextFieldIsInline());
2230         newKeyboardOffset = round(newKeyboardOffset);
2231         if (NearZero(keyboardHeight) || LessOrEqual(newKeyboardOffset, lastKeyboardOffset) ||
2232             manager->GetOnFocusTextFieldId() == manager->GetLastAvoidFieldId()) {
2233             context->safeAreaManager_->UpdateKeyboardOffset(newKeyboardOffset);
2234         } else {
2235             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Different field, Calculated offfset %{public}f is smaller than current"
2236                 "keyboardOffset, so keep current keyboardOffset", newKeyboardOffset);
2237         }
2238         manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
2239 
2240         TAG_LOGI(AceLogTag::ACE_KEYBOARD,
2241             "keyboardHeight: %{public}f, positionY: %{public}f, textHeight: %{public}f, "
2242             "rootSize.Height() %{public}f adjust: %{public}f final calculate keyboard offset is %{public}f",
2243             keyboardHeight, positionY, height, rootSize.Height(), adjust,
2244             context->safeAreaManager_->GetKeyboardOffset());
2245         context->SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
2246         manager->AvoidKeyBoardInNavigation();
2247         // layout before scrolling textfield to safeArea, because of getting correct position
2248         context->FlushUITasks();
2249         bool scrollResult = manager->ScrollTextFieldToSafeArea();
2250         if (scrollResult) {
2251             context->FlushUITasks();
2252         }
2253         context->MarkDirtyOverlay();
2254         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
2255     };
2256     FlushUITasks();
2257     FlushDirtyPropertyNodesWhenExist();
2258     SetIsLayouting(true);
2259     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
2260 
2261 #ifdef ENABLE_ROSEN_BACKEND
2262     if (rsTransaction) {
2263         rsTransaction->Commit();
2264     }
2265 #endif
2266 }
2267 
MarkDirtyOverlay()2268 void PipelineContext::MarkDirtyOverlay()
2269 {
2270     CHECK_NULL_VOID(rootNode_);
2271     auto childNodes = rootNode_->GetChildren();
2272     for (auto child: childNodes) {
2273         if (child && child->GetTag() == V2::POPUP_ETS_TAG) {
2274             child->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
2275         }
2276     }
2277 }
2278 
FlushDirtyPropertyNodesWhenExist()2279 void PipelineContext::FlushDirtyPropertyNodesWhenExist()
2280 {
2281     if ((!IsDirtyLayoutNodesEmpty() || !dirtyPropertyNodes_.empty()) && !IsLayouting()) {
2282         FlushUITasks();
2283     }
2284 }
2285 
UsingCaretAvoidMode()2286 bool PipelineContext::UsingCaretAvoidMode()
2287 {
2288     CHECK_NULL_RETURN(safeAreaManager_, false);
2289     return safeAreaManager_->GetKeyBoardAvoidMode() == KeyBoardAvoidMode::OFFSET_WITH_CARET ||
2290         safeAreaManager_->GetKeyBoardAvoidMode() == KeyBoardAvoidMode::RESIZE_WITH_CARET;
2291 }
2292 
OnCaretPositionChangeOrKeyboardHeightChange(float keyboardHeight,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction,bool forceChange)2293 void PipelineContext::OnCaretPositionChangeOrKeyboardHeightChange(
2294     float keyboardHeight, double positionY, double height,
2295     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool forceChange)
2296 {
2297     CHECK_RUN_ON(UI);
2298     CHECK_NULL_VOID(safeAreaManager_);
2299     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2300     CHECK_NULL_VOID(manager);
2301     if (manager->UsingCustomKeyboardAvoid()) {
2302         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Using Custom Avoid Instead");
2303         return;
2304     }
2305     manager->UpdatePrevHasTextFieldPattern();
2306     prevKeyboardAvoidMode_ = safeAreaManager_->GetKeyBoardAvoidMode();
2307     ACE_FUNCTION_TRACE();
2308 #ifdef ENABLE_ROSEN_BACKEND
2309     if (rsTransaction) {
2310         FlushMessages();
2311         rsTransaction->Begin();
2312     }
2313 #endif
2314     bool keyboardHeightChanged = NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length());
2315     auto weak = WeakClaim(this);
2316     auto func = [weak, keyboardHeight, positionY, height, keyboardHeightChanged]() mutable {
2317         auto context = weak.Upgrade();
2318         CHECK_NULL_VOID(context);
2319         context->DoKeyboardAvoidFunc(keyboardHeight, positionY, height, keyboardHeightChanged);
2320         context->MarkDirtyOverlay();
2321         SubwindowManager::GetInstance()->FlushSubWindowUITasks(Container::CurrentId());
2322     };
2323     FlushUITasks();
2324     SetIsLayouting(true);
2325     DoKeyboardAvoidAnimate(keyboardAnimationConfig_, keyboardHeight, func);
2326 
2327 #ifdef ENABLE_ROSEN_BACKEND
2328     if (rsTransaction) {
2329         rsTransaction->Commit();
2330     }
2331 #endif
2332 }
2333 
DoKeyboardAvoidFunc(float keyboardHeight,double positionY,double height,bool keyboardHeightChanged)2334 void PipelineContext::DoKeyboardAvoidFunc(float keyboardHeight, double positionY, double height,
2335     bool keyboardHeightChanged)
2336 {
2337     CHECK_NULL_VOID(safeAreaManager_);
2338     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2339     CHECK_NULL_VOID(manager);
2340     SetIsLayouting(false);
2341     safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
2342     if (keyboardHeight > 0) {
2343         // add height of navigation bar
2344         keyboardHeight += safeAreaManager_->GetSystemSafeArea().bottom_.Length();
2345     }
2346     SizeF rootSize { static_cast<float>(rootWidth_), static_cast<float>(rootHeight_) };
2347     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "origin positionY: %{public}f, height %{public}f", positionY, height);
2348     float caretPos = manager->GetFocusedNodeCaretRect().Top() - GetRootRect().GetOffset().GetY() -
2349         GetSafeAreaManager()->GetKeyboardOffsetDirectly();
2350     auto onFocusField = manager->GetOnFocusTextField().Upgrade();
2351     float adjust = 0.0f;
2352     if (onFocusField && onFocusField->GetHost() && onFocusField->GetHost()->GetGeometryNode()) {
2353         adjust = onFocusField->GetHost()->GetGeometryNode()->GetParentAdjust().Top();
2354         positionY = caretPos;
2355         height = manager->GetHeight();
2356     }
2357     positionY += adjust;
2358     if (rootSize.Height() - positionY - height < 0 && manager->IsScrollableChild()) {
2359         height = rootSize.Height() - positionY;
2360     }
2361     auto lastKeyboardOffset = safeAreaManager_->GetKeyboardOffsetDirectly();
2362     auto newKeyboardOffset = CalcNewKeyboardOffset(keyboardHeight, positionY, height, rootSize);
2363     if (NearZero(keyboardHeight) || LessOrEqual(newKeyboardOffset, lastKeyboardOffset) ||
2364         (manager->GetOnFocusTextFieldId() == manager->GetLastAvoidFieldId() && !keyboardHeightChanged)) {
2365         safeAreaManager_->UpdateKeyboardOffset(newKeyboardOffset);
2366     } else {
2367         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "calc offset %{public}f is smaller, keep current", newKeyboardOffset);
2368         manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
2369         return;
2370     }
2371     manager->SetLastAvoidFieldId(manager->GetOnFocusTextFieldId());
2372     TAG_LOGI(AceLogTag::ACE_KEYBOARD,
2373         "keyboardHeight: %{public}f, caretPos: %{public}f, caretHeight: %{public}f, "
2374         "rootSize.Height() %{public}f adjust: %{public}f lastOffset: %{public}f, "
2375         "final calculate keyboard offset is %{public}f",
2376         keyboardHeight, positionY, height, rootSize.Height(), adjust, lastKeyboardOffset,
2377         safeAreaManager_->GetKeyboardOffset());
2378     SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_KEYBOARD);
2379     manager->AvoidKeyBoardInNavigation();
2380     // layout before scrolling textfield to safeArea, because of getting correct position
2381     FlushUITasks();
2382     bool scrollResult = manager->ScrollTextFieldToSafeArea();
2383     if (scrollResult) {
2384         FlushUITasks();
2385     }
2386 }
2387 
CalcNewKeyboardOffset(float keyboardHeight,float positionY,float height,SizeF & rootSize,bool isInline)2388 float  PipelineContext::CalcNewKeyboardOffset(float keyboardHeight, float positionY,
2389     float height, SizeF& rootSize, bool isInline)
2390 {
2391     auto newKeyboardOffset = CalcAvoidOffset(keyboardHeight, positionY, height, rootSize);
2392     CHECK_NULL_RETURN(!isInline, newKeyboardOffset);
2393     CHECK_NULL_RETURN(safeAreaManager_, newKeyboardOffset);
2394     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2395     CHECK_NULL_RETURN(manager, newKeyboardOffset);
2396     auto onFocusField = manager->GetOnFocusTextField().Upgrade();
2397     CHECK_NULL_RETURN(onFocusField, newKeyboardOffset);
2398     auto host = onFocusField->GetHost();
2399     CHECK_NULL_RETURN(host, newKeyboardOffset);
2400     auto geometryNode = host->GetGeometryNode();
2401     CHECK_NULL_RETURN(geometryNode, newKeyboardOffset);
2402     auto paintOffset = host->GetPaintRectOffset(false, true);
2403     auto frameSize = geometryNode->GetFrameSize();
2404     auto offset = CalcAvoidOffset(keyboardHeight, paintOffset.GetY() - safeAreaManager_->GetKeyboardOffsetDirectly(),
2405         frameSize.Height() + CARET_AVOID_OFFSET.ConvertToPx(), rootSize);
2406     return std::max(offset, newKeyboardOffset);
2407 }
2408 
CalcAvoidOffset(float keyboardHeight,float positionY,float height,SizeF rootSize)2409 float PipelineContext::CalcAvoidOffset(float keyboardHeight, float positionY,
2410     float height, SizeF rootSize)
2411 {
2412     float offsetFix = (rootSize.Height() - positionY - height) < keyboardHeight
2413         ? keyboardHeight - (rootSize.Height() - positionY - height)
2414         : keyboardHeight;
2415     if (NearZero(keyboardHeight)) {
2416         return 0.0f;
2417     }
2418     if (positionY + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
2419         return -offsetFix;
2420     }
2421     if (LessOrEqual(rootSize.Height() - positionY - height, height) &&
2422         LessOrEqual(rootSize.Height() - positionY, keyboardHeight)) {
2423         return -keyboardHeight;
2424     }
2425     if ((positionY + height > rootSize.Height() - keyboardHeight &&
2426         positionY < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
2427         NearZero(rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
2428         return -height - offsetFix / 2.0f;
2429     }
2430     return 0.0f;
2431 }
2432 
OnBackPressed()2433 bool PipelineContext::OnBackPressed()
2434 {
2435     CHECK_RUN_ON(PLATFORM);
2436     auto frontend = weakFrontend_.Upgrade();
2437     if (!frontend) {
2438         // return back.
2439         return false;
2440     }
2441 
2442     // If the tag of the last child of the rootnode is video, exit full screen.
2443     if (fullScreenManager_->OnBackPressed()) {
2444         LOGI("fullscreen component: video or web consumed backpressed event");
2445         return true;
2446     }
2447 
2448     // if has sharedTransition, back press will stop the sharedTransition
2449     if (sharedTransitionManager_ && sharedTransitionManager_->OnBackPressed()) {
2450         LOGI("sharedTransition consumed backpressed event");
2451         return true;
2452     }
2453 
2454     // if has popup, back press would hide popup and not trigger page back
2455     auto textfieldMgr = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2456     if (textfieldMgr) {
2457         auto lastRequestKeyboardNodeId = textfieldMgr->GetLastRequestKeyboardId();
2458         auto lastRequestKeyboardNode = DynamicCast<FrameNode>(
2459             ElementRegister::GetInstance()->GetUINodeById(lastRequestKeyboardNodeId));
2460         auto hasContainerModal = windowModal_ == WindowModal::CONTAINER_MODAL;
2461         if (lastRequestKeyboardNode && (lastRequestKeyboardNode->GetPageId() == -1 || (hasContainerModal &&
2462             lastRequestKeyboardNode->GetPageId() == 0)) && textfieldMgr->OnBackPressed()) {
2463             LOGI("textfield consumed backpressed event");
2464             return true;
2465         }
2466     }
2467     auto hasOverlay = false;
2468     taskExecutor_->PostSyncTask(
2469         [weakOverlay = AceType::WeakClaim(AceType::RawPtr(overlayManager_)),
2470             weakSelectOverlay = AceType::WeakClaim(AceType::RawPtr(selectOverlayManager_)), &hasOverlay]() {
2471             // Destroy behaviour of Select Overlay shouble be adjusted.
2472             auto overlay = weakOverlay.Upgrade();
2473             CHECK_NULL_VOID(overlay);
2474             auto selectOverlay = weakSelectOverlay.Upgrade();
2475             CHECK_NULL_VOID(selectOverlay);
2476             hasOverlay = selectOverlay->ResetSelectionAndDestroySelectOverlay(true);
2477             hasOverlay |= overlay->RemoveOverlay(true);
2478         },
2479         TaskExecutor::TaskType::UI, "ArkUIBackPressedRemoveOverlay");
2480     if (hasOverlay) {
2481         LOGI("Overlay consumed backpressed event");
2482         return true;
2483     }
2484 
2485     auto textfieldManager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
2486     if (textfieldManager && textfieldManager->OnBackPressed()) {
2487         LOGI("textfield consumed backpressed event");
2488         return true;
2489     }
2490 
2491     auto result = false;
2492     taskExecutor_->PostSyncTask(
2493         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), stageManager = stageManager_, &result]() {
2494             auto frontend = weakFrontend.Upgrade();
2495             if (!frontend) {
2496                 result = false;
2497                 return;
2498             }
2499             auto context = weakPipelineContext.Upgrade();
2500             if (!context) {
2501                 result = false;
2502                 return;
2503             }
2504             CHECK_NULL_VOID(stageManager);
2505             auto lastPage = stageManager->GetLastPage();
2506             CHECK_NULL_VOID(lastPage);
2507             bool isEntry = false;
2508             auto pagePattern = lastPage->GetPattern<NG::PagePattern>();
2509             if (pagePattern) {
2510                 isEntry = pagePattern->IsNeedCallbackBackPressed();
2511             }
2512             auto navigationGroupNode =
2513                 AceType::DynamicCast<NavigationGroupNode>(context->FindNavigationNodeToHandleBack(lastPage, isEntry));
2514             if (navigationGroupNode) {
2515                 result = true;
2516             }
2517         },
2518         TaskExecutor::TaskType::UI, "ArkUIBackPressedFindNavigationGroup");
2519 
2520     if (result) {
2521         // user accept
2522         LOGI("Navigation consumed backpressed event");
2523         return true;
2524     }
2525 
2526     taskExecutor_->PostSyncTask(
2527         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), &result]() {
2528             auto frontend = weakFrontend.Upgrade();
2529             if (!frontend) {
2530                 result = false;
2531                 return;
2532             }
2533             result = frontend->OnBackPressed();
2534         },
2535         TaskExecutor::TaskType::JS, "ArkUIBackPressed");
2536 
2537     if (result) {
2538         // user accept
2539         LOGI("router consumed backpressed event");
2540         return true;
2541     }
2542     return false;
2543 }
2544 
FindNavigationNodeToHandleBack(const RefPtr<UINode> & node,bool & isEntry)2545 RefPtr<FrameNode> PipelineContext::FindNavigationNodeToHandleBack(const RefPtr<UINode>& node, bool& isEntry)
2546 {
2547     CHECK_NULL_RETURN(node, nullptr);
2548     const auto& children = node->GetChildren();
2549     for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
2550         auto& child = *iter;
2551         auto childNode = AceType::DynamicCast<FrameNode>(child);
2552         if (childNode && childNode->GetLayoutProperty()) {
2553             auto property = childNode->GetLayoutProperty();
2554             if (property->GetVisibilityValue(VisibleType::VISIBLE) != VisibleType::VISIBLE ||
2555                 !childNode->IsActive()) {
2556                 continue;
2557             }
2558         }
2559         if (childNode && childNode->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
2560             auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(childNode);
2561             auto topChild = navigationGroupNode->GetTopDestination();
2562             // find navigation from top destination
2563             auto targetNodeFromDestination = FindNavigationNodeToHandleBack(topChild, isEntry);
2564             if (targetNodeFromDestination) {
2565                 return targetNodeFromDestination;
2566             }
2567             if (isEntry) {
2568                 return nullptr;
2569             }
2570             targetNodeFromDestination = childNode;
2571             auto targetNavigation = AceType::DynamicCast<NavigationGroupNode>(targetNodeFromDestination);
2572             // check if the destination responds
2573             if (targetNavigation && targetNavigation->CheckCanHandleBack(isEntry)) {
2574                 return targetNavigation;
2575             }
2576             if (isEntry) {
2577                 return nullptr;
2578             }
2579             // if the destination does not responds, find navigation from navbar
2580             auto navBarNode = AceType::DynamicCast<NavBarNode>(navigationGroupNode->GetNavBarNode());
2581             auto navigationLayoutProperty = navigationGroupNode->GetLayoutProperty<NavigationLayoutProperty>();
2582             CHECK_NULL_RETURN(navigationLayoutProperty, nullptr);
2583             if (navigationLayoutProperty->GetHideNavBarValue(false)) {
2584                 return nullptr;
2585             }
2586             auto targetNodeFromNavbar = FindNavigationNodeToHandleBack(navBarNode, isEntry);
2587             if (targetNodeFromNavbar) {
2588                 return targetNodeFromNavbar;
2589             }
2590             return nullptr;
2591         }
2592         auto target = FindNavigationNodeToHandleBack(child, isEntry);
2593         if (target) {
2594             return target;
2595         }
2596         if (isEntry) {
2597             return nullptr;
2598         }
2599     }
2600     return nullptr;
2601 }
2602 
SetIsFocusActive(bool isFocusActive,FocusActiveReason reason,bool autoFocusInactive)2603 bool PipelineContext::SetIsFocusActive(bool isFocusActive, FocusActiveReason reason, bool autoFocusInactive)
2604 {
2605     if (!SystemProperties::GetFocusCanBeActive() && isFocusActive) {
2606         TAG_LOGI(AceLogTag::ACE_FOCUS, "FocusActive false");
2607         return false;
2608     }
2609     auto containerId = Container::CurrentId();
2610     auto subWindowContainerId = SubwindowManager::GetInstance()->GetSubContainerId(containerId);
2611     if (subWindowContainerId >= 0) {
2612         auto subPipeline = GetContextByContainerId(subWindowContainerId);
2613         CHECK_NULL_RETURN(subPipeline, false);
2614         ContainerScope scope(subWindowContainerId);
2615         subPipeline->SetIsFocusActive(isFocusActive, reason, autoFocusInactive);
2616     }
2617     if (reason == FocusActiveReason::USE_API) {
2618         TAG_LOGI(AceLogTag::ACE_FOCUS, "autoFocusInactive turns to %{public}d", autoFocusInactive);
2619         autoFocusInactive_ = autoFocusInactive;
2620     }
2621     if (!isFocusActive && reason == FocusActiveReason::POINTER_EVENT && !autoFocusInactive_) {
2622         TAG_LOGI(AceLogTag::ACE_FOCUS, "focus cannot be deactived automaticly by pointer event");
2623         return false;
2624     }
2625 
2626     if (isFocusActive_ == isFocusActive) {
2627         return false;
2628     }
2629     TAG_LOGI(AceLogTag::ACE_FOCUS, "Pipeline focus turns to %{public}s", isFocusActive ? "active" : "inactive");
2630     isFocusActive_ = isFocusActive;
2631     auto focusManager = GetOrCreateFocusManager();
2632     CHECK_NULL_RETURN(focusManager, false);
2633     focusManager->TriggerFocusActiveChangeCallback(isFocusActive);
2634     for (auto& pair : isFocusActiveUpdateEvents_) {
2635         if (pair.second) {
2636             pair.second(isFocusActive_);
2637         }
2638     }
2639     CHECK_NULL_RETURN(rootNode_, false);
2640     auto rootFocusHub = rootNode_->GetFocusHub();
2641     CHECK_NULL_RETURN(rootFocusHub, false);
2642     if (isFocusActive_) {
2643         return rootFocusHub->PaintAllFocusState();
2644     }
2645     rootFocusHub->ClearAllFocusState();
2646     return true;
2647 }
2648 
OnTouchEvent(const TouchEvent & point,bool isSubPipe)2649 void PipelineContext::OnTouchEvent(const TouchEvent& point, bool isSubPipe)
2650 {
2651     OnTouchEvent(point, rootNode_, isSubPipe);
2652 }
2653 
OnMouseEvent(const MouseEvent & event)2654 void PipelineContext::OnMouseEvent(const MouseEvent& event)
2655 {
2656     OnMouseEvent(event, rootNode_);
2657 }
2658 
OnAxisEvent(const AxisEvent & event)2659 void PipelineContext::OnAxisEvent(const AxisEvent& event)
2660 {
2661     OnAxisEvent(event, rootNode_);
2662 }
2663 
OnTouchEvent(const TouchEvent & point,const RefPtr<FrameNode> & node,bool isSubPipe)2664 void PipelineContext::OnTouchEvent(
2665     const TouchEvent& point, const RefPtr<FrameNode>& node, bool isSubPipe)
2666 {
2667     CHECK_RUN_ON(UI);
2668 
2669     HandlePenHoverOut(point);
2670     auto gestureReferee = eventManager_->GetGestureRefereeNG(nullptr);
2671     CHECK_NULL_VOID(gestureReferee);
2672     if (gestureReferee->CheckSourceTypeChange(lastSourceType_)) {
2673         HandleTouchHoverOut(point);
2674     }
2675 
2676 #ifdef UICAST_COMPONENT_SUPPORTED
2677     do {
2678         auto container = Container::Current();
2679         CHECK_NULL_BREAK(container);
2680         auto distributedUI = container->GetDistributedUI();
2681         CHECK_NULL_BREAK(distributedUI);
2682         if (distributedUI->IsSinkMode()) {
2683             distributedUI->BypassEvent(point, isSubPipe);
2684             return;
2685         }
2686     } while (false);
2687 #endif
2688 
2689     auto formEventMgr = this->GetFormEventManager();
2690     SerializedGesture etsSerializedGesture;
2691     if (point.type != TouchType::DOWN && formEventMgr) {
2692         formEventMgr->HandleEtsCardTouchEvent(point, etsSerializedGesture);
2693     }
2694 
2695     auto oriPoint = point;
2696     auto scalePoint = point.CreateScalePoint(GetViewScale());
2697     eventManager_->CheckDownEvent(scalePoint);
2698     ResSchedReport::GetInstance().OnTouchEvent(scalePoint);
2699 
2700     if (scalePoint.type != TouchType::MOVE && scalePoint.type != TouchType::PULL_MOVE &&
2701         scalePoint.type != TouchType::HOVER_MOVE) {
2702         eventManager_->GetEventTreeRecord(EventTreeType::TOUCH).AddTouchPoint(scalePoint);
2703 #ifdef IS_RELEASE_VERSION
2704             TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
2705                 "InputTracking id:%{public}d, fingerId:%{public}d, type=%{public}d, inject=%{public}d, "
2706                 "isPrivacyMode=%{public}d",
2707                 scalePoint.touchEventId, scalePoint.id, (int)scalePoint.type, scalePoint.isInjected,
2708                 scalePoint.isPrivacyMode);
2709 #else
2710             TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
2711                 "InputTracking id:%{public}d, fingerId:%{public}d, x=%{public}.3f, y=%{public}.3f type=%{public}d, "
2712                 "inject=%{public}d",
2713                 scalePoint.touchEventId, scalePoint.id, scalePoint.x, scalePoint.y, (int)scalePoint.type,
2714                 scalePoint.isInjected);
2715 #endif
2716     }
2717 
2718     if (scalePoint.type == TouchType::MOVE) {
2719         for (auto listenerItem : listenerVector_) {
2720             if (listenerItem) {
2721                 listenerItem->OnTouchEvent();
2722             }
2723         }
2724     }
2725 
2726     eventManager_->SetInstanceId(GetInstanceId());
2727     if (scalePoint.type != TouchType::MOVE && historyPointsById_.find(scalePoint.id) != historyPointsById_.end()) {
2728         historyPointsById_.erase(scalePoint.id);
2729     }
2730     if (scalePoint.type == TouchType::DOWN) {
2731         // Set focus state inactive while touch down event received
2732         SetIsFocusActive(false, FocusActiveReason::POINTER_EVENT);
2733         TouchRestrict touchRestrict { TouchRestrict::NONE };
2734         touchRestrict.sourceType = point.sourceType;
2735         touchRestrict.touchEvent = point;
2736         touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
2737 
2738         eventManager_->TouchTest(scalePoint, node, touchRestrict, GetPluginEventOffset(), viewScale_, isSubPipe);
2739         if (!touchRestrict.childTouchTestList.empty()) {
2740             scalePoint.childTouchTestList = touchRestrict.childTouchTestList;
2741         }
2742         auto touchTestResults = eventManager_->touchTestResults_;
2743         if (StylusDetectorMgr::GetInstance()->IsNeedInterceptedTouchEvent(
2744             scalePoint, eventManager_->touchTestResults_)) {
2745             eventManager_->ClearTouchTestTargetForPenStylus(scalePoint);
2746             return;
2747         }
2748 
2749         if (formEventMgr) {
2750             formEventMgr->HandleEtsCardTouchEvent(oriPoint, etsSerializedGesture);
2751         }
2752 
2753         if (etsSerializedGesture.data.size() != 0) {
2754             GestureGroup rebirth(GestureMode::Exclusive);
2755             rebirth.Deserialize(etsSerializedGesture.data.data());
2756             auto recognizer = rebirth.CreateRecognizer();
2757             if (recognizer) {
2758                 recognizer->SetInnerFlag(true);
2759                 recognizer->BeginReferee(scalePoint.id, true);
2760                 std::list<RefPtr<NGGestureRecognizer>> combined;
2761                 combined.emplace_back(recognizer);
2762                 for (auto iter = touchTestResults[point.id].begin();
2763                     iter != touchTestResults[point.id].end(); iter++) {
2764                     auto outRecognizer = AceType::DynamicCast<NGGestureRecognizer>(*iter);
2765                     if (outRecognizer) {
2766                         combined.emplace_back(outRecognizer);
2767                         touchTestResults[point.id].erase(iter);
2768                         break;
2769                     }
2770                 }
2771                 auto exclusiveRecognizer = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(combined));
2772                 exclusiveRecognizer->AttachFrameNode(node);
2773                 exclusiveRecognizer->BeginReferee(scalePoint.id);
2774                 touchTestResults[point.id].emplace_back(exclusiveRecognizer);
2775                 eventManager_->touchTestResults_ = touchTestResults;
2776                 eventManager_->SetInnerFlag(true);
2777             }
2778         }
2779         if (IsFormRender() && touchTestResults.find(point.id) != touchTestResults.end()) {
2780             for (const auto& touchResult : touchTestResults[point.id]) {
2781                 auto recognizer = AceType::DynamicCast<NG::RecognizerGroup>(touchResult);
2782                 if (recognizer) {
2783                     auto gesture = recognizer->CreateGestureFromRecognizer();
2784                     if (gesture) {
2785                         serializedGesture_.data = std::vector<char>(gesture->SizeofMe());
2786                         gesture->Serialize(serializedGesture_.data.data());
2787                     }
2788                     break;
2789                 }
2790             }
2791         }
2792         for (const auto& weakContext : touchPluginPipelineContext_) {
2793             auto pipelineContext = DynamicCast<OHOS::Ace::PipelineBase>(weakContext.Upgrade());
2794             if (!pipelineContext) {
2795                 continue;
2796             }
2797             auto pluginPoint =
2798                 point.UpdateScalePoint(viewScale_, static_cast<float>(pipelineContext->GetPluginEventOffset().GetX()),
2799                     static_cast<float>(pipelineContext->GetPluginEventOffset().GetY()), point.id);
2800             // eventManager_ instance Id may changed.
2801             pipelineContext->OnTouchEvent(pluginPoint, true);
2802         }
2803 
2804         // restore instance Id.
2805         eventManager_->SetInstanceId(GetInstanceId());
2806     }
2807     auto rootOffset = GetRootRect().GetOffset();
2808     eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
2809 
2810     if (isSubPipe) {
2811         return;
2812     }
2813 
2814     // Currently, SetupRootElement is executed later than InitializeCallback in AceContainer.
2815     // We need to check whether accessibilityManagerNG_ is created.
2816     if (accessibilityManagerNG_ != nullptr) {
2817         accessibilityManagerNG_->HandleAccessibilityHoverEvent(node, scalePoint);
2818     }
2819 
2820     if (scalePoint.type == TouchType::MOVE) {
2821         if (isEventsPassThrough_) {
2822             scalePoint.isPassThroughMode = true;
2823             eventManager_->FlushTouchEventsEnd({ scalePoint });
2824             eventManager_->DispatchTouchEvent(scalePoint);
2825             hasIdleTasks_ = true;
2826             return;
2827         }
2828         if (!eventManager_->GetInnerFlag() && formEventMgr) {
2829             auto mockPoint = point;
2830             mockPoint.type = TouchType::CANCEL;
2831             formEventMgr->HandleEtsCardTouchEvent(mockPoint, etsSerializedGesture);
2832             formEventMgr->RemoveEtsCardTouchEventCallback(mockPoint.id);
2833         }
2834         if (dragDropManager_ && dragDropManager_->IsDragging() && dragDropManager_->IsSameDraggingPointer(point.id)) {
2835             auto pointerEvent = DragPointerEvent(scalePoint.x, scalePoint.y, scalePoint.screenX, scalePoint.screenY);
2836             dragDropManager_->SetDragAnimationPointerEvent(pointerEvent);
2837         }
2838         touchEvents_.emplace_back(point);
2839         hasIdleTasks_ = true;
2840         RequestFrame();
2841         return;
2842     }
2843 
2844     if (scalePoint.type == TouchType::UP) {
2845         lastTouchTime_ = GetTimeFromExternalTimer();
2846         CompensateTouchMoveEvent(scalePoint);
2847         if (thpExtraMgr_ != nullptr) {
2848             const uint32_t delay = 800; // 800: ms
2849             taskExecutor_->RemoveTask(TaskExecutor::TaskType::UI, "NotifyResponseRegionChanged");
2850             auto task = [weak = WeakClaim(this)]() {
2851                 auto pipeline = weak.Upgrade();
2852                 CHECK_NULL_VOID(pipeline);
2853                 pipeline->NotifyResponseRegionChanged(pipeline->GetRootElement());
2854             };
2855             taskExecutor_->PostDelayedTask(task, TaskExecutor::TaskType::UI, delay, "NotifyResponseRegionChanged");
2856         }
2857     }
2858 
2859     eventManager_->DispatchTouchEvent(scalePoint);
2860 
2861     if ((scalePoint.type == TouchType::UP) || (scalePoint.type == TouchType::CANCEL)) {
2862         // need to reset touchPluginPipelineContext_ for next touch down event.
2863         touchPluginPipelineContext_.clear();
2864         if (formEventMgr) {
2865             formEventMgr->RemoveEtsCardTouchEventCallback(point.id);
2866         }
2867         if (scalePoint.type == TouchType::CANCEL) {
2868             dragEvents_.clear();
2869         }
2870         ResetDraggingStatus(scalePoint, node);
2871     }
2872     if (scalePoint.type != TouchType::MOVE) {
2873         auto lastDispatchTime = eventManager_->GetLastDispatchTime();
2874         lastDispatchTime.erase(scalePoint.id);
2875         eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
2876         eventManager_->EraseFingerId(scalePoint.id);
2877     }
2878 
2879     hasIdleTasks_ = true;
2880     RequestFrame();
2881 }
2882 
CompensateTouchMoveEventFromUnhandledEvents(const TouchEvent & event)2883 bool PipelineContext::CompensateTouchMoveEventFromUnhandledEvents(const TouchEvent& event)
2884 {
2885     std::vector<TouchEvent> history;
2886     if (!touchEvents_.empty()) {
2887         for (auto iter = touchEvents_.begin(); iter != touchEvents_.end();) {
2888             auto movePoint = (*iter).CreateScalePoint(GetViewScale());
2889             if (event.id == movePoint.id) {
2890                 ShouldAddToHistory(history, event, movePoint);
2891                 iter = touchEvents_.erase(iter);
2892             } else {
2893                 auto& pointers = iter->pointers;
2894                 for (auto pointerIter = pointers.begin(); pointerIter != pointers.end();) {
2895                     if (pointerIter->id == event.id) {
2896                         pointerIter = pointers.erase(pointerIter);
2897                     } else {
2898                         ++pointerIter;
2899                     }
2900                 }
2901                 ++iter;
2902             }
2903         }
2904         if (!history.empty()) {
2905             TouchEvent lastMoveEvent(history.back());
2906             lastMoveEvent.history.swap(history);
2907             eventManager_->SetLastMoveBeforeUp(event.sourceType == SourceType::MOUSE);
2908             eventManager_->DispatchTouchEvent(lastMoveEvent);
2909             eventManager_->SetLastMoveBeforeUp(false);
2910         } else {
2911             TAG_LOGD(AceLogTag::ACE_INPUTTRACKING,
2912                 "Finger id: %{public}d, not found unhandled move event, compensate failed.", event.id);
2913         }
2914         return true;
2915     }
2916     return false;
2917 }
2918 
CompensateTouchMoveEvent(const TouchEvent & event)2919 void PipelineContext::CompensateTouchMoveEvent(const TouchEvent& event)
2920 {
2921     if (event.type != TouchType::UP) {
2922         // If not up, no need to compensate touch move event.
2923         return;
2924     }
2925     if (!CompensateTouchMoveEventFromUnhandledEvents(event)) {
2926         // Compensate touch move event with all touch move Event before up has been handled.
2927         auto lastEventIter = eventManager_->GetIdToTouchPoint().find(event.id);
2928         if (lastEventIter != eventManager_->GetIdToTouchPoint().end()) {
2929             auto iter = eventManager_->GetLastDispatchTime().find(lastEventIter->first);
2930             if (iter != eventManager_->GetLastDispatchTime().end()) {
2931                 ACE_SCOPED_TRACE("CompensateTouchMoveEvent last move event time: %s last dispatch time: %s",
2932                     std::to_string(static_cast<uint64_t>(lastEventIter->second.time.time_since_epoch().count()))
2933                         .c_str(),
2934                     std::to_string(iter->second).c_str());
2935                 if (static_cast<uint64_t>(lastEventIter->second.time.time_since_epoch().count()) > iter->second) {
2936                     eventManager_->SetLastMoveBeforeUp(event.sourceType == SourceType::MOUSE);
2937                     eventManager_->DispatchTouchEvent(lastEventIter->second);
2938                     eventManager_->SetLastMoveBeforeUp(false);
2939                 }
2940             }
2941         }
2942     }
2943 
2944     auto lastEventIter = eventManager_->GetIdToTouchPoint().find(event.id);
2945     if (lastEventIter != eventManager_->GetIdToTouchPoint().end()) {
2946         ACE_SCOPED_TRACE("Finger id: %d process last move event eventId: %d", lastEventIter->first,
2947             lastEventIter->second.touchEventId);
2948     }
2949 }
2950 
ResetDraggingStatus(const TouchEvent & touchPoint,const RefPtr<FrameNode> & node)2951 void PipelineContext::ResetDraggingStatus(const TouchEvent& touchPoint, const RefPtr<FrameNode>& node)
2952 {
2953     auto manager = GetDragDropManager();
2954     CHECK_NULL_VOID(manager);
2955     manager->ResetDraggingStatus(touchPoint);
2956 }
2957 
OnSurfaceDensityChanged(double density)2958 void PipelineContext::OnSurfaceDensityChanged(double density)
2959 {
2960     CHECK_RUN_ON(UI);
2961     if (!NearEqual(density, density_)) {
2962         isDensityChanged_ = true;
2963         isNeedReloadDensity_ = true;
2964     }
2965     density_ = density;
2966     if (!NearZero(viewScale_)) {
2967         dipScale_ = density_ / viewScale_;
2968     }
2969     if (isNeedReloadDensity_) {
2970         UIObserverHandler::GetInstance().NotifyDensityChange(density_);
2971         PipelineBase::OnSurfaceDensityChanged(density);
2972     }
2973 }
2974 
DumpPageViewData(const RefPtr<FrameNode> & node,RefPtr<ViewDataWrap> viewDataWrap,bool skipSubAutoFillContainer,bool needsRecordData)2975 bool PipelineContext::DumpPageViewData(const RefPtr<FrameNode>& node, RefPtr<ViewDataWrap> viewDataWrap,
2976     bool skipSubAutoFillContainer, bool needsRecordData)
2977 {
2978     CHECK_NULL_RETURN(viewDataWrap, false);
2979     CHECK_NULL_RETURN(rootNode_, false);
2980     auto rootRect = GetRootRect();
2981     rootRect.SetOffset(rootNode_->GetPositionToScreenWithTransform());
2982     viewDataWrap->SetPageRect(rootRect);
2983     RefPtr<FrameNode> pageNode = nullptr;
2984     RefPtr<FrameNode> dumpNode = nullptr;
2985     if (node == nullptr) {
2986         if (stageManager_) {
2987             pageNode = stageManager_->GetLastPage();
2988             dumpNode = pageNode;
2989         }
2990     } else {
2991         pageNode = node->GetPageNode();
2992         dumpNode = node;
2993     }
2994     CHECK_NULL_RETURN(dumpNode, false);
2995     dumpNode->DumpViewDataPageNodes(viewDataWrap, skipSubAutoFillContainer, needsRecordData);
2996     // The page path may not be obtained in the container, use the node tag as the page path.
2997     if (node) {
2998         const auto& nodeTag = node->GetTag();
2999         if (nodeTag == V2::DIALOG_ETS_TAG || nodeTag == V2::SHEET_PAGE_TAG ||
3000             nodeTag == V2::MODAL_PAGE_TAG || nodeTag == V2::POPUP_ETS_TAG) {
3001             viewDataWrap->SetPageUrl(nodeTag);
3002             return true;
3003         }
3004     }
3005     CHECK_NULL_RETURN(pageNode, false);
3006     auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
3007     CHECK_NULL_RETURN(pagePattern, false);
3008     auto pageInfo = pagePattern->GetPageInfo();
3009     CHECK_NULL_RETURN(pageInfo, false);
3010     viewDataWrap->SetPageUrl(pageInfo->GetPageUrl());
3011     return true;
3012 }
3013 
CheckNeedAutoSave()3014 bool PipelineContext::CheckNeedAutoSave()
3015 {
3016     CHECK_NULL_RETURN(stageManager_, false);
3017     auto pageNode = stageManager_->GetLastPage();
3018     CHECK_NULL_RETURN(pageNode, false);
3019     return pageNode->NeedRequestAutoSave();
3020 }
3021 
CheckOverlayFocus()3022 bool PipelineContext::CheckOverlayFocus()
3023 {
3024     CHECK_NULL_RETURN(overlayManager_, false);
3025     auto overlayNode = overlayManager_->GetOverlayNode();
3026     CHECK_NULL_RETURN(overlayNode, false);
3027     return overlayNode->GetFocusHub() && overlayNode->GetFocusHub()->IsCurrentFocus();
3028 }
3029 
NotifyFillRequestSuccess(AceAutoFillType autoFillType,RefPtr<ViewDataWrap> viewDataWrap)3030 void PipelineContext::NotifyFillRequestSuccess(AceAutoFillType autoFillType, RefPtr<ViewDataWrap> viewDataWrap)
3031 {
3032     CHECK_NULL_VOID(viewDataWrap);
3033     auto pageNodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
3034     for (const auto& item : pageNodeInfoWraps) {
3035         if (item == nullptr) {
3036             continue;
3037         }
3038         auto frameNode = DynamicCast<FrameNode>(ElementRegister::GetInstance()->GetUINodeById(item->GetId()));
3039         if (frameNode == nullptr) {
3040             TAG_LOGW(AceLogTag::ACE_AUTO_FILL, "frameNode is not found, id=%{public}d", item->GetId());
3041             continue;
3042         }
3043         frameNode->NotifyFillRequestSuccess(viewDataWrap, item, autoFillType);
3044     }
3045 }
3046 
NotifyFillRequestFailed(RefPtr<FrameNode> node,int32_t errCode,const std::string & fillContent,bool isPopup)3047 void PipelineContext::NotifyFillRequestFailed(RefPtr<FrameNode> node, int32_t errCode,
3048     const std::string& fillContent, bool isPopup)
3049 {
3050     CHECK_NULL_VOID(node);
3051     node->NotifyFillRequestFailed(errCode, fillContent, isPopup);
3052 }
3053 
DumpFocus(bool hasJson) const3054 void PipelineContext::DumpFocus(bool hasJson) const
3055 {
3056     auto rootFocusHub = rootNode_->GetFocusHub();
3057     CHECK_NULL_VOID(rootFocusHub);
3058     rootFocusHub->DumpFocusTree(0, hasJson);
3059     if (hasJson) {
3060         DumpLog::GetInstance().PrintEndDumpInfoNG();
3061     }
3062 }
3063 
DumpInspector(const std::vector<std::string> & params,bool hasJson) const3064 void PipelineContext::DumpInspector(const std::vector<std::string>& params, bool hasJson) const
3065 {
3066     auto accessibilityManager = GetAccessibilityManager();
3067     if (accessibilityManager) {
3068         accessibilityManager->OnDumpInfoNG(params, windowId_, hasJson);
3069         if (hasJson) {
3070             DumpLog::GetInstance().PrintEndDumpInfoNG();
3071         }
3072     }
3073 }
3074 
DumpData(const RefPtr<FrameNode> & node,const std::vector<std::string> & params,bool hasJson) const3075 void PipelineContext::DumpData(
3076     const RefPtr<FrameNode>& node, const std::vector<std::string>& params, bool hasJson) const
3077 {
3078     CHECK_NULL_VOID(node);
3079     std::string pid = "";
3080     for (auto param : params) {
3081         if (param.find("-") == std::string::npos) {
3082             pid = param;
3083             LOGD("Find pid in element dump pipeline");
3084         }
3085     }
3086 
3087     int32_t depth = 0;
3088     if (IsDynamicRender()) {
3089         depth = GetDepthFromParams(params);
3090     }
3091     if (pid == "") {
3092         LOGD("Dump element without pid");
3093         node->DumpTree(depth, hasJson);
3094         if (hasJson) {
3095             DumpLog::GetInstance().PrintEndDumpInfoNG(true);
3096         }
3097         DumpLog::GetInstance().OutPutBySize();
3098     } else {
3099         node->DumpTreeById(depth, params[PARAM_NUM], hasJson);
3100     }
3101 }
3102 
DumpElement(const std::vector<std::string> & params,bool hasJson) const3103 void PipelineContext::DumpElement(const std::vector<std::string>& params, bool hasJson) const
3104 {
3105     if (params.size() > 1 && params[1] == "-lastpage") {
3106         auto lastPage = stageManager_->GetLastPage();
3107         DumpData(lastPage, params, hasJson);
3108     } else {
3109         DumpData(rootNode_, params, hasJson);
3110     }
3111 }
3112 
DumpResLoadError() const3113 void PipelineContext::DumpResLoadError() const
3114 {
3115     ResourceManager::GetInstance().DumpResLoadError();
3116 }
3117 
OnDumpInfo(const std::vector<std::string> & params) const3118 bool PipelineContext::OnDumpInfo(const std::vector<std::string>& params) const
3119 {
3120     bool hasJson = params.back() == "-json";
3121     int32_t depth = 0;
3122     if (IsDynamicRender()) {
3123         depth = GetDepthFromParams(params);
3124     }
3125 
3126     if (window_) {
3127         DumpLog::GetInstance().Print(1, "LastRequestVsyncTime: " + std::to_string(window_->GetLastRequestVsyncTime()));
3128 #ifdef ENABLE_ROSEN_BACKEND
3129         auto rsUIDirector = window_->GetRSUIDirector();
3130         if (rsUIDirector) {
3131             DumpLog::GetInstance().Print(1, "transactionFlags: [" + std::to_string(getpid()) + "," +
3132                 std::to_string(rsUIDirector->GetIndex()) + "]");
3133         }
3134 #endif
3135     }
3136     DumpLog::GetInstance().Print(1, "last vsyncId: " + std::to_string(GetFrameCount()));
3137     DumpLog::GetInstance().Print(1, "finishCount:" + GetUnexecutedFinishCount());
3138     if (params[0] == "-element") {
3139         DumpElement(params, hasJson);
3140     } else if (params[0] == "-navigation") {
3141         auto navigationDumpMgr = GetNavigationManager();
3142         if (navigationDumpMgr) {
3143             navigationDumpMgr->OnDumpInfo();
3144         }
3145     } else if (params[0] == "-focus") {
3146         DumpFocus(hasJson);
3147     } else if (params[0] == "-focuswindowscene") {
3148         auto windowSceneNode = GetFocusedWindowSceneNode();
3149         auto windowSceneFocusHub = windowSceneNode ? windowSceneNode->GetFocusHub() : nullptr;
3150         if (windowSceneFocusHub) {
3151             windowSceneFocusHub->DumpFocusTree(0);
3152         }
3153     } else if (params[0] == "-focusmanager") {
3154         if (focusManager_) {
3155             focusManager_->DumpFocusManager();
3156         }
3157     } else if (params[0] == "-accessibility") {
3158         auto accessibilityManager = GetAccessibilityManager();
3159         if (accessibilityManager) {
3160             accessibilityManager->OnDumpInfoNG(params, windowId_);
3161         }
3162     } else if (params[0] == "-inspector") {
3163         DumpInspector(params, hasJson);
3164     } else if (params[0] == "-rotation" && params.size() >= 2) {
3165     } else if (params[0] == "-animationscale" && params.size() >= 2) {
3166     } else if (params[0] == "-velocityscale" && params.size() >= 2) {
3167     } else if (params[0] == "-scrollfriction" && params.size() >= 2) {
3168     } else if (params[0] == "-threadstuck" && params.size() >= 3) {
3169     } else if (params[0] == "-pipeline") {
3170         DumpPipelineInfo();
3171     } else if (params[0] == "-jsdump") {
3172         std::vector<std::string> jsParams;
3173         if (params.begin() != params.end()) {
3174             jsParams = std::vector<std::string>(params.begin() + 1, params.end());
3175         }
3176 
3177         auto stageNode = stageManager_->GetStageNode();
3178         CHECK_NULL_RETURN(stageNode, false);
3179         auto children = stageNode->GetChildren();
3180         for (const auto& pageNode : children) {
3181             auto frameNode = AceType::DynamicCast<FrameNode>(pageNode);
3182             CHECK_NULL_RETURN(frameNode, false);
3183             auto pagePattern = frameNode->GetPattern<PagePattern>();
3184             CHECK_NULL_RETURN(pagePattern, false);
3185             pagePattern->FireDumpListener(jsParams);
3186         }
3187     } else if (params[0] == "-event") {
3188         if (eventManager_) {
3189             eventManager_->DumpEvent(EventTreeType::TOUCH, hasJson);
3190         }
3191         DumpUIExt();
3192     } else if (params[0] == "-postevent") {
3193         if (eventManager_) {
3194             eventManager_->DumpEvent(EventTreeType::POST_EVENT, hasJson);
3195         }
3196     } else if (params[0] == "-imagecache") {
3197         if (imageCache_) {
3198             imageCache_->DumpCacheInfo();
3199         }
3200         DumpUIExt();
3201     } else if (params[0] == "-imagefilecache") {
3202         ImageFileCache::GetInstance().DumpCacheInfo();
3203         DumpUIExt();
3204     } else if (params[0] == "-allelements") {
3205         AceEngine::Get().NotifyContainers([](const RefPtr<Container>& container) {
3206             auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
3207             auto rootNode = pipeline->GetRootElement();
3208             if (rootNode) {
3209                 DumpLog::GetInstance().Print(0, "ContainerId: " + std::to_string(Container::CurrentId()));
3210                 rootNode->DumpTree(0);
3211                 DumpLog::GetInstance().OutPutBySize();
3212             }
3213         });
3214     } else if (params[0] == "-default") {
3215         rootNode_->DumpTree(depth);
3216         DumpLog::GetInstance().OutPutDefault();
3217     } else if (params[0] == "-overlay") {
3218         if (overlayManager_) {
3219             overlayManager_->DumpOverlayInfo();
3220         }
3221     } else if (params[0] == "--stylus") {
3222         StylusDetectorDefault::GetInstance()->ExecuteCommand(params);
3223     } else if (params[0] == "-simplify") {
3224         LOGI("start collect simplify dump info");
3225         rootNode_->DumpTree(0);
3226         DumpLog::GetInstance().OutPutByCompress();
3227         LOGI("end collect simplify dump info");
3228     } else if (params[0] == "-resource") {
3229         DumpResLoadError();
3230     } else if (params[0] == "-start") {
3231         OnDumpRecorderStart(params);
3232     } else if (params[0] == "-end") {
3233         DumpRecorder::GetInstance().Stop();
3234     }
3235     return true;
3236 }
3237 
OnDumpRecorderStart(const std::vector<std::string> & params) const3238 void PipelineContext::OnDumpRecorderStart(const std::vector<std::string>& params) const
3239 {
3240     int32_t recordTime = DEFAULT_RECORD_SECOND;
3241     if (static_cast<uint32_t>(sizeof(params)) <= 1) {
3242         return;
3243     }
3244     int32_t inputTime = StringUtils::StringToInt(params[1]);
3245     if (inputTime > 0) {
3246         recordTime = inputTime;
3247     }
3248     recordTime = std::min(recordTime, MAX_RECORD_SECOND);
3249     int64_t startTime = GetCurrentTimestamp();
3250     auto taskExecutor = GetTaskExecutor();
3251     std::function<bool()> dumpFunc = [startTime, recordTime, weakRoot = WeakClaim(RawPtr(rootNode_))]() {
3252         int64_t currentTime = GetCurrentTimestamp();
3253         if ((currentTime - startTime) >= recordTime * SECOND_TO_MILLISEC) {
3254             return false;
3255         }
3256         auto root = weakRoot.Upgrade();
3257         CHECK_NULL_RETURN(root, false);
3258         auto jsonRoot = JsonUtil::Create(true);
3259         root->DumpTreeJsonForDiff(jsonRoot);
3260         DumpRecorder::GetInstance().Record(currentTime, std::move(jsonRoot));
3261         return true;
3262     };
3263     DumpRecorder::GetInstance().Start(std::move(dumpFunc));
3264 }
3265 
TriggerFrameDumpFuncIfExist() const3266 void PipelineContext::TriggerFrameDumpFuncIfExist() const
3267 {
3268     auto frameDumpFunc = DumpRecorder::GetInstance().GetFrameDumpFunc();
3269     CHECK_NULL_VOID(frameDumpFunc);
3270     if (!frameDumpFunc()) {
3271         DumpRecorder::GetInstance().Stop();
3272     }
3273 }
3274 
DumpUIExt() const3275 void PipelineContext::DumpUIExt() const
3276 {
3277 #ifdef WINDOW_SCENE_SUPPORTED
3278     if (uiExtensionManager_) {
3279         uiExtensionManager_->DumpUIExt();
3280     }
3281 #endif
3282 }
3283 
GetCurrentFrameInfo(uint64_t recvTime,uint64_t timeStamp)3284 FrameInfo* PipelineContext::GetCurrentFrameInfo(uint64_t recvTime, uint64_t timeStamp)
3285 {
3286     if (SystemProperties::GetDumpFrameCount() == 0) {
3287         return nullptr;
3288     }
3289     if (dumpFrameInfos_.size() >= SystemProperties::GetDumpFrameCount()) {
3290         dumpFrameInfos_.pop_front();
3291     }
3292 
3293     dumpFrameInfos_.push_back({ .frameRecvTime_ = recvTime, .frameTimeStamp_ = timeStamp });
3294     return &dumpFrameInfos_.back();
3295 }
3296 
DumpPipelineInfo() const3297 void PipelineContext::DumpPipelineInfo() const
3298 {
3299     DumpLog::GetInstance().Print("PipelineInfo:");
3300     if (window_) {
3301         DumpLog::GetInstance().Print(1, "DisplayRefreshRate: " + std::to_string(window_->GetRefreshRate()));
3302         DumpLog::GetInstance().Print(1, "LastRequestVsyncTime: " + std::to_string(window_->GetLastRequestVsyncTime()));
3303         DumpLog::GetInstance().Print(1, "NowTime: " + std::to_string(GetSysTimestamp()));
3304     }
3305     if (!dumpFrameInfos_.empty()) {
3306         DumpLog::GetInstance().Print("==================================FrameTask==================================");
3307         for (const auto& info : dumpFrameInfos_) {
3308             DumpLog::GetInstance().Print("Task: " + info.GetTimeInfo());
3309             DumpLog::GetInstance().Print(1, "LayoutTask:");
3310             for (const auto& layout : info.layoutInfos_) {
3311                 DumpLog::GetInstance().Print(2, layout.ToString());
3312             }
3313             DumpLog::GetInstance().Print(1, "RenderTask:");
3314             for (const auto& layout : info.renderInfos_) {
3315                 DumpLog::GetInstance().Print(2, layout.ToString());
3316             }
3317             DumpLog::GetInstance().Print(
3318                 "==================================FrameTask==================================");
3319         }
3320     }
3321 }
3322 
CollectTouchEventsBeforeVsync(std::list<TouchEvent> & touchEvents)3323 void PipelineContext::CollectTouchEventsBeforeVsync(std::list<TouchEvent>& touchEvents)
3324 {
3325     auto targetTimeStamp = compensationValue_ > 0 ? GetVsyncTime() - compensationValue_ : GetVsyncTime();
3326     for (auto iter = touchEvents_.begin(); iter != touchEvents_.end();) {
3327         auto timeStamp = std::chrono::duration_cast<std::chrono::nanoseconds>(iter->time.time_since_epoch()).count();
3328         if (targetTimeStamp < static_cast<uint64_t>(timeStamp)) {
3329             iter++;
3330             continue;
3331         }
3332         touchEvents.emplace_back(*iter);
3333         iter = touchEvents_.erase(iter);
3334     }
3335 }
3336 
FlushTouchEvents()3337 void PipelineContext::FlushTouchEvents()
3338 {
3339     CHECK_RUN_ON(UI);
3340     CHECK_NULL_VOID(rootNode_);
3341     {
3342         std::list<TouchEvent> touchEvents;
3343         CollectTouchEventsBeforeVsync(touchEvents);
3344         if (touchEvents.empty()) {
3345             canUseLongPredictTask_ = true;
3346             return;
3347         }
3348         canUseLongPredictTask_ = false;
3349         eventManager_->FlushTouchEventsBegin(touchEvents_);
3350         std::unordered_map<int, TouchEvent> idToTouchPoints;
3351         if (touchAccelarate_) {
3352             AccelerateConsumeTouchEvents(touchEvents, idToTouchPoints);
3353         } else {
3354             ConsumeTouchEvents(touchEvents, idToTouchPoints);
3355         }
3356         auto maxSize = touchEvents.size();
3357         for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) {
3358             maxSize--;
3359             if (maxSize == 0) {
3360                 eventManager_->FlushTouchEventsEnd(touchEvents);
3361             }
3362             eventManager_->DispatchTouchEvent(*iter);
3363         }
3364         eventManager_->SetIdToTouchPoint(std::move(idToTouchPoints));
3365     }
3366 }
3367 
ConsumeTouchEvents(std::list<TouchEvent> & touchEvents,std::unordered_map<int,TouchEvent> & idToTouchPoints)3368 void PipelineContext::ConsumeTouchEvents(
3369     std::list<TouchEvent>& touchEvents, std::unordered_map<int, TouchEvent>& idToTouchPoints)
3370 {
3371     bool needInterpolation = true;
3372     std::unordered_map<int32_t, TouchEvent> newIdTouchPoints;
3373     for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) {
3374         auto scalePoint = (*iter).CreateScalePoint(GetViewScale());
3375         idToTouchPoints.emplace(scalePoint.id, scalePoint);
3376         idToTouchPoints[scalePoint.id].history.insert(idToTouchPoints[scalePoint.id].history.begin(), scalePoint);
3377         needInterpolation = iter->type != TouchType::MOVE ? false : true;
3378     }
3379     if (!NeedTouchInterpolation()) {
3380         needInterpolation = false;
3381     }
3382     if (needInterpolation) {
3383         auto targetTimeStamp = resampleTimeStamp_;
3384         for (const auto& idIter : idToTouchPoints) {
3385             auto stamp =
3386                 std::chrono::duration_cast<std::chrono::nanoseconds>(idIter.second.time.time_since_epoch()).count();
3387             if (targetTimeStamp > static_cast<uint64_t>(stamp)) {
3388                 continue;
3389             }
3390             TouchEvent newTouchEvent;
3391             if (eventManager_->GetResampleTouchEvent(
3392                     historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp, newTouchEvent)) {
3393                 newIdTouchPoints[idIter.first] = newTouchEvent;
3394             }
3395             historyPointsById_[idIter.first] = idIter.second.history;
3396         }
3397     }
3398     touchEvents.clear();
3399     for (const auto& iter : idToTouchPoints) {
3400         auto lastDispatchTime = eventManager_->GetLastDispatchTime();
3401         lastDispatchTime[iter.first] = GetVsyncTime() - compensationValue_;
3402         eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
3403         auto it = newIdTouchPoints.find(iter.first);
3404         if (it != newIdTouchPoints.end()) {
3405             touchEvents.emplace_back(it->second);
3406         } else {
3407             touchEvents.emplace_back(iter.second);
3408         }
3409     }
3410 }
3411 
GetResampleStamp() const3412 uint64_t PipelineContext::GetResampleStamp() const
3413 {
3414     constexpr uint64_t RESAMPLE_LANTENCY = 5 * ONE_MS_IN_NS;
3415     uint64_t vsyncTime = GetVsyncTime();
3416     return std::min(vsyncTime - RESAMPLE_LANTENCY, vsyncTime - compensationValue_);
3417 }
3418 
AccelerateConsumeTouchEvents(std::list<TouchEvent> & touchEvents,std::unordered_map<int,TouchEvent> & idToTouchPoints)3419 void PipelineContext::AccelerateConsumeTouchEvents(
3420     std::list<TouchEvent>& touchEvents, std::unordered_map<int, TouchEvent>& idToTouchPoints)
3421 {
3422     // consume touchEvents and generate idToTouchPoints.
3423     for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) {
3424         auto scalePoint = iter->CreateScalePoint(GetViewScale());
3425         idToTouchPoints.emplace(scalePoint.id, scalePoint);
3426         auto& history = idToTouchPoints[scalePoint.id].history;
3427         history.emplace(history.begin(), std::move(scalePoint));
3428     }
3429     bool needInterpolation = (touchEvents.front().type == TouchType::MOVE) && NeedTouchInterpolation();
3430     auto& lastDispatchTime = eventManager_->GetLastDispatchTime();
3431     auto curVsyncArrivalTime = GetVsyncTime() - compensationValue_;
3432     touchEvents.clear();
3433 
3434     // resample and generate event to dispatch in touchEvents
3435     if (needInterpolation) {
3436         auto targetTimeStamp = GetResampleStamp();
3437         for (const auto& idIter : idToTouchPoints) {
3438             TouchEvent newTouchEvent;
3439             eventManager_->TryResampleTouchEvent(
3440                 historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp, newTouchEvent);
3441             lastDispatchTime[idIter.first] = curVsyncArrivalTime;
3442             touchEvents.emplace_back(newTouchEvent);
3443         }
3444         auto idToTouchPoint = eventManager_->GetIdToTouchPoint();
3445         idToTouchPoint = std::move(idToTouchPoints);
3446         eventManager_->SetIdToTouchPoint(std::move(idToTouchPoint));
3447     } else {
3448         for (const auto& idIter : idToTouchPoints) {
3449             lastDispatchTime[idIter.first] = curVsyncArrivalTime;
3450             touchEvents.emplace_back(idIter.second);
3451         }
3452     }
3453 }
3454 
OnAccessibilityHoverEvent(const TouchEvent & point,const RefPtr<NG::FrameNode> & node)3455 void PipelineContext::OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node)
3456 {
3457     CHECK_RUN_ON(UI);
3458     auto scaleEvent = point.CreateScalePoint(viewScale_);
3459     if (scaleEvent.type != TouchType::HOVER_MOVE) {
3460 #ifdef IS_RELEASE_VERSION
3461         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
3462             "OnAccessibilityHoverEvent event id:%{public}d, fingerId:%{public}d,"
3463             "type=%{public}d, "
3464             "inject=%{public}d",
3465             scaleEvent.touchEventId, scaleEvent.id, (int)scaleEvent.type, scaleEvent.isInjected);
3466 #else
3467         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
3468             "OnAccessibilityHoverEvent event id:%{public}d, fingerId:%{public}d, x=%{public}f y=%{public}f "
3469             "type=%{public}d, "
3470             "inject=%{public}d",
3471             scaleEvent.touchEventId, scaleEvent.id, scaleEvent.x, scaleEvent.y, (int)scaleEvent.type,
3472             scaleEvent.isInjected);
3473 #endif
3474     }
3475     auto targerNode = node ? node : rootNode_;
3476     if (accessibilityManagerNG_ != nullptr) {
3477         accessibilityManagerNG_->HandleAccessibilityHoverEvent(targerNode, scaleEvent);
3478     }
3479     TouchRestrict touchRestrict { TouchRestrict::NONE };
3480     touchRestrict.sourceType = scaleEvent.sourceType;
3481     // use mouse to collect accessibility hover target
3482     touchRestrict.hitTestType = SourceType::MOUSE;
3483     touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
3484     eventManager_->AccessibilityHoverTest(scaleEvent, targerNode, touchRestrict);
3485     eventManager_->DispatchAccessibilityHoverEventNG(scaleEvent);
3486     RequestFrame();
3487 }
3488 
OnPenHoverEvent(const TouchEvent & point,const RefPtr<NG::FrameNode> & node)3489 void PipelineContext::OnPenHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node)
3490 {
3491     CHECK_RUN_ON(UI);
3492     auto scaleEvent = point.CreateScalePoint(viewScale_);
3493     if (scaleEvent.type != TouchType::MOVE) {
3494         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
3495             "OnPenHoverEvent event id:%{public}d, fingerId:%{public}d "
3496             "type=%{public}d, "
3497             "inject=%{public}d",
3498             scaleEvent.touchEventId, scaleEvent.id, (int)scaleEvent.type,
3499             scaleEvent.isInjected);
3500     }
3501 
3502     auto targerNode = node ? node : rootNode_;
3503     TouchRestrict touchRestrict { TouchRestrict::NONE };
3504     touchRestrict.sourceType = scaleEvent.sourceType;
3505     touchRestrict.touchEvent.sourceTool = scaleEvent.sourceTool;
3506     touchRestrict.touchEvent.type = scaleEvent.type;
3507     touchRestrict.touchEvent.force = scaleEvent.force;
3508 
3509     // use mouse to collect pen hover target
3510     touchRestrict.hitTestType = SourceType::MOUSE;
3511     touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
3512     eventManager_->PenHoverTest(scaleEvent, targerNode, touchRestrict);
3513     eventManager_->DispatchPenHoverEventNG(scaleEvent);
3514     eventManager_->DispatchPenHoverMoveEventNG(scaleEvent);
3515     RequestFrame();
3516 }
3517 
HandlePenHoverOut(const TouchEvent & point)3518 void PipelineContext::HandlePenHoverOut(const TouchEvent& point)
3519 {
3520     if (point.sourceTool != SourceTool::PEN || point.type != TouchType::DOWN || NearZero(point.force)) {
3521         return;
3522     }
3523 
3524     CHECK_RUN_ON(UI);
3525     auto oriPoint = point;
3526     oriPoint.type = TouchType::PROXIMITY_OUT;
3527 
3528     TouchTestResult testResult;
3529     eventManager_->UpdatePenHoverNode(oriPoint, testResult);
3530     eventManager_->DispatchPenHoverEventNG(oriPoint);
3531 }
3532 
CancelDragIfRightBtnPressed(const MouseEvent & event)3533 void PipelineContext::CancelDragIfRightBtnPressed(const MouseEvent& event)
3534 {
3535     auto manager = GetDragDropManager();
3536     if (!manager) {
3537         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "InputTracking id:%{public}d, OnMouseEvent GetDragDropManager is null",
3538             event.touchEventId);
3539         return;
3540     }
3541     if (event.button == MouseButton::RIGHT_BUTTON &&
3542         (event.action == MouseAction::PRESS || event.action == MouseAction::PULL_UP)) {
3543         manager->SetIsDragCancel(true);
3544         return;
3545     }
3546     manager->SetIsDragCancel(false);
3547 }
3548 
UpdateLastMoveEvent(const MouseEvent & event)3549 void PipelineContext::UpdateLastMoveEvent(const MouseEvent& event)
3550 {
3551     if (!lastMouseEvent_) {
3552         lastMouseEvent_ = std::make_unique<MouseEvent>();
3553     }
3554     if (event.mockFlushEvent && event.action == MouseAction::WINDOW_LEAVE) {
3555         lastMouseEvent_->isMockWindowTransFlag = true;
3556     }
3557     lastMouseEvent_->x = event.x;
3558     lastMouseEvent_->y = event.y;
3559     lastMouseEvent_->button = event.button;
3560     lastMouseEvent_->action = event.action;
3561     lastMouseEvent_->sourceType = event.sourceType;
3562     lastMouseEvent_->time = event.time;
3563     lastMouseEvent_->touchEventId = event.touchEventId;
3564     lastMouseEvent_->mockFlushEvent = event.mockFlushEvent;
3565     lastMouseEvent_->pointerEvent = event.pointerEvent;
3566     lastMouseEvent_->deviceId = event.deviceId;
3567     lastMouseEvent_->sourceTool = event.sourceTool;
3568     lastSourceType_ = event.sourceType;
3569 }
3570 
OnMouseEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)3571 void PipelineContext::OnMouseEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
3572 {
3573     CHECK_RUN_ON(UI);
3574     UpdateLastMoveEvent(event);
3575     lastMouseEvent_->node = node;
3576     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE) {
3577 #ifdef IS_RELEASE_VERSION
3578         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
3579             "InputTracking id:%{public}d, mouseId:%{public}d, type=%{public}d, button=%{public}d, inject=%{public}d",
3580             event.touchEventId, event.id, (int)event.action, (int)event.button, event.isInjected);
3581 #else
3582         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW,
3583             "InputTracking id:%{public}d, mouseId:%{public}d, x=%{public}.3f, y=%{public}.3f, z=%{public}.3f, "
3584             "type=%{public}d, button=%{public}d"
3585             "inject=%{public}d",
3586             event.touchEventId, event.id, event.x, event.y, event.z, (int)event.action, (int)event.button,
3587             event.isInjected);
3588 #endif
3589     }
3590 
3591     if (event.button == MouseButton::RIGHT_BUTTON && event.action == MouseAction::PRESS) {
3592         // Mouse right button press event set focus inactive here.
3593         // Mouse left button press event will set focus inactive in touch process.
3594         SetIsFocusActive(false, FocusActiveReason::POINTER_EVENT);
3595     }
3596     CancelDragIfRightBtnPressed(event);
3597 
3598     if (event.action == MouseAction::RELEASE || event.action == MouseAction::CANCEL ||
3599         event.action == MouseAction::WINDOW_LEAVE) {
3600         lastMouseTime_ = GetTimeFromExternalTimer();
3601         CompensateMouseMoveEvent(event, node);
3602     }
3603     DispatchMouseToTouchEvent(event, node);
3604     if (event.action == MouseAction::MOVE) {
3605         if (dragDropManager_ && dragDropManager_->IsDragging() && event.pullAction != MouseAction::PULL_MOVE) {
3606             auto pointerEvent = DragPointerEvent(event.x, event.y, event.screenX, event.screenY);
3607             dragDropManager_->SetDragAnimationPointerEvent(pointerEvent);
3608         }
3609         mouseEvents_[node].emplace_back(event);
3610         hasIdleTasks_ = true;
3611         RequestFrame();
3612         return;
3613     }
3614     DispatchMouseEvent(event, node);
3615 }
3616 
DispatchMouseToTouchEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)3617 void PipelineContext::DispatchMouseToTouchEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
3618 {
3619     CHECK_NULL_VOID(node);
3620     if (((event.action == MouseAction::RELEASE || event.action == MouseAction::PRESS ||
3621             event.action == MouseAction::MOVE) &&
3622             (event.button == MouseButton::LEFT_BUTTON || event.pressedButtons == MOUSE_PRESS_LEFT)) ||
3623         event.action == MouseAction::CANCEL) {
3624         auto touchPoint = event.CreateTouchPoint();
3625         if (event.pullAction == MouseAction::PULL_MOVE) {
3626             touchPoint.pullType = TouchType::PULL_MOVE;
3627         }
3628         OnTouchEvent(touchPoint, node);
3629     } else {
3630         auto touchPoint = event.CreateTouchPoint();
3631         auto scalePoint = touchPoint.CreateScalePoint(GetViewScale());
3632         auto rootOffset = GetRootRect().GetOffset();
3633         eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
3634     }
3635 }
3636 
CompensateMouseMoveEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)3637 void PipelineContext::CompensateMouseMoveEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
3638 {
3639     if (CompensateMouseMoveEventFromUnhandledEvents(event, node)) {
3640         return;
3641     }
3642     auto lastEventIter = nodeToMousePoints_.find(node);
3643     if (lastEventIter == nodeToMousePoints_.end() || lastEventIter->second.empty()) {
3644         return;
3645     }
3646     MouseEvent mouseEvent = lastEventIter->second.back();
3647     auto iter = eventManager_->GetLastDispatchTime().find(mouseEvent.id);
3648     if (iter != eventManager_->GetLastDispatchTime().end()) {
3649         if (static_cast<uint64_t>(mouseEvent.time.time_since_epoch().count()) > iter->second) {
3650             TouchRestrict touchRestrict { TouchRestrict::NONE };
3651             touchRestrict.sourceType = event.sourceType;
3652             touchRestrict.hitTestType = SourceType::MOUSE;
3653             touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3654             eventManager_->MouseTest(mouseEvent, node, touchRestrict);
3655             eventManager_->DispatchMouseEventNG(mouseEvent);
3656             eventManager_->DispatchMouseHoverEventNG(mouseEvent);
3657             eventManager_->DispatchMouseHoverAnimationNG(mouseEvent);
3658         }
3659     }
3660 }
3661 
CompensateMouseMoveEventFromUnhandledEvents(const MouseEvent & event,const RefPtr<FrameNode> & node)3662 bool PipelineContext::CompensateMouseMoveEventFromUnhandledEvents(
3663     const MouseEvent& event, const RefPtr<FrameNode>& node)
3664 {
3665     if (mouseEvents_.empty()) {
3666         return false;
3667     }
3668 
3669     auto iter = mouseEvents_.find(node);
3670     if (iter == mouseEvents_.end()) {
3671         return false;
3672     }
3673     std::vector<MouseEvent> history;
3674     for (auto mouseIter = iter->second.begin(); mouseIter != iter->second.end();) {
3675         if (event.id == mouseIter->id) {
3676             history.emplace_back(*mouseIter);
3677             mouseIter = iter->second.erase(mouseIter);
3678         } else {
3679             mouseIter++;
3680         }
3681     }
3682     mouseEvents_.erase(iter);
3683 
3684     if (history.empty()) {
3685         return false;
3686     }
3687 
3688     MouseEvent lastMoveEvent(history.back());
3689     lastMoveEvent.history.swap(history);
3690     TouchRestrict touchRestrict { TouchRestrict::NONE };
3691     touchRestrict.sourceType = event.sourceType;
3692     touchRestrict.hitTestType = SourceType::MOUSE;
3693     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3694     eventManager_->MouseTest(lastMoveEvent, node, touchRestrict);
3695     eventManager_->DispatchMouseEventNG(lastMoveEvent);
3696     eventManager_->DispatchMouseHoverEventNG(lastMoveEvent);
3697     eventManager_->DispatchMouseHoverAnimationNG(lastMoveEvent);
3698     return true;
3699 }
3700 
DispatchMouseEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)3701 void PipelineContext::DispatchMouseEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
3702 {
3703     CHECK_NULL_VOID(node);
3704     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3705     if (scaleEvent.action != MouseAction::MOVE &&
3706         historyMousePointsById_.find(scaleEvent.id) != historyMousePointsById_.end()) {
3707         historyMousePointsById_.erase(scaleEvent.id);
3708     }
3709 
3710     TouchRestrict touchRestrict { TouchRestrict::NONE };
3711     touchRestrict.sourceType = event.sourceType;
3712     touchRestrict.hitTestType = SourceType::MOUSE;
3713     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3714     if (event.action != MouseAction::MOVE) {
3715         eventManager_->MouseTest(scaleEvent, node, touchRestrict);
3716         eventManager_->DispatchMouseEventNG(scaleEvent);
3717         eventManager_->DispatchMouseHoverEventNG(scaleEvent);
3718         eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
3719     }
3720     accessibilityManagerNG_->HandleAccessibilityHoverEvent(node, scaleEvent);
3721     RequestFrame();
3722 }
3723 
FlushMouseEvent()3724 void PipelineContext::FlushMouseEvent()
3725 {
3726     if (!lastMouseEvent_ || lastMouseEvent_->action == MouseAction::WINDOW_LEAVE) {
3727         return;
3728     }
3729     MouseEvent event;
3730     event.x = lastMouseEvent_->x;
3731     event.y = lastMouseEvent_->y;
3732     event.time = lastMouseEvent_->time;
3733     event.action = MouseAction::MOVE;
3734     event.button = MouseButton::NONE_BUTTON;
3735     event.sourceType = SourceType::MOUSE;
3736     event.deviceId = lastMouseEvent_->deviceId;
3737     event.sourceTool = SourceTool::MOUSE;
3738 
3739     CHECK_RUN_ON(UI);
3740     CHECK_NULL_VOID(rootNode_);
3741     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3742     TouchRestrict touchRestrict { TouchRestrict::NONE };
3743     touchRestrict.sourceType = event.sourceType;
3744     touchRestrict.hitTestType = SourceType::MOUSE;
3745     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
3746     OnFlushMouseEvent(touchRestrict);
3747 }
3748 
OnFlushMouseEvent(TouchRestrict & touchRestrict)3749 void PipelineContext::OnFlushMouseEvent(TouchRestrict& touchRestrict)
3750 {
3751     decltype(mouseEvents_) mouseEvents(std::move(mouseEvents_));
3752     if (mouseEvents.empty()) {
3753         canUseLongPredictTask_ = true;
3754         nodeToMousePoints_.clear();
3755         return;
3756     }
3757     canUseLongPredictTask_ = false;
3758     for (auto iter = mouseEvents.begin(); iter != mouseEvents.end(); ++iter) {
3759         OnFlushMouseEvent(iter->first, iter->second, touchRestrict);
3760     }
3761 }
3762 
OnFlushMouseEvent(const RefPtr<FrameNode> & node,const std::list<MouseEvent> & mouseEvents,TouchRestrict & touchRestrict)3763 void PipelineContext::OnFlushMouseEvent(
3764     const RefPtr<FrameNode> &node, const std::list<MouseEvent>& mouseEvents, TouchRestrict& touchRestrict)
3765 {
3766     if (mouseEvents.empty()) {
3767         canUseLongPredictTask_ = true;
3768         return ;
3769     }
3770     canUseLongPredictTask_ = false;
3771     std::unordered_map<int, MouseEvent> idToMousePoints;
3772     bool needInterpolation = true;
3773     std::unordered_map<int32_t, MouseEvent> newIdMousePoints;
3774     std::map<RefPtr<FrameNode>, std::vector<MouseEvent>> nodeToMousePoints;
3775     for (auto iter = mouseEvents.rbegin(); iter != mouseEvents.rend(); ++iter) {
3776         auto scaleEvent = (*iter).CreateScaleEvent(GetViewScale());
3777         idToMousePoints.emplace(scaleEvent.id, scaleEvent);
3778         if (!iter->mockFlushEvent) {
3779             idToMousePoints[scaleEvent.id].history.insert(idToMousePoints[scaleEvent.id].history.begin(), scaleEvent);
3780         }
3781         nodeToMousePoints[node].emplace_back(idToMousePoints[scaleEvent.id]);
3782         needInterpolation = iter->action != MouseAction::MOVE ? false : true;
3783     }
3784     if (!NeedTouchInterpolation()) {
3785         needInterpolation = false;
3786     }
3787     if (needInterpolation) {
3788         auto targetTimeStamp = resampleTimeStamp_;
3789         for (const auto& idIter : idToMousePoints) {
3790             auto stamp =
3791                 std::chrono::duration_cast<std::chrono::nanoseconds>(idIter.second.time.time_since_epoch()).count();
3792             if (targetTimeStamp > static_cast<uint64_t>(stamp)) {
3793                 LOGI("there is no mouse event after interpolation time point. "
3794                     "(last stamp:%{public}" PRIu64 ", target stamp:%{public}" PRIu64 ")",
3795                     static_cast<uint64_t>(stamp), targetTimeStamp);
3796                 continue;
3797             }
3798             if (idIter.second.button == MouseButton::NONE_BUTTON) {
3799                 continue;
3800             }
3801             MouseEvent newMouseEvent = eventManager_->GetResampleMouseEvent(
3802                 historyMousePointsById_[idIter.first], idIter.second.history, targetTimeStamp);
3803             if (newMouseEvent.x != 0 && newMouseEvent.y != 0) {
3804                 newIdMousePoints[idIter.first] = newMouseEvent;
3805             }
3806             historyMousePointsById_[idIter.first] = idIter.second.history;
3807         }
3808     }
3809     nodeToMousePoints_ = std::move(nodeToMousePoints);
3810     DispatchMouseEvent(idToMousePoints, newIdMousePoints, mouseEvents, touchRestrict, node);
3811 }
3812 
DispatchMouseEvent(std::unordered_map<int,MouseEvent> & idToMousePoints,std::unordered_map<int32_t,MouseEvent> & newIdMousePoints,const std::list<MouseEvent> & mouseEvents,TouchRestrict & touchRestrict,const RefPtr<FrameNode> & node)3813 void PipelineContext::DispatchMouseEvent(
3814     std::unordered_map<int, MouseEvent>& idToMousePoints,
3815     std::unordered_map<int32_t, MouseEvent> &newIdMousePoints,
3816     const std::list<MouseEvent> &mouseEvents,
3817     TouchRestrict& touchRestrict,
3818     const RefPtr<FrameNode> &node)
3819 {
3820     std::list<MouseEvent> mousePoints;
3821     for (const auto& iter : idToMousePoints) {
3822         auto lastDispatchTime = eventManager_->GetLastDispatchTime();
3823         lastDispatchTime[iter.first] = GetVsyncTime();
3824         eventManager_->SetLastDispatchTime(std::move(lastDispatchTime));
3825         auto it = newIdMousePoints.find(iter.first);
3826         if (it != newIdMousePoints.end()) {
3827             mousePoints.emplace_back(it->second);
3828         } else {
3829             mousePoints.emplace_back(iter.second);
3830         }
3831     }
3832     for (auto iter = mousePoints.rbegin(); iter != mousePoints.rend(); ++iter) {
3833         auto scaleEvent = iter->CreateScaleEvent(viewScale_);
3834         eventManager_->MouseTest(scaleEvent, node, touchRestrict);
3835         eventManager_->DispatchMouseEventNG(scaleEvent);
3836         eventManager_->DispatchMouseHoverEventNG(scaleEvent);
3837         eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
3838     }
3839 }
3840 
ChangeMouseStyle(int32_t nodeId,MouseFormat format,int32_t windowId,bool isByPass,MouseStyleChangeReason reason)3841 bool PipelineContext::ChangeMouseStyle(int32_t nodeId, MouseFormat format, int32_t windowId, bool isByPass,
3842     MouseStyleChangeReason reason)
3843 {
3844     auto mouseStyleManager = eventManager_->GetMouseStyleManager();
3845     CHECK_NULL_RETURN(mouseStyleManager, false);
3846     mouseStyleManager->SetMouseFormat(windowId, nodeId, format, isByPass, reason);
3847     RequestFrame();
3848     return true;
3849 }
3850 
ReDispatch(KeyEvent & keyEvent)3851 void PipelineContext::ReDispatch(KeyEvent& keyEvent)
3852 {
3853     CHECK_NULL_VOID(eventManager_);
3854     TAG_LOGD(AceLogTag::ACE_WEB, "Web ReDispach key event: code:" SEC_PLD(%{public}d) "/action:%{public}d.",
3855         SEC_PARAM(keyEvent.code), keyEvent.action);
3856     eventManager_->ReDispatch(keyEvent);
3857 }
3858 
OnNonPointerEvent(const NonPointerEvent & event)3859 bool PipelineContext::OnNonPointerEvent(const NonPointerEvent& event)
3860 {
3861     return eventManager_->OnNonPointerEvent(event);
3862 }
3863 
RequestFocus(const std::string & targetNodeId,bool isSyncRequest)3864 bool PipelineContext::RequestFocus(const std::string& targetNodeId, bool isSyncRequest)
3865 {
3866     auto rootNode = GetFocusedWindowSceneNode();
3867     if (!rootNode) {
3868         rootNode = rootNode_;
3869     }
3870     CHECK_NULL_RETURN(rootNode, false);
3871     auto focusHub = rootNode->GetFocusHub();
3872     CHECK_NULL_RETURN(focusHub, false);
3873     auto currentFocusChecked = focusHub->RequestFocusImmediatelyById(targetNodeId, isSyncRequest);
3874     if (!isSubPipeline_ || currentFocusChecked) {
3875         return currentFocusChecked;
3876     }
3877     auto parentPipelineBase = parentPipeline_.Upgrade();
3878     CHECK_NULL_RETURN(parentPipelineBase, false);
3879     auto parentPipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentPipelineBase);
3880     CHECK_NULL_RETURN(parentPipelineContext, false);
3881     return parentPipelineContext->RequestFocus(targetNodeId, isSyncRequest);
3882 }
3883 
AddDirtyFocus(const RefPtr<FrameNode> & node)3884 void PipelineContext::AddDirtyFocus(const RefPtr<FrameNode>& node)
3885 {
3886     CHECK_RUN_ON(UI);
3887     CHECK_NULL_VOID(node);
3888     if (node->GetFocusType() == FocusType::NODE) {
3889         dirtyFocusNode_ = WeakClaim(RawPtr(node));
3890     } else {
3891         dirtyFocusScope_ = WeakClaim(RawPtr(node));
3892     }
3893     RequestFrame();
3894 }
3895 
AddDirtyRequestFocus(const RefPtr<FrameNode> & node)3896 void PipelineContext::AddDirtyRequestFocus(const RefPtr<FrameNode>& node)
3897 {
3898     CHECK_RUN_ON(UI);
3899     CHECK_NULL_VOID(node);
3900     dirtyRequestFocusNode_ = WeakPtr<FrameNode>(node);
3901     RequestFrame();
3902 }
3903 
RootLostFocus(BlurReason reason) const3904 void PipelineContext::RootLostFocus(BlurReason reason) const
3905 {
3906     CHECK_NULL_VOID(rootNode_);
3907     auto focusHub = rootNode_->GetFocusHub();
3908     CHECK_NULL_VOID(focusHub);
3909     focusHub->LostFocus(reason);
3910     CHECK_NULL_VOID(overlayManager_);
3911     overlayManager_->HideAllMenus();
3912 }
3913 
ConvertAxisToMouse(const AxisEvent & event)3914 MouseEvent ConvertAxisToMouse(const AxisEvent& event)
3915 {
3916     MouseEvent result;
3917     result.x = event.x;
3918     result.y = event.y;
3919     result.action = MouseAction::MOVE;
3920     result.button = MouseButton::NONE_BUTTON;
3921     result.time = event.time;
3922     result.deviceId = event.deviceId;
3923     result.sourceType = event.sourceType;
3924     result.sourceTool = event.sourceTool;
3925     result.touchEventId = event.touchEventId;
3926     result.pointerEvent = event.pointerEvent;
3927     result.screenX = event.screenX;
3928     result.screenY = event.screenY;
3929     return result;
3930 }
3931 
OnAxisEvent(const AxisEvent & event,const RefPtr<FrameNode> & node)3932 void PipelineContext::OnAxisEvent(const AxisEvent& event, const RefPtr<FrameNode>& node)
3933 {
3934     if (!axisEventChecker_.IsAxisEventSequenceCorrect(event)) {
3935         TAG_LOGW(AceLogTag::ACE_INPUTKEYFLOW,
3936             "AxisEvent error occurred, the currentAction is %{public}d, the preAction is %{public}d", event.action,
3937             axisEventChecker_.GetPreAction());
3938     }
3939     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3940     auto formEventMgr = this->GetFormEventManager();
3941     SerializedGesture etsSerializedGesture;
3942     if (event.action != AxisAction::BEGIN && formEventMgr) {
3943         formEventMgr->HandleEtsCardAxisEvent(scaleEvent, etsSerializedGesture);
3944     }
3945 
3946     DispatchAxisEventToDragDropManager(event, node, etsSerializedGesture);
3947     // when api >= 15, do not block end and cancel action.
3948     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_FIFTEEN)) {
3949         if (event.action != AxisAction::NONE) {
3950             eventManager_->AxisTest(scaleEvent, node);
3951             eventManager_->DispatchAxisEventNG(scaleEvent);
3952         }
3953     } else {
3954         if (event.action == AxisAction::BEGIN || event.action == AxisAction::UPDATE) {
3955             eventManager_->AxisTest(scaleEvent, node);
3956             eventManager_->DispatchAxisEventNG(scaleEvent);
3957         }
3958     }
3959     if (event.action == AxisAction::BEGIN && formEventMgr) {
3960         formEventMgr->HandleEtsCardAxisEvent(scaleEvent, etsSerializedGesture);
3961     }
3962     if (scaleEvent.action == AxisAction::BEGIN) {
3963         TAG_LOGD(AceLogTag::ACE_MOUSE, "Slide Axis Begin");
3964         ResSchedReport::GetInstance().OnAxisEvent(scaleEvent);
3965     } else if (scaleEvent.verticalAxis == 0 && scaleEvent.horizontalAxis == 0) {
3966         TAG_LOGD(AceLogTag::ACE_MOUSE, "Slide Axis End");
3967         ResSchedReport::GetInstance().ResSchedDataReport("axis_off");
3968     } else {
3969         TAG_LOGD(AceLogTag::ACE_MOUSE, "Slide Axis Update");
3970         ResSchedReport::GetInstance().OnAxisEvent(scaleEvent);
3971     }
3972     if (event.action == AxisAction::BEGIN || event.action == AxisAction::CANCEL || event.action == AxisAction::END) {
3973         eventManager_->GetEventTreeRecord(EventTreeType::TOUCH).AddAxis(scaleEvent);
3974     }
3975     auto mouseEvent = ConvertAxisToMouse(event);
3976     OnMouseMoveEventForAxisEvent(mouseEvent, node);
3977     if (formEventMgr && ((scaleEvent.action == AxisAction::END) || (scaleEvent.action == AxisAction::CANCEL))) {
3978         formEventMgr->RemoveEtsCardAxisEventCallback(event.id);
3979         formEventMgr->RemoveEtsCardTouchEventCallback(event.id);
3980     }
3981 }
3982 
DispatchAxisEventToDragDropManager(const AxisEvent & event,const RefPtr<FrameNode> & node,SerializedGesture & etsSerializedGesture)3983 void PipelineContext::DispatchAxisEventToDragDropManager(const AxisEvent& event, const RefPtr<FrameNode>& node,
3984     SerializedGesture& etsSerializedGesture)
3985 {
3986     auto scaleEvent = event.CreateScaleEvent(viewScale_);
3987     auto dragManager = GetDragDropManager();
3988     if (dragManager && !dragManager->IsDragged()) {
3989         if (event.action == AxisAction::BEGIN) {
3990             isBeforeDragHandleAxis_ = true;
3991             TouchRestrict touchRestrict { TouchRestrict::NONE };
3992             touchRestrict.sourceType = event.sourceType;
3993             touchRestrict.hitTestType = SourceType::TOUCH;
3994             touchRestrict.inputEventType = InputEventType::AXIS;
3995             // If received rotate event, no need to touchtest.
3996             if (!event.isRotationEvent) {
3997                 eventManager_->TouchTest(scaleEvent, node, touchRestrict);
3998                 auto axisTouchTestResults_ = eventManager_->GetAxisTouchTestResults();
3999                 auto formEventMgr = this->GetFormEventManager();
4000                 if (formEventMgr) {
4001                     formEventMgr->HandleEtsCardTouchEvent(touchRestrict.touchEvent, etsSerializedGesture);
4002                 }
4003                 auto formGestureMgr =  this->GetFormGestureManager();
4004                 if (formGestureMgr) {
4005                     formGestureMgr->LinkGesture(event, this, node, axisTouchTestResults_,
4006                         etsSerializedGesture, eventManager_);
4007                 }
4008             }
4009         }
4010         eventManager_->DispatchTouchEvent(scaleEvent);
4011     } else if (isBeforeDragHandleAxis_ && (event.action == AxisAction::END || event.action == AxisAction::CANCEL)) {
4012         eventManager_->DispatchTouchEvent(scaleEvent);
4013         isBeforeDragHandleAxis_ = false;
4014     }
4015 }
4016 
OnMouseMoveEventForAxisEvent(const MouseEvent & event,const RefPtr<NG::FrameNode> & node)4017 void PipelineContext::OnMouseMoveEventForAxisEvent(const MouseEvent& event, const RefPtr<NG::FrameNode>& node)
4018 {
4019     if (event.action != MouseAction::MOVE || event.button != MouseButton::NONE_BUTTON) {
4020         return;
4021     }
4022     CHECK_RUN_ON(UI);
4023     UpdateLastMoveEvent(event);
4024     auto manager = GetDragDropManager();
4025     if (manager) {
4026         manager->SetIsDragCancel(false);
4027     } else {
4028         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "InputTracking id:%{public}d, OnMouseEvent GetDragDropManager is null",
4029             event.touchEventId);
4030     }
4031     auto touchPoint = event.CreateTouchPoint();
4032     auto scalePoint = touchPoint.CreateScalePoint(GetViewScale());
4033     auto rootOffset = GetRootRect().GetOffset();
4034     eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
4035     CHECK_NULL_VOID(node);
4036     auto scaleEvent = event.CreateScaleEvent(viewScale_);
4037     TouchRestrict touchRestrict { TouchRestrict::NONE };
4038     touchRestrict.sourceType = event.sourceType;
4039     touchRestrict.hitTestType = SourceType::MOUSE;
4040     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
4041     eventManager_->MouseTest(scaleEvent, node, touchRestrict);
4042     eventManager_->DispatchMouseEventNG(scaleEvent);
4043     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
4044     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
4045     accessibilityManagerNG_->HandleAccessibilityHoverEvent(node, scaleEvent);
4046     RequestFrame();
4047 }
4048 
HasDifferentDirectionGesture() const4049 bool PipelineContext::HasDifferentDirectionGesture() const
4050 {
4051     CHECK_NULL_RETURN(eventManager_, false);
4052     return eventManager_->HasDifferentDirectionGesture();
4053 }
4054 
AddVisibleAreaChangeNode(const int32_t nodeId)4055 void PipelineContext::AddVisibleAreaChangeNode(const int32_t nodeId)
4056 {
4057     onVisibleAreaChangeNodeIds_.emplace(nodeId);
4058 }
4059 
AddVisibleAreaChangeNode(const RefPtr<FrameNode> & node,const std::vector<double> & ratios,const VisibleRatioCallback & callback,bool isUserCallback,bool isCalculateInnerClip)4060 void PipelineContext::AddVisibleAreaChangeNode(const RefPtr<FrameNode>& node,
4061     const std::vector<double>& ratios, const VisibleRatioCallback& callback, bool isUserCallback,
4062     bool isCalculateInnerClip)
4063 {
4064     CHECK_NULL_VOID(node);
4065     VisibleCallbackInfo addInfo;
4066     addInfo.callback = callback;
4067     addInfo.isCurrentVisible = false;
4068     onVisibleAreaChangeNodeIds_.emplace(node->GetId());
4069     if (isUserCallback) {
4070         node->SetVisibleAreaUserCallback(ratios, addInfo);
4071     } else {
4072         node->SetVisibleAreaInnerCallback(ratios, addInfo, isCalculateInnerClip);
4073     }
4074 }
4075 
RemoveVisibleAreaChangeNode(int32_t nodeId)4076 void PipelineContext::RemoveVisibleAreaChangeNode(int32_t nodeId)
4077 {
4078     onVisibleAreaChangeNodeIds_.erase(nodeId);
4079 }
4080 
HandleVisibleAreaChangeEvent(uint64_t nanoTimestamp)4081 void PipelineContext::HandleVisibleAreaChangeEvent(uint64_t nanoTimestamp)
4082 {
4083     ACE_FUNCTION_TRACE();
4084     if (onVisibleAreaChangeNodeIds_.empty()) {
4085         return;
4086     }
4087     auto nodes = FrameNode::GetNodesById(onVisibleAreaChangeNodeIds_);
4088     for (auto&& frameNode : nodes) {
4089         frameNode->TriggerVisibleAreaChangeCallback(nanoTimestamp);
4090     }
4091 }
4092 
AddOnAreaChangeNode(int32_t nodeId)4093 void PipelineContext::AddOnAreaChangeNode(int32_t nodeId)
4094 {
4095     onAreaChangeNodeIds_.emplace(nodeId);
4096     isOnAreaChangeNodesCacheVaild_ = false;
4097 }
4098 
RemoveOnAreaChangeNode(int32_t nodeId)4099 void PipelineContext::RemoveOnAreaChangeNode(int32_t nodeId)
4100 {
4101     onAreaChangeNodeIds_.erase(nodeId);
4102     isOnAreaChangeNodesCacheVaild_ = false;
4103 }
4104 
HasOnAreaChangeNode(int32_t nodeId)4105 bool PipelineContext::HasOnAreaChangeNode(int32_t nodeId)
4106 {
4107     return onAreaChangeNodeIds_.find(nodeId) != onAreaChangeNodeIds_.end();
4108 }
4109 
HandleOnAreaChangeEvent(uint64_t nanoTimestamp)4110 void PipelineContext::HandleOnAreaChangeEvent(uint64_t nanoTimestamp)
4111 {
4112     ACE_FUNCTION_TRACE();
4113     if (onAreaChangeNodeIds_.empty()) {
4114         return;
4115     }
4116     auto nodes = FrameNode::GetNodesById(onAreaChangeNodeIds_);
4117     for (auto&& frameNode : nodes) {
4118         frameNode->TriggerOnAreaChangeCallback(nanoTimestamp);
4119     }
4120     UpdateFormLinkInfos();
4121 }
4122 
UpdateFormLinkInfos()4123 void PipelineContext::UpdateFormLinkInfos()
4124 {
4125     if (formLinkInfoUpdateHandler_ && !formLinkInfoMap_.empty()) {
4126         std::vector<std::string> formLinkInfos;
4127         for (auto iter = formLinkInfoMap_.rbegin(); iter != formLinkInfoMap_.rend(); ++iter) {
4128             auto info = iter->second;
4129             formLinkInfos.push_back(info);
4130         }
4131         formLinkInfoUpdateHandler_(formLinkInfos);
4132     }
4133 }
4134 
OnShow()4135 void PipelineContext::OnShow()
4136 {
4137     CHECK_RUN_ON(UI);
4138     onShow_ = true;
4139     window_->OnShow();
4140     PerfMonitor::GetPerfMonitor()->SetAppForeground(true);
4141     RequestFrame();
4142     FlushWindowStateChangedCallback(true);
4143     AccessibilityEvent event;
4144     event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
4145     event.type = AccessibilityEventType::PAGE_CHANGE;
4146     SendEventToAccessibility(event);
4147 }
4148 
OnHide()4149 void PipelineContext::OnHide()
4150 {
4151     CHECK_RUN_ON(UI);
4152     auto dragDropManager = GetDragDropManager();
4153     if (dragDropManager && dragDropManager->IsItemDragging()) {
4154         dragDropManager->CancelItemDrag();
4155     }
4156     onShow_ = false;
4157     window_->OnHide();
4158     PerfMonitor::GetPerfMonitor()->SetAppForeground(false);
4159     RequestFrame();
4160     OnVirtualKeyboardAreaChange(Rect());
4161     FlushWindowStateChangedCallback(false);
4162     AccessibilityEvent event;
4163     event.type = AccessibilityEventType::PAGE_CLOSE;
4164     SendEventToAccessibility(event);
4165     memoryMgr_->PostMemRecycleTask();
4166 }
4167 
WindowFocus(bool isFocus)4168 void PipelineContext::WindowFocus(bool isFocus)
4169 {
4170     CHECK_RUN_ON(UI);
4171     onFocus_ = isFocus;
4172     if (!isFocus) {
4173         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window: %{public}d lost focus.", windowId_);
4174         RestoreDefault();
4175         RootLostFocus(BlurReason::WINDOW_BLUR);
4176         NotifyPopupDismiss();
4177     } else {
4178         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window: %{public}d get focus.", windowId_);
4179 
4180         isWindowHasFocused_ = true;
4181         InputMethodManager::GetInstance()->SetWindowFocus(true);
4182     }
4183     GetOrCreateFocusManager()->WindowFocus(isFocus);
4184     FlushWindowFocusChangedCallback(isFocus);
4185 }
4186 
WindowActivate(bool isActive)4187 void PipelineContext::WindowActivate(bool isActive)
4188 {
4189     CHECK_RUN_ON(UI);
4190     onActive_ = isActive;
4191     FlushWindowActivateChangedCallback(isActive);
4192 }
4193 
ContainerModalUnFocus()4194 void PipelineContext::ContainerModalUnFocus()
4195 {
4196     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4197         return;
4198     }
4199     CHECK_NULL_VOID(rootNode_);
4200     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4201     CHECK_NULL_VOID(containerNode);
4202     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4203     CHECK_NULL_VOID(containerPattern);
4204     containerPattern->OnWindowForceUnfocused();
4205 }
4206 
ShowContainerTitle(bool isShow,bool hasDeco,bool needUpdate)4207 void PipelineContext::ShowContainerTitle(bool isShow, bool hasDeco, bool needUpdate)
4208 {
4209     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4210         return;
4211     }
4212     CHECK_NULL_VOID(rootNode_);
4213     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4214     CHECK_NULL_VOID(containerNode);
4215     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4216     CHECK_NULL_VOID(containerPattern);
4217     containerPattern->ShowTitle(isShow, hasDeco, needUpdate);
4218     isShowTitle_ = isShow && hasDeco;
4219 }
4220 
UpdateTitleInTargetPos(bool isShow,int32_t height)4221 void PipelineContext::UpdateTitleInTargetPos(bool isShow, int32_t height)
4222 {
4223     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4224         return;
4225     }
4226     CHECK_NULL_VOID(rootNode_);
4227     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4228     CHECK_NULL_VOID(containerNode);
4229     auto containerPattern = containerNode->GetPattern<ContainerModalPatternEnhance>();
4230     CHECK_NULL_VOID(containerPattern);
4231     containerPattern->UpdateTitleInTargetPos(isShow, height);
4232 }
4233 
4234 
SetContainerWindow(bool isShow,RRect & rRect)4235 void PipelineContext::SetContainerWindow(bool isShow, RRect& rRect)
4236 {
4237 #ifdef ENABLE_ROSEN_BACKEND
4238     if (!IsJsCard()) {
4239         auto window = GetWindow();
4240         if (window) {
4241             auto rect = rRect.GetRect();
4242             OHOS::Rosen::RectF rosenRectF = {rect.GetOffset().GetX(), rect.GetOffset().GetY(),
4243                 rect.Width(), rect.Height()};
4244             auto radiusValueX = rRect.GetCorner().topLeftRadius.GetX().Value();
4245             auto radiusValueY = rRect.GetCorner().topLeftRadius.GetY().Value();
4246 
4247             auto rosenRRect = OHOS::Rosen::RRect(rosenRectF, radiusValueX, radiusValueY);
4248             auto rsUIDirector = window->GetRSUIDirector();
4249             if (rsUIDirector) {
4250                 // set container window show state to render service
4251                 TAG_LOGD(AceLogTag::ACE_APPBAR, "SetContainerWindow: isShow=%{public}d; "
4252                     "x=%{public}f, y=%{public}f, width=%{public}f, hight=%{public}f, radiusValueX=%{public}f.",
4253                     isShow, rect.GetOffset().GetX(), rect.GetOffset().GetY(),
4254                     rect.Width(), rect.Height(), radiusValueX);
4255                 rsUIDirector->SetContainerWindow(isShow, rosenRRect);
4256             }
4257         }
4258     }
4259 #endif
4260 }
4261 
SetAppBgColor(const Color & color)4262 void PipelineContext::SetAppBgColor(const Color& color)
4263 {
4264     appBgColor_ = color;
4265 #ifdef ENABLE_ROSEN_BACKEND
4266     if (!IsJsCard()) {
4267         auto window = GetWindow();
4268         if (window) {
4269             auto rsUIDirector = window->GetRSUIDirector();
4270             if (rsUIDirector) {
4271                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
4272             }
4273         }
4274     }
4275 #endif
4276     CHECK_NULL_VOID(stageManager_);
4277     auto stage = stageManager_->GetStageNode();
4278     CHECK_NULL_VOID(stage);
4279     auto renderContext = stage->GetRenderContext();
4280     CHECK_NULL_VOID(renderContext);
4281     renderContext->UpdateBackgroundColor(color);
4282 }
4283 
SetAppTitle(const std::string & title)4284 void PipelineContext::SetAppTitle(const std::string& title)
4285 {
4286     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4287         return;
4288     }
4289     CHECK_NULL_VOID(rootNode_);
4290     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4291     CHECK_NULL_VOID(containerNode);
4292     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4293     CHECK_NULL_VOID(containerPattern);
4294     containerPattern->SetAppTitle(title);
4295 }
4296 
SetAppIcon(const RefPtr<PixelMap> & icon)4297 void PipelineContext::SetAppIcon(const RefPtr<PixelMap>& icon)
4298 {
4299     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4300         return;
4301     }
4302     CHECK_NULL_VOID(rootNode_);
4303     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4304     CHECK_NULL_VOID(containerNode);
4305     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4306     CHECK_NULL_VOID(containerPattern);
4307     containerPattern->SetAppIcon(icon);
4308 }
4309 
FlushReload(const ConfigurationChange & configurationChange,bool fullUpdate)4310 void PipelineContext::FlushReload(const ConfigurationChange& configurationChange, bool fullUpdate)
4311 {
4312     AnimationOption option;
4313     const int32_t duration = 400;
4314     option.SetDuration(duration);
4315     option.SetCurve(Curves::FRICTION);
4316     RecycleManager::Notify(configurationChange);
4317     AnimationUtils::Animate(
4318         option,
4319         [weak = WeakClaim(this), configurationChange,
4320             weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager_)), fullUpdate]() {
4321             auto pipeline = weak.Upgrade();
4322             CHECK_NULL_VOID(pipeline);
4323             if (configurationChange.IsNeedUpdate() || configurationChange.iconUpdate) {
4324                 auto rootNode = pipeline->GetRootElement();
4325                 rootNode->UpdateConfigurationUpdate(configurationChange);
4326                 auto overlay = weakOverlayManager.Upgrade();
4327                 if (overlay) {
4328                     overlay->ReloadBuilderNodeConfig();
4329                 }
4330             }
4331             if (fullUpdate && configurationChange.IsNeedUpdate()) {
4332                 CHECK_NULL_VOID(pipeline->stageManager_);
4333                 pipeline->SetIsReloading(true);
4334                 pipeline->stageManager_->ReloadStage();
4335                 pipeline->SetIsReloading(false);
4336                 pipeline->FlushUITasks();
4337             }
4338         },
4339         [weak = WeakClaim(this)]() {
4340             auto pipeline = weak.Upgrade();
4341             CHECK_NULL_VOID(pipeline);
4342             pipeline->OnFlushReloadFinish();
4343         });
4344     auto stage = stageManager_->GetStageNode();
4345     CHECK_NULL_VOID(stage);
4346     auto renderContext = stage->GetRenderContext();
4347     CHECK_NULL_VOID(renderContext);
4348     renderContext->UpdateWindowBlur();
4349 }
4350 
Destroy()4351 void PipelineContext::Destroy()
4352 {
4353     CHECK_RUN_ON(UI);
4354     SetDestroyed();
4355     rootNode_->DetachFromMainTree();
4356     std::unordered_set<UINode*> nodeSet;
4357     std::swap(nodeSet, attachedNodeSet_);
4358     for (auto& node : nodeSet) {
4359         node->DetachFromMainTree();
4360     }
4361     rootNode_->FireCustomDisappear();
4362     taskScheduler_->CleanUp();
4363     scheduleTasks_.clear();
4364     dirtyNodes_.clear();
4365     rootNode_.Reset();
4366     accessibilityManagerNG_.Reset();
4367     stageManager_.Reset();
4368     if (overlayManager_) {
4369         overlayManager_->ClearUIExtensionNode();
4370     }
4371     overlayManager_.Reset();
4372     sharedTransitionManager_.Reset();
4373     dragDropManager_.Reset();
4374     TAG_LOGI(AceLogTag::ACE_DRAG, "PipelineContext::Destroy Reset dragDropManager_");
4375     focusManager_.Reset();
4376     selectOverlayManager_.Reset();
4377     fullScreenManager_.Reset();
4378     memoryMgr_.Reset();
4379     nodeToMousePoints_.clear();
4380     nodeToPointEvent_.clear();
4381     touchEvents_.clear();
4382     mouseEvents_.clear();
4383     dragEvents_.clear();
4384     buildFinishCallbacks_.clear();
4385     onWindowStateChangedCallbacks_.clear();
4386     onWindowFocusChangedCallbacks_.clear();
4387     nodesToNotifyMemoryLevel_.clear();
4388     dirtyFocusNode_.Reset();
4389     dirtyFocusScope_.Reset();
4390     needRenderNode_.clear();
4391     dirtyRequestFocusNode_.Reset();
4392     if (textFieldManager_ && textFieldManager_->GetImeShow()) {
4393         InputMethodManager::GetInstance()->CloseKeyboardInPipelineDestroy();
4394     }
4395     auto formEventMgr = this->GetFormEventManager();
4396     if (formEventMgr) {
4397         formEventMgr->ClearEtsCardTouchEventCallback();
4398         formEventMgr->ClearEtsCardAxisEventCallback();
4399     }
4400 #ifdef WINDOW_SCENE_SUPPORTED
4401     uiExtensionManager_.Reset();
4402 #endif
4403     uiContextImpl_.Reset();
4404     PipelineBase::Destroy();
4405 }
4406 
AddBuildFinishCallBack(std::function<void ()> && callback)4407 void PipelineContext::AddBuildFinishCallBack(std::function<void()>&& callback)
4408 {
4409     buildFinishCallbacks_.emplace_back(std::move(callback));
4410 }
4411 
AddWindowStateChangedCallback(int32_t nodeId)4412 void PipelineContext::AddWindowStateChangedCallback(int32_t nodeId)
4413 {
4414     if (!CheckThreadSafe()) {
4415         LOGW("AddWindowStateChangedCallback doesn't run on UI thread!");
4416     }
4417     onWindowStateChangedCallbacks_.emplace(nodeId);
4418 }
4419 
RemoveWindowStateChangedCallback(int32_t nodeId)4420 void PipelineContext::RemoveWindowStateChangedCallback(int32_t nodeId)
4421 {
4422     if (!CheckThreadSafe()) {
4423         LOGW("RemoveWindowStateChangedCallback doesn't run on UI thread!");
4424     }
4425     onWindowStateChangedCallbacks_.erase(nodeId);
4426 }
4427 
FlushWindowStateChangedCallback(bool isShow)4428 void PipelineContext::FlushWindowStateChangedCallback(bool isShow)
4429 {
4430     if (!CheckThreadSafe()) {
4431         LOGW("FlushWindowStateChangedCallback doesn't run on UI thread!");
4432     }
4433     std::set<int32_t> onWindowStateChangedCallbacks;
4434     std::swap(onWindowStateChangedCallbacks, onWindowStateChangedCallbacks_);
4435     auto iter = onWindowStateChangedCallbacks.begin();
4436     while (iter != onWindowStateChangedCallbacks.end()) {
4437         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
4438         if (!node) {
4439             iter = onWindowStateChangedCallbacks.erase(iter);
4440         } else {
4441             if (isShow) {
4442                 node->OnWindowShow();
4443             } else {
4444                 node->OnWindowHide();
4445             }
4446             ++iter;
4447         }
4448     }
4449     std::swap(onWindowStateChangedCallbacks, onWindowStateChangedCallbacks_);
4450     HandleVisibleAreaChangeEvent(GetTimeFromExternalTimer());
4451     HandleSubwindow(isShow);
4452 }
4453 
AddWindowFocusChangedCallback(int32_t nodeId)4454 void PipelineContext::AddWindowFocusChangedCallback(int32_t nodeId)
4455 {
4456     onWindowFocusChangedCallbacks_.emplace(nodeId);
4457 }
4458 
RemoveWindowFocusChangedCallback(int32_t nodeId)4459 void PipelineContext::RemoveWindowFocusChangedCallback(int32_t nodeId)
4460 {
4461     onWindowFocusChangedCallbacks_.erase(nodeId);
4462 }
4463 
FlushWindowFocusChangedCallback(bool isFocus)4464 void PipelineContext::FlushWindowFocusChangedCallback(bool isFocus)
4465 {
4466     auto iter = onWindowFocusChangedCallbacks_.begin();
4467     while (iter != onWindowFocusChangedCallbacks_.end()) {
4468         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
4469         if (!node) {
4470             iter = onWindowFocusChangedCallbacks_.erase(iter);
4471         } else {
4472             if (isFocus) {
4473                 node->OnWindowFocused();
4474             } else {
4475                 node->OnWindowUnfocused();
4476             }
4477             ++iter;
4478         }
4479     }
4480 }
4481 
AddWindowActivateChangedCallback(int32_t nodeId)4482 void PipelineContext::AddWindowActivateChangedCallback(int32_t nodeId)
4483 {
4484     onWindowActivateChangedCallbacks_.emplace(nodeId);
4485 }
4486 
RemoveWindowActivateChangedCallback(int32_t nodeId)4487 void PipelineContext::RemoveWindowActivateChangedCallback(int32_t nodeId)
4488 {
4489     onWindowActivateChangedCallbacks_.erase(nodeId);
4490 }
4491 
FlushWindowActivateChangedCallback(bool isActivate)4492 void PipelineContext::FlushWindowActivateChangedCallback(bool isActivate)
4493 {
4494     auto iter = onWindowActivateChangedCallbacks_.begin();
4495     while (iter != onWindowActivateChangedCallbacks_.end()) {
4496         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
4497         if (!node) {
4498             iter = onWindowActivateChangedCallbacks_.erase(iter);
4499         } else {
4500             if (isActivate) {
4501                 node->OnWindowActivated();
4502             } else {
4503                 node->OnWindowDeactivated();
4504             }
4505             ++iter;
4506         }
4507     }
4508 }
4509 
AddWindowSizeChangeCallback(int32_t nodeId)4510 void PipelineContext::AddWindowSizeChangeCallback(int32_t nodeId)
4511 {
4512     onWindowSizeChangeCallbacks_.emplace_back(nodeId);
4513 }
4514 
RemoveWindowSizeChangeCallback(int32_t nodeId)4515 void PipelineContext::RemoveWindowSizeChangeCallback(int32_t nodeId)
4516 {
4517     onWindowSizeChangeCallbacks_.remove(nodeId);
4518 }
4519 
AddWindowSizeDragEndCallback(std::function<void ()> && callback)4520 void PipelineContext::AddWindowSizeDragEndCallback(std::function<void()>&& callback)
4521 {
4522     onWindowSizeDragEndCallbacks_.emplace_back(std::move(callback));
4523 }
4524 
SetIsWindowSizeDragging(bool isDragging)4525 void PipelineContext::SetIsWindowSizeDragging(bool isDragging)
4526 {
4527     isWindowSizeDragging_ = isDragging;
4528     if (!isDragging) {
4529         decltype(onWindowSizeDragEndCallbacks_) dragEndCallbacks(std::move(onWindowSizeDragEndCallbacks_));
4530         for (const auto& func : dragEndCallbacks) {
4531             if (func) {
4532                 func();
4533             }
4534         }
4535     }
4536 }
4537 
AddNavigationNode(int32_t pageId,WeakPtr<UINode> navigationNode)4538 void PipelineContext::AddNavigationNode(int32_t pageId, WeakPtr<UINode> navigationNode)
4539 {
4540     CHECK_RUN_ON(UI);
4541     pageToNavigationNodes_[pageId].push_back(navigationNode);
4542 }
4543 
RemoveNavigationNode(int32_t pageId,int32_t nodeId)4544 void PipelineContext::RemoveNavigationNode(int32_t pageId, int32_t nodeId)
4545 {
4546     CHECK_RUN_ON(UI);
4547     auto it = pageToNavigationNodes_.find(pageId);
4548     if (it != pageToNavigationNodes_.end() && !it->second.empty()) {
4549         for (auto iter = it->second.begin(); iter != it->second.end();) {
4550             auto navigationNode = AceType::DynamicCast<NavigationGroupNode>((*iter).Upgrade());
4551             if (navigationNode && navigationNode->GetId() == nodeId) {
4552                 iter = it->second.erase(iter);
4553             } else {
4554                 iter++;
4555             }
4556         }
4557     }
4558 }
4559 
FirePageChanged(int32_t pageId,bool isOnShow)4560 void PipelineContext::FirePageChanged(int32_t pageId, bool isOnShow)
4561 {
4562     CHECK_RUN_ON(UI);
4563     auto iter = pageToNavigationNodes_.find(pageId);
4564     if (iter == pageToNavigationNodes_.end()) {
4565         return;
4566     }
4567     for (auto navigationNode : iter->second) {
4568         NavigationPattern::FireNavigationChange(navigationNode.Upgrade(), isOnShow, true);
4569     }
4570 }
4571 
FlushWindowSizeChangeCallback(int32_t width,int32_t height,WindowSizeChangeReason type)4572 void PipelineContext::FlushWindowSizeChangeCallback(int32_t width, int32_t height, WindowSizeChangeReason type)
4573 {
4574     auto iter = onWindowSizeChangeCallbacks_.begin();
4575     while (iter != onWindowSizeChangeCallbacks_.end()) {
4576         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
4577         if (!node) {
4578             iter = onWindowSizeChangeCallbacks_.erase(iter);
4579         } else {
4580             node->OnWindowSizeChanged(width, height, type);
4581             ++iter;
4582         }
4583     }
4584 }
4585 
RequireSummary()4586 void PipelineContext::RequireSummary()
4587 {
4588     auto manager = GetDragDropManager();
4589     if (!manager) {
4590         TAG_LOGW(AceLogTag::ACE_DRAG, "require summary, dragDropManager is null");
4591         return;
4592     }
4593     manager->RequireSummary();
4594 }
4595 
OnDragEvent(const DragPointerEvent & pointerEvent,DragEventAction action,const RefPtr<NG::FrameNode> & node)4596 void PipelineContext::OnDragEvent(const DragPointerEvent& pointerEvent, DragEventAction action,
4597     const RefPtr<NG::FrameNode>& node)
4598 {
4599     auto manager = GetDragDropManager();
4600     CHECK_NULL_VOID(manager);
4601     std::string extraInfo = manager->GetExtraInfo();
4602     auto container = Container::Current();
4603     if (container && container->IsScenceBoardWindow()) {
4604         if (!manager->IsDragged() && manager->IsWindowConsumed()) {
4605             manager->SetIsWindowConsumed(false);
4606             return;
4607         }
4608     }
4609     if (action == DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER) {
4610         manager->RequireSummary();
4611         manager->OnDragStart(pointerEvent.GetPoint());
4612         return;
4613     }
4614     if (action == DragEventAction::DRAG_EVENT_OUT) {
4615         lastDragTime_ = GetTimeFromExternalTimer();
4616         CompensatePointerMoveEvent(pointerEvent, node);
4617         manager->OnDragMoveOut(pointerEvent);
4618         manager->ClearSummary();
4619         manager->ClearExtraInfo();
4620         manager->SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
4621         return;
4622     }
4623 
4624     if (action == DragEventAction::DRAG_EVENT_START) {
4625         manager->ResetPreTargetFrameNode(GetInstanceId());
4626         manager->RequireSummaryIfNecessary(pointerEvent);
4627         manager->SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
4628         TAG_LOGI(AceLogTag::ACE_DRAG, "start drag, current windowId is %{public}d", container->GetWindowId());
4629     }
4630     if (action == DragEventAction::DRAG_EVENT_END) {
4631         lastDragTime_ = GetTimeFromExternalTimer();
4632         CompensatePointerMoveEvent(pointerEvent, node);
4633         manager->OnDragEnd(pointerEvent, extraInfo, node);
4634         return;
4635     }
4636     if (action == DragEventAction::DRAG_EVENT_PULL_CANCEL) {
4637         lastDragTime_ = GetTimeFromExternalTimer();
4638         CompensatePointerMoveEvent(pointerEvent, node);
4639         manager->OnDragPullCancel(pointerEvent, extraInfo, node);
4640         return;
4641     }
4642     HandleOnDragEventMove(pointerEvent, action, node);
4643 }
4644 
HandleOnDragEventMove(const DragPointerEvent & pointerEvent,DragEventAction action,const RefPtr<NG::FrameNode> & node)4645 void PipelineContext::HandleOnDragEventMove(const DragPointerEvent& pointerEvent, DragEventAction action,
4646     const RefPtr<NG::FrameNode>& node)
4647 {
4648     auto manager = GetDragDropManager();
4649     CHECK_NULL_VOID(manager);
4650     std::string extraInfo = manager->GetExtraInfo();
4651     if (action == DragEventAction::DRAG_EVENT_MOVE) {
4652         manager->SetDragAnimationPointerEvent(pointerEvent);
4653         dragEvents_[node].emplace_back(pointerEvent);
4654         RequestFrame();
4655     }
4656     if (action != DragEventAction::DRAG_EVENT_MOVE &&
4657         historyPointsEventById_.find(pointerEvent.pointerId) != historyPointsEventById_.end()) {
4658         historyPointsEventById_.erase(pointerEvent.pointerId);
4659     }
4660     if (action != DragEventAction::DRAG_EVENT_MOVE) {
4661         manager->OnDragMove(pointerEvent, extraInfo, node);
4662     }
4663 }
4664 
CompensatePointerMoveEvent(const DragPointerEvent & event,const RefPtr<FrameNode> & node)4665 void PipelineContext::CompensatePointerMoveEvent(const DragPointerEvent& event, const RefPtr<FrameNode>& node)
4666 {
4667     auto manager = GetDragDropManager();
4668     std::string extraInfo = manager->GetExtraInfo();
4669     if (CompensatePointerMoveEventFromUnhandledEvents(event, node)) {
4670         return;
4671     }
4672     auto lastEventIter = nodeToPointEvent_.find(node);
4673     if (lastEventIter == nodeToPointEvent_.end() || lastEventIter->second.empty()) {
4674         return;
4675     }
4676     DragPointerEvent pointerEvent = lastEventIter->second.back();
4677     auto iter = eventManager_->GetLastDispatchTime().find(pointerEvent.pointerEventId);
4678     if (iter != eventManager_->GetLastDispatchTime().end()) {
4679         if (static_cast<uint64_t>(pointerEvent.time.time_since_epoch().count()) > iter->second) {
4680             manager->OnDragMove(pointerEvent, extraInfo, node);
4681         }
4682     }
4683 }
4684 
CompensatePointerMoveEventFromUnhandledEvents(const DragPointerEvent & event,const RefPtr<FrameNode> & node)4685 bool PipelineContext::CompensatePointerMoveEventFromUnhandledEvents(
4686     const DragPointerEvent& event, const RefPtr<FrameNode>& node)
4687 {
4688     auto manager = GetDragDropManager();
4689     std::string extraInfo = manager->GetExtraInfo();
4690     std::vector<DragPointerEvent> history;
4691     if (dragEvents_.empty()) {
4692         return false;
4693     }
4694 
4695     auto iter = dragEvents_.find(node);
4696     if (iter == dragEvents_.end()) {
4697         return false;
4698     }
4699     for (auto dragIter = iter->second.begin(); dragIter != iter->second.end();) {
4700         if (event.pointerEventId == dragIter->pointerEventId) {
4701             history.emplace_back(*dragIter);
4702             dragIter = iter->second.erase(dragIter);
4703         } else {
4704             dragIter++;
4705         }
4706     }
4707     dragEvents_.erase(iter);
4708 
4709     if (history.empty()) {
4710         return false;
4711     }
4712 
4713     auto lastePointerEvent(history.back());
4714     lastePointerEvent.history.swap(history);
4715     manager->OnDragMove(lastePointerEvent, extraInfo, node);
4716     return true;
4717 }
4718 
AddNodesToNotifyMemoryLevel(int32_t nodeId)4719 void PipelineContext::AddNodesToNotifyMemoryLevel(int32_t nodeId)
4720 {
4721     nodesToNotifyMemoryLevel_.emplace_back(nodeId);
4722 }
4723 
RemoveNodesToNotifyMemoryLevel(int32_t nodeId)4724 void PipelineContext::RemoveNodesToNotifyMemoryLevel(int32_t nodeId)
4725 {
4726     nodesToNotifyMemoryLevel_.remove(nodeId);
4727 }
4728 
NotifyMemoryLevel(int32_t level)4729 void PipelineContext::NotifyMemoryLevel(int32_t level)
4730 {
4731     auto iter = nodesToNotifyMemoryLevel_.begin();
4732     while (iter != nodesToNotifyMemoryLevel_.end()) {
4733         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
4734         if (!node) {
4735             iter = nodesToNotifyMemoryLevel_.erase(iter);
4736         } else {
4737             node->OnNotifyMemoryLevel(level);
4738             ++iter;
4739         }
4740     }
4741     if (window_) {
4742         window_->FlushTasks();
4743     }
4744 }
AddPredictTask(PredictTask && task)4745 void PipelineContext::AddPredictTask(PredictTask&& task)
4746 {
4747     taskScheduler_->AddPredictTask(std::move(task));
4748     RequestFrame();
4749 }
4750 
AddFrameCallback(FrameCallbackFunc && frameCallbackFunc,FrameCallbackFunc && idleCallbackFunc,int64_t delayMillis)4751 void PipelineContext::AddFrameCallback(FrameCallbackFunc&& frameCallbackFunc, FrameCallbackFunc&& idleCallbackFunc,
4752     int64_t delayMillis)
4753 {
4754     if (delayMillis <= 0) {
4755         if (frameCallbackFunc != nullptr) {
4756             frameCallbackFuncs_.emplace_back(std::move(frameCallbackFunc));
4757         }
4758         if (idleCallbackFunc != nullptr) {
4759             idleCallbackFuncs_.emplace_back(std::move(idleCallbackFunc));
4760         }
4761         RequestFrame();
4762         return;
4763     }
4764     auto taskScheduler = GetTaskExecutor();
4765     CHECK_NULL_VOID(taskScheduler);
4766     if (frameCallbackFunc != nullptr) {
4767         taskScheduler->PostDelayedTask(
4768             [weak = WeakClaim(this), callbackFunc = std::move(frameCallbackFunc)]() -> void {
4769                 auto pipeline = weak.Upgrade();
4770                 CHECK_NULL_VOID(pipeline);
4771                 auto callback = const_cast<FrameCallbackFunc&>(callbackFunc);
4772                 pipeline->frameCallbackFuncs_.emplace_back(std::move(callback));
4773                 pipeline->RequestFrame();
4774             },
4775             TaskExecutor::TaskType::UI, delayMillis, "ArkUIPostFrameCallbackFuncDelayed");
4776     }
4777     if (idleCallbackFunc != nullptr) {
4778         taskScheduler->PostDelayedTask(
4779             [weak = WeakClaim(this), callbackFunc = std::move(idleCallbackFunc)]() -> void {
4780                 auto pipeline = weak.Upgrade();
4781                 CHECK_NULL_VOID(pipeline);
4782                 auto callback = const_cast<FrameCallbackFunc&>(callbackFunc);
4783                 pipeline->idleCallbackFuncs_.emplace_back(std::move(callback));
4784                 pipeline->RequestFrame();
4785             },
4786             TaskExecutor::TaskType::UI, delayMillis, "ArkUIPostIdleCallbackFuncDelayed");
4787     }
4788 }
4789 
AddCAPIFrameCallback(FrameCallbackFuncFromCAPI && frameCallbackFuncFromCAPI)4790 void PipelineContext::AddCAPIFrameCallback(FrameCallbackFuncFromCAPI&& frameCallbackFuncFromCAPI)
4791 {
4792     if (frameCallbackFuncFromCAPI != nullptr) {
4793         frameCallbackFuncsFromCAPI_.emplace_back(std::move(frameCallbackFuncFromCAPI));
4794     }
4795 }
4796 
TriggerIdleCallback(int64_t deadline)4797 void PipelineContext::TriggerIdleCallback(int64_t deadline)
4798 {
4799     if (idleCallbackFuncs_.empty()) {
4800         return;
4801     }
4802     int64_t currentTime = GetSysTimestamp();
4803     if (deadline - currentTime < MIN_IDLE_TIME) {
4804         RequestFrame();
4805         return;
4806     }
4807     decltype(idleCallbackFuncs_) tasks(std::move(idleCallbackFuncs_));
4808     for (const auto& idleCallbackFunc : tasks) {
4809         idleCallbackFunc(deadline - currentTime);
4810         currentTime = GetSysTimestamp();
4811     }
4812 }
4813 
OnIdle(int64_t deadline)4814 void PipelineContext::OnIdle(int64_t deadline)
4815 {
4816     int64_t currentTime = GetSysTimestamp();
4817     if (deadline == 0) {
4818         int64_t lastTaskEndTimestamp = window_->GetLastVsyncEndTimestamp();
4819         if (eventManager_) {
4820             lastTaskEndTimestamp = std::max(lastTaskEndTimestamp, eventManager_->GetLastTouchEventEndTimestamp());
4821         }
4822         if (lastTaskEndTimestamp > 0 && currentTime > lastTaskEndTimestamp
4823             && currentTime - lastTaskEndTimestamp > VSYNC_PERIOD_COUNT * window_->GetVSyncPeriod()) {
4824             auto frontend = weakFrontend_.Upgrade();
4825             if (frontend) {
4826                 frontend->NotifyUIIdle();
4827             }
4828         }
4829     }
4830     if (deadline == 0 || isWindowAnimation_) {
4831         canUseLongPredictTask_ = false;
4832         return;
4833     }
4834     if (canUseLongPredictTask_) {
4835         // check new incoming event after vsync.
4836         if (!touchEvents_.empty()) {
4837             canUseLongPredictTask_ = false;
4838         }
4839     }
4840     CHECK_RUN_ON(UI);
4841     ACE_SCOPED_TRACE_COMMERCIAL("OnIdle, targettime:%" PRId64 "", deadline);
4842     taskScheduler_->FlushPredictTask(deadline - TIME_THRESHOLD, canUseLongPredictTask_);
4843     canUseLongPredictTask_ = false;
4844     if (currentTime < deadline) {
4845         ElementRegister::GetInstance()->CallJSCleanUpIdleTaskFunc();
4846     }
4847     TriggerIdleCallback(deadline);
4848 }
4849 
Finish(bool) const4850 void PipelineContext::Finish(bool /* autoFinish */) const
4851 {
4852     CHECK_RUN_ON(UI);
4853     if (finishEventHandler_) {
4854         finishEventHandler_();
4855     }
4856 }
4857 
AddAfterLayoutTask(std::function<void ()> && task,bool isFlushInImplicitAnimationTask)4858 void PipelineContext::AddAfterLayoutTask(std::function<void()>&& task, bool isFlushInImplicitAnimationTask)
4859 {
4860     taskScheduler_->AddAfterLayoutTask(std::move(task), isFlushInImplicitAnimationTask);
4861 }
4862 
AddPersistAfterLayoutTask(std::function<void ()> && task)4863 void PipelineContext::AddPersistAfterLayoutTask(std::function<void()>&& task)
4864 {
4865     taskScheduler_->AddPersistAfterLayoutTask(std::move(task));
4866 }
4867 
AddAfterRenderTask(std::function<void ()> && task)4868 void PipelineContext::AddAfterRenderTask(std::function<void()>&& task)
4869 {
4870     taskScheduler_->AddAfterRenderTask(std::move(task));
4871 }
4872 
AddSafeAreaPaddingProcessTask(FrameNode * node)4873 void PipelineContext::AddSafeAreaPaddingProcessTask(FrameNode* node)
4874 {
4875     taskScheduler_->AddSafeAreaPaddingProcessTask(node);
4876 }
4877 
RemoveSafeAreaPaddingProcessTask(FrameNode * node)4878 void PipelineContext::RemoveSafeAreaPaddingProcessTask(FrameNode* node)
4879 {
4880     taskScheduler_->RemoveSafeAreaPaddingProcessTask(node);
4881 }
4882 
FlushSafeAreaPaddingProcess()4883 void PipelineContext::FlushSafeAreaPaddingProcess()
4884 {
4885     taskScheduler_->FlushSafeAreaPaddingProcess();
4886 }
4887 
RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)4888 void PipelineContext::RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)
4889 {
4890     auto child = nodeInfo->GetChild();
4891     while (child->IsValid()) {
4892         auto key = child->GetKey();
4893         auto value = child->GetString();
4894         restoreNodeInfo_.try_emplace(StringUtils::StringToInt(key), value);
4895         child = child->GetNext();
4896     }
4897 }
4898 
GetStoredNodeInfo()4899 std::unique_ptr<JsonValue> PipelineContext::GetStoredNodeInfo()
4900 {
4901     auto jsonNodeInfo = JsonUtil::Create(true);
4902     auto iter = storeNode_.begin();
4903     while (iter != storeNode_.end()) {
4904         auto node = (iter->second).Upgrade();
4905         if (node) {
4906             std::string info = node->ProvideRestoreInfo();
4907             if (!info.empty()) {
4908                 jsonNodeInfo->Put(std::to_string(iter->first).c_str(), info.c_str());
4909             }
4910         }
4911         ++iter;
4912     }
4913     return jsonNodeInfo;
4914 }
4915 
StoreNode(int32_t restoreId,const WeakPtr<FrameNode> & node)4916 void PipelineContext::StoreNode(int32_t restoreId, const WeakPtr<FrameNode>& node)
4917 {
4918     auto ret = storeNode_.try_emplace(restoreId, node);
4919     if (!ret.second) {
4920         storeNode_[restoreId] = node;
4921     }
4922 }
4923 
GetRestoreInfo(int32_t restoreId,std::string & restoreInfo)4924 bool PipelineContext::GetRestoreInfo(int32_t restoreId, std::string& restoreInfo)
4925 {
4926     auto iter = restoreNodeInfo_.find(restoreId);
4927     if (iter != restoreNodeInfo_.end()) {
4928         restoreInfo = iter->second;
4929         restoreNodeInfo_.erase(iter);
4930         return true;
4931     }
4932     return false;
4933 }
4934 
SetContainerButtonHide(bool hideSplit,bool hideMaximize,bool hideMinimize,bool hideClose)4935 void PipelineContext::SetContainerButtonHide(bool hideSplit, bool hideMaximize, bool hideMinimize, bool hideClose)
4936 {
4937     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
4938         LOGW("Set app icon failed, Window modal is not container.");
4939         return;
4940     }
4941     CHECK_NULL_VOID(rootNode_);
4942     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4943     CHECK_NULL_VOID(containerNode);
4944     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4945     CHECK_NULL_VOID(containerPattern);
4946     containerPattern->SetContainerButtonHide(hideSplit, hideMaximize, hideMinimize, hideClose);
4947 }
4948 
EnableContainerModalGesture(bool isEnable)4949 void PipelineContext::EnableContainerModalGesture(bool isEnable)
4950 {
4951     CHECK_NULL_VOID(rootNode_);
4952     const auto &children = rootNode_->GetChildren();
4953     if (children.empty()) {
4954         LOGW("rootNode children list is empty.");
4955         return;
4956     }
4957     auto containerNode = AceType::DynamicCast<FrameNode>(children.front());
4958     if (!containerNode) {
4959         LOGW("container node is null when set event on gesture row");
4960         return;
4961     }
4962     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4963     CHECK_NULL_VOID(containerPattern);
4964     containerPattern->EnableContainerModalGesture(isEnable);
4965 }
4966 
GetContainerFloatingTitleVisible()4967 bool PipelineContext::GetContainerFloatingTitleVisible()
4968 {
4969     CHECK_NULL_RETURN(rootNode_, false);
4970     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4971     CHECK_NULL_RETURN(containerNode, false);
4972     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4973     CHECK_NULL_RETURN(containerPattern, false);
4974     return containerPattern->GetFloatingTitleVisible();
4975 }
4976 
GetContainerCustomTitleVisible()4977 bool PipelineContext::GetContainerCustomTitleVisible()
4978 {
4979     CHECK_NULL_RETURN(rootNode_, false);
4980     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4981     CHECK_NULL_RETURN(containerNode, false);
4982     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4983     CHECK_NULL_RETURN(containerPattern, false);
4984     return containerPattern->GetCustomTitleVisible();
4985 }
4986 
GetContainerControlButtonVisible()4987 bool PipelineContext::GetContainerControlButtonVisible()
4988 {
4989     CHECK_NULL_RETURN(rootNode_, false);
4990     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
4991     CHECK_NULL_RETURN(containerNode, false);
4992     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
4993     CHECK_NULL_RETURN(containerPattern, false);
4994     return containerPattern->GetControlButtonVisible();
4995 }
4996 
SetWindowContainerColor(const Color & activeColor,const Color & inactiveColor)4997 void PipelineContext::SetWindowContainerColor(const Color& activeColor, const Color& inactiveColor)
4998 {
4999     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5000         LOGW("Set app icon failed, Window modal is not container.");
5001         return;
5002     }
5003     CHECK_NULL_VOID(rootNode_);
5004     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
5005     CHECK_NULL_VOID(containerNode);
5006     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5007     CHECK_NULL_VOID(containerPattern);
5008     containerPattern->SetWindowContainerColor(activeColor, inactiveColor);
5009 }
5010 
AddFontNodeNG(const WeakPtr<UINode> & node)5011 void PipelineContext::AddFontNodeNG(const WeakPtr<UINode>& node)
5012 {
5013     if (fontManager_) {
5014         fontManager_->AddFontNodeNG(node);
5015     }
5016 }
5017 
RemoveFontNodeNG(const WeakPtr<UINode> & node)5018 void PipelineContext::RemoveFontNodeNG(const WeakPtr<UINode>& node)
5019 {
5020     if (fontManager_) {
5021         fontManager_->RemoveFontNodeNG(node);
5022     }
5023 }
5024 
SetWindowSceneConsumed(bool isConsumed)5025 void PipelineContext::SetWindowSceneConsumed(bool isConsumed)
5026 {
5027     isWindowSceneConsumed_ = isConsumed;
5028 }
5029 
IsWindowSceneConsumed()5030 bool PipelineContext::IsWindowSceneConsumed()
5031 {
5032     return isWindowSceneConsumed_;
5033 }
5034 
SetCloseButtonStatus(bool isEnabled)5035 void PipelineContext::SetCloseButtonStatus(bool isEnabled)
5036 {
5037     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5038         return;
5039     }
5040     CHECK_NULL_VOID(rootNode_);
5041     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
5042     CHECK_NULL_VOID(containerNode);
5043     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5044     CHECK_NULL_VOID(containerPattern);
5045     containerPattern->SetCloseButtonStatus(isEnabled);
5046 }
5047 
AnimateOnSafeAreaUpdate()5048 void PipelineContext::AnimateOnSafeAreaUpdate()
5049 {
5050     // complete other layout tasks before animation
5051     FlushUITasks();
5052     AnimationOption option;
5053     option.SetCurve(safeAreaManager_->GetSafeAreaCurve());
5054     AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
5055         auto self = weak.Upgrade();
5056         CHECK_NULL_VOID(self);
5057         self->SyncSafeArea(SafeAreaSyncType::SYNC_TYPE_AVOID_AREA);
5058         self->FlushUITasks();
5059     });
5060 }
5061 
HandleSubwindow(bool isShow)5062 void PipelineContext::HandleSubwindow(bool isShow)
5063 {
5064     // When the main window is applied to the background,
5065     // there are sub windows that do not immediately hide, such as Toast floating window
5066     if (!isShow) {
5067         overlayManager_->ClearToastInSubwindow();
5068     }
5069 }
5070 
AddIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node,const std::function<void (bool)> & eventCallback)5071 void PipelineContext::AddIsFocusActiveUpdateEvent(
5072     const RefPtr<FrameNode>& node, const std::function<void(bool)>& eventCallback)
5073 {
5074     CHECK_NULL_VOID(node);
5075     isFocusActiveUpdateEvents_.insert_or_assign(node->GetId(), eventCallback);
5076 }
5077 
RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node)5078 void PipelineContext::RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode>& node)
5079 {
5080     CHECK_NULL_VOID(node);
5081     auto iter = isFocusActiveUpdateEvents_.find(node->GetId());
5082     if (iter != isFocusActiveUpdateEvents_.end()) {
5083         isFocusActiveUpdateEvents_.erase(iter);
5084     }
5085 }
5086 
GetNavigationController(const std::string & id)5087 std::shared_ptr<NavigationController> PipelineContext::GetNavigationController(const std::string& id)
5088 {
5089     std::lock_guard lock(navigationMutex_);
5090     auto iter = navigationNodes_.find(id);
5091     if (iter == navigationNodes_.end()) {
5092         return nullptr;
5093     }
5094 
5095     auto navigationGroupNode = iter->second.Upgrade();
5096     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
5097 
5098     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
5099     CHECK_NULL_RETURN(navigationPattern, nullptr);
5100     return navigationPattern->GetNavigationController();
5101 }
5102 
AddOrReplaceNavigationNode(const std::string & id,const WeakPtr<FrameNode> & node)5103 void PipelineContext::AddOrReplaceNavigationNode(const std::string& id, const WeakPtr<FrameNode>& node)
5104 {
5105     std::lock_guard lock(navigationMutex_);
5106     auto frameNode = node.Upgrade();
5107     CHECK_NULL_VOID(frameNode);
5108     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
5109     CHECK_NULL_VOID(navigationGroupNode);
5110     auto oldId = navigationGroupNode->GetCurId();
5111     if (!oldId.empty() && navigationNodes_.find(oldId) != navigationNodes_.end()) {
5112         navigationNodes_.erase(oldId);
5113     }
5114 
5115     if (!id.empty()) {
5116         navigationNodes_[id] = node;
5117     }
5118 }
5119 
DeleteNavigationNode(const std::string & id)5120 void PipelineContext::DeleteNavigationNode(const std::string& id)
5121 {
5122     std::lock_guard lock(navigationMutex_);
5123     if (!id.empty() && navigationNodes_.find(id) != navigationNodes_.end()) {
5124         navigationNodes_.erase(id);
5125     }
5126 }
5127 
GetCurrentExtraInfo()5128 std::string PipelineContext::GetCurrentExtraInfo()
5129 {
5130     auto node = activeNode_.Upgrade();
5131     return node ? node->GetCurrentCustomNodeInfo() : std::string();
5132 }
5133 
SetCursor(int32_t cursorValue)5134 void PipelineContext::SetCursor(int32_t cursorValue)
5135 {
5136     if (cursorValue >= 0 && cursorValue <= static_cast<int32_t>(MouseFormat::RUNNING)) {
5137         auto mouseFormat = static_cast<MouseFormat>(cursorValue);
5138         auto mouseStyleManager = eventManager_->GetMouseStyleManager();
5139         CHECK_NULL_VOID(mouseStyleManager);
5140         mouseStyleManager->SetUserSetCursor(true);
5141         ChangeMouseStyle(-1, mouseFormat, GetFocusWindowId(),
5142             false, MouseStyleChangeReason::USER_SET_MOUSESTYLE);
5143     }
5144 }
5145 
RestoreDefault(int32_t windowId)5146 void PipelineContext::RestoreDefault(int32_t windowId)
5147 {
5148     ChangeMouseStyle(-1, MouseFormat::DEFAULT, windowId > 0 ? windowId : GetFocusWindowId(),
5149         false, MouseStyleChangeReason::USER_SET_MOUSESTYLE);
5150     auto mouseStyleManager = eventManager_->GetMouseStyleManager();
5151     CHECK_NULL_VOID(mouseStyleManager);
5152     mouseStyleManager->SetUserSetCursor(false);
5153 }
5154 
FlushAnimationDirtysWhenExist(const AnimationOption & option)5155 void PipelineContext::FlushAnimationDirtysWhenExist(const AnimationOption& option)
5156 {
5157     int32_t flushCount = 0;
5158     bool isDirtyLayoutNodesEmpty = IsDirtyLayoutNodesEmpty();
5159     while (!isDirtyLayoutNodesEmpty && !IsLayouting() && !isReloading_) {
5160         if (flushCount >= MAX_FLUSH_COUNT || option.GetIteration() != ANIMATION_REPEAT_INFINITE) {
5161             TAG_LOGW(AceLogTag::ACE_ANIMATION, "animation: option:%{public}s, isDirtyLayoutNodesEmpty:%{public}d",
5162                 option.ToString().c_str(), isDirtyLayoutNodesEmpty);
5163             break;
5164         }
5165         FlushUITasks(true);
5166         isDirtyLayoutNodesEmpty = IsDirtyLayoutNodesEmpty();
5167         flushCount++;
5168     }
5169 }
5170 
OpenFrontendAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)5171 void PipelineContext::OpenFrontendAnimation(
5172     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
5173 {
5174     // push false to show we already open a animation closure.
5175     pendingFrontendAnimation_.push(false);
5176 
5177     // flush ui tasks before open animation closure.
5178     if (!isReloading_ && !IsLayouting()) {
5179         FlushUITasks();
5180     }
5181     auto wrapFinishCallback = GetWrappedAnimationCallback(option, finishCallback);
5182     if (IsFormRenderExceptDynamicComponent()) {
5183         SetIsFormAnimation(true);
5184         if (!IsFormAnimationFinishCallback()) {
5185             SetFormAnimationStartTime(GetMicroTickCount());
5186         }
5187     }
5188     FlushAnimationDirtysWhenExist(option);
5189     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
5190 }
5191 
CloseFrontendAnimation()5192 void PipelineContext::CloseFrontendAnimation()
5193 {
5194     if (pendingFrontendAnimation_.empty()) {
5195         return;
5196     }
5197 
5198     if (pendingFrontendAnimation_.top()) {
5199         if (!isReloading_ && !IsLayouting()) {
5200             FlushUITasks();
5201         } else if (IsLayouting()) {
5202             TAG_LOGW(AceLogTag::ACE_ANIMATION,
5203                 "IsLayouting, CloseFrontendAnimation has tasks not flushed, maybe some layout animation not generated");
5204         }
5205     }
5206     if (!pendingFrontendAnimation_.empty()) {
5207         pendingFrontendAnimation_.pop();
5208     }
5209     AnimationUtils::CloseImplicitAnimation();
5210 }
5211 
IsDragging() const5212 bool PipelineContext::IsDragging() const
5213 {
5214     if (!dragDropManager_) {
5215         return false;
5216     }
5217     bool isDragging = dragDropManager_->IsDragging();
5218     isDragging = (isDragging || dragDropManager_->IsMSDPDragging());
5219     return isDragging;
5220 }
5221 
SetIsDragging(bool isDragging)5222 void PipelineContext::SetIsDragging(bool isDragging)
5223 {
5224     if (!eventManager_) {
5225         return;
5226     }
5227     eventManager_->SetIsDragging(isDragging);
5228 }
5229 
ResetDragging()5230 void PipelineContext::ResetDragging()
5231 {
5232     CHECK_NULL_VOID(dragDropManager_);
5233     dragDropManager_->ResetDragging();
5234 }
5235 
SetContainerModalTitleVisible(bool customTitleSettedShow,bool floatingTitleSettedShow)5236 void PipelineContext::SetContainerModalTitleVisible(bool customTitleSettedShow, bool floatingTitleSettedShow)
5237 {
5238     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5239         return;
5240     }
5241     CHECK_NULL_VOID(rootNode_);
5242     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5243     CHECK_NULL_VOID(containerNode);
5244     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5245     CHECK_NULL_VOID(containerPattern);
5246     containerPattern->SetContainerModalTitleVisible(customTitleSettedShow, floatingTitleSettedShow);
5247     customTitleSettedShow_ = customTitleSettedShow;
5248 }
5249 
SetContainerModalTitleHeight(int32_t height)5250 void PipelineContext::SetContainerModalTitleHeight(int32_t height)
5251 {
5252     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5253         return;
5254     }
5255     CHECK_NULL_VOID(rootNode_);
5256     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5257     CHECK_NULL_VOID(containerNode);
5258     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5259     CHECK_NULL_VOID(containerPattern);
5260     containerPattern->SetContainerModalTitleHeight(height);
5261 }
5262 
GetContainerModalTitleHeight()5263 int32_t PipelineContext::GetContainerModalTitleHeight()
5264 {
5265     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5266         return -1;
5267     }
5268     CHECK_NULL_RETURN(rootNode_, -1);
5269     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5270     CHECK_NULL_RETURN(containerNode, -1);
5271     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5272     CHECK_NULL_RETURN(containerPattern, -1);
5273     return containerPattern->GetContainerModalTitleHeight();
5274 }
5275 
GetContainerModalNode()5276 RefPtr<FrameNode> PipelineContext::GetContainerModalNode()
5277 {
5278     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5279         return nullptr;
5280     }
5281     CHECK_NULL_RETURN(rootNode_, nullptr);
5282     return AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5283 }
5284 
DoKeyboardAvoidAnimate(const KeyboardAnimationConfig & keyboardAnimationConfig,float keyboardHeight,const std::function<void ()> & func)5285 void PipelineContext::DoKeyboardAvoidAnimate(const KeyboardAnimationConfig& keyboardAnimationConfig,
5286     float keyboardHeight, const std::function<void()>& func)
5287 {
5288     if (isDoKeyboardAvoidAnimate_) {
5289         AnimationOption option = AnimationUtil::CreateKeyboardAnimationOption(keyboardAnimationConfig, keyboardHeight);
5290         Animate(option, option.GetCurve(), func, [weak = WeakClaim(this)]() {
5291             auto pipeline = weak.Upgrade();
5292             CHECK_NULL_VOID(pipeline);
5293             CHECK_NULL_VOID(pipeline->textFieldManager_);
5294             auto textFieldManagerNg = DynamicCast<TextFieldManagerNG>(pipeline->textFieldManager_);
5295             CHECK_NULL_VOID(textFieldManagerNg);
5296             textFieldManagerNg->OnAfterAvoidKeyboard(false);
5297         });
5298     } else {
5299         func();
5300     }
5301 }
5302 
GetCustomTitleHeight()5303 Dimension PipelineContext::GetCustomTitleHeight()
5304 {
5305     auto containerModal = GetContainerModalNode();
5306     CHECK_NULL_RETURN(containerModal, Dimension());
5307     return containerModal->GetPattern<ContainerModalPattern>()->GetCustomTitleHeight();
5308 }
5309 
GetContainerModalButtonsRect(RectF & containerModal,RectF & buttons)5310 bool PipelineContext::GetContainerModalButtonsRect(RectF& containerModal, RectF& buttons)
5311 {
5312     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5313         return false;
5314     }
5315     CHECK_NULL_RETURN(rootNode_, false);
5316     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5317     CHECK_NULL_RETURN(containerNode, false);
5318     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5319     CHECK_NULL_RETURN(containerPattern, false);
5320     return containerPattern->GetContainerModalButtonsRect(containerModal, buttons);
5321 }
5322 
SubscribeContainerModalButtonsRectChange(std::function<void (RectF & containerModal,RectF & buttons)> && callback)5323 void PipelineContext::SubscribeContainerModalButtonsRectChange(
5324     std::function<void(RectF& containerModal, RectF& buttons)>&& callback)
5325 {
5326     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5327         return;
5328     }
5329     CHECK_NULL_VOID(rootNode_);
5330     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5331     CHECK_NULL_VOID(containerNode);
5332     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5333     CHECK_NULL_VOID(containerPattern);
5334     containerPattern->SubscribeContainerModalButtonsRectChange(std::move(callback));
5335 }
5336 
GetWindowPaintRectWithoutMeasureAndLayout(RectInt & rect)5337 void PipelineContext::GetWindowPaintRectWithoutMeasureAndLayout(RectInt& rect)
5338 {
5339     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5340         return;
5341     }
5342     CHECK_NULL_VOID(rootNode_);
5343     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
5344     CHECK_NULL_VOID(containerNode);
5345     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
5346     CHECK_NULL_VOID(containerPattern);
5347     containerPattern->GetWindowPaintRectWithoutMeasureAndLayout(rect);
5348 }
5349 
GetPostEventManager()5350 const RefPtr<PostEventManager>& PipelineContext::GetPostEventManager()
5351 {
5352     return postEventManager_;
5353 }
5354 
GetSerializedGesture() const5355 const SerializedGesture& PipelineContext::GetSerializedGesture() const
5356 {
5357     return serializedGesture_;
5358 }
5359 
PrintVsyncInfoIfNeed() const5360 bool PipelineContext::PrintVsyncInfoIfNeed() const
5361 {
5362     if (dumpFrameInfos_.empty()) {
5363         return false;
5364     }
5365     auto lastFrameInfo = dumpFrameInfos_.back();
5366     const uint64_t timeout = 1000000000; // unit is ns, 1s
5367     if (lastFrameInfo.frameRecvTime_ < window_->GetLastRequestVsyncTime() &&
5368         static_cast<uint64_t>(GetSysTimestamp()) - window_->GetLastRequestVsyncTime() >= timeout) {
5369         LOGW("lastRequestVsyncTime is %{public}" PRIu64 ", now time is %{public}" PRId64
5370              ", timeout, window foreground:%{public}d, lastReceiveVsync info:%{public}s",
5371             window_->GetLastRequestVsyncTime(), GetSysTimestamp(), onShow_, lastFrameInfo.GetTimeInfo().c_str());
5372         return true;
5373     }
5374     return false;
5375 }
5376 
StopWindowAnimation()5377 void PipelineContext::StopWindowAnimation()
5378 {
5379     isWindowAnimation_ = false;
5380     if (taskScheduler_ && !taskScheduler_->IsPredictTaskEmpty()) {
5381         RequestFrame();
5382     }
5383 }
5384 
AddSyncGeometryNodeTask(std::function<void ()> && task)5385 void PipelineContext::AddSyncGeometryNodeTask(std::function<void()>&& task)
5386 {
5387     taskScheduler_->AddSyncGeometryNodeTask(std::move(task));
5388 }
5389 
FlushSyncGeometryNodeTasks()5390 void PipelineContext::FlushSyncGeometryNodeTasks()
5391 {
5392     taskScheduler_->FlushSyncGeometryNodeTasks();
5393 }
5394 
SetUIExtensionImeShow(bool imeShow)5395 void PipelineContext::SetUIExtensionImeShow(bool imeShow)
5396 {
5397     textFieldManager_->SetUIExtensionImeShow(imeShow);
5398 }
5399 
SetOverlayNodePositions(std::vector<Ace::RectF> rects)5400 void PipelineContext::SetOverlayNodePositions(std::vector<Ace::RectF> rects)
5401 {
5402     overlayNodePositions_ = rects;
5403 }
5404 
SetCallBackNode(const WeakPtr<NG::FrameNode> & node)5405 void PipelineContext::SetCallBackNode(const WeakPtr<NG::FrameNode>& node)
5406 {
5407     auto frameNode = node.Upgrade();
5408     CHECK_NULL_VOID(frameNode);
5409     auto pipelineContext = frameNode->GetContext();
5410     CHECK_NULL_VOID(pipelineContext);
5411     pipelineContext->UpdateCurrentActiveNode(node);
5412 }
5413 
GetOverlayNodePositions()5414 std::vector<Ace::RectF> PipelineContext::GetOverlayNodePositions()
5415 {
5416     return overlayNodePositions_;
5417 }
5418 
RegisterOverlayNodePositionsUpdateCallback(const std::function<void (std::vector<Ace::RectF>)> && callback)5419 void PipelineContext::RegisterOverlayNodePositionsUpdateCallback(
5420     const std::function<void(std::vector<Ace::RectF>)>&& callback)
5421 {
5422     overlayNodePositionUpdateCallback_ = std::move(callback);
5423 }
5424 
TriggerOverlayNodePositionsUpdateCallback(std::vector<Ace::RectF> rects)5425 void PipelineContext::TriggerOverlayNodePositionsUpdateCallback(std::vector<Ace::RectF> rects)
5426 {
5427     if (overlayNodePositionUpdateCallback_) {
5428         overlayNodePositionUpdateCallback_(rects);
5429     }
5430 }
5431 
CheckNeedUpdateBackgroundColor(Color & color)5432 void PipelineContext::CheckNeedUpdateBackgroundColor(Color& color)
5433 {
5434     if (!isFormRender_ || (renderingMode_ != RENDERING_SINGLE_COLOR)) {
5435         return;
5436     }
5437     Color replaceColor = color.ChangeAlpha(SINGLECOLOR_UPDATE_ALPHA);
5438     color = replaceColor;
5439 }
5440 
CheckNeedDisableUpdateBackgroundImage()5441 bool PipelineContext::CheckNeedDisableUpdateBackgroundImage()
5442 {
5443     if (!isFormRender_ || (renderingMode_ != RENDERING_SINGLE_COLOR && !enableBlurBackground_)) {
5444         return false;
5445     }
5446     return true;
5447 }
5448 
GetColorMode() const5449 ColorMode PipelineContext::GetColorMode() const
5450 {
5451     auto container = Container::GetContainer(instanceId_);
5452     CHECK_NULL_RETURN(container, ColorMode::LIGHT);
5453     return container->GetColorMode();
5454 }
5455 
ChangeDarkModeBrightness()5456 void PipelineContext::ChangeDarkModeBrightness()
5457 {
5458     auto windowManager = GetWindowManager();
5459     CHECK_NULL_VOID(windowManager);
5460     auto mode = windowManager->GetWindowMode();
5461     auto container = Container::CurrentSafely();
5462     CHECK_NULL_VOID(container);
5463     auto percent = SystemProperties::GetDarkModeBrightnessPercent();
5464     auto stage = stageManager_->GetStageNode();
5465     CHECK_NULL_VOID(stage);
5466     auto renderContext = stage->GetRenderContext();
5467     CHECK_NULL_VOID(renderContext);
5468     CalcDimension dimension;
5469     dimension.SetValue(1);
5470     if (container->GetColorMode() == ColorMode::DARK && appBgColor_.ColorToString().compare("#FF000000") == 0 &&
5471         mode != WindowMode::WINDOW_MODE_FULLSCREEN && !container->IsUIExtensionWindow() &&
5472         !container->IsDynamicRender() && !container->IsFormRender() && !IsJsCard()) {
5473         if (!onFocus_ && mode == WindowMode::WINDOW_MODE_FLOATING) {
5474             dimension.SetValue(1 + percent.second);
5475         } else {
5476             dimension.SetValue(1 + percent.first);
5477         }
5478     }
5479     renderContext->UpdateFrontBrightness(dimension);
5480 }
5481 
IsContainerModalVisible()5482 bool PipelineContext::IsContainerModalVisible()
5483 {
5484     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
5485         return false;
5486     }
5487     auto windowManager = GetWindowManager();
5488     bool isFloatingWindow = windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
5489     return isShowTitle_ && isFloatingWindow && customTitleSettedShow_;
5490 }
5491 
PreLayout(uint64_t nanoTimestamp,uint32_t frameCount)5492 void PipelineContext::PreLayout(uint64_t nanoTimestamp, uint32_t frameCount)
5493 {
5494     FlushVsync(nanoTimestamp, frameCount);
5495 }
5496 
CheckAndLogLastReceivedTouchEventInfo(int32_t eventId,TouchType type)5497 void PipelineContext::CheckAndLogLastReceivedTouchEventInfo(int32_t eventId, TouchType type)
5498 {
5499     eventManager_->CheckAndLogLastReceivedTouchEventInfo(eventId, type);
5500 }
5501 
CheckAndLogLastConsumedTouchEventInfo(int32_t eventId,TouchType type)5502 void PipelineContext::CheckAndLogLastConsumedTouchEventInfo(int32_t eventId, TouchType type)
5503 {
5504     eventManager_->CheckAndLogLastConsumedTouchEventInfo(eventId, type);
5505 }
5506 
CheckAndLogLastReceivedMouseEventInfo(int32_t eventId,MouseAction action)5507 void PipelineContext::CheckAndLogLastReceivedMouseEventInfo(int32_t eventId, MouseAction action)
5508 {
5509     eventManager_->CheckAndLogLastReceivedMouseEventInfo(eventId, action);
5510 }
5511 
CheckAndLogLastConsumedMouseEventInfo(int32_t eventId,MouseAction action)5512 void PipelineContext::CheckAndLogLastConsumedMouseEventInfo(int32_t eventId, MouseAction action)
5513 {
5514     eventManager_->CheckAndLogLastConsumedMouseEventInfo(eventId, action);
5515 }
5516 
CheckAndLogLastReceivedAxisEventInfo(int32_t eventId,AxisAction action)5517 void PipelineContext::CheckAndLogLastReceivedAxisEventInfo(int32_t eventId, AxisAction action)
5518 {
5519     eventManager_->CheckAndLogLastReceivedAxisEventInfo(eventId, action);
5520 }
5521 
CheckAndLogLastConsumedAxisEventInfo(int32_t eventId,AxisAction action)5522 void PipelineContext::CheckAndLogLastConsumedAxisEventInfo(int32_t eventId, AxisAction action)
5523 {
5524     eventManager_->CheckAndLogLastConsumedAxisEventInfo(eventId, action);
5525 }
5526 
FlushFrameCallback(uint64_t nanoTimestamp)5527 void PipelineContext::FlushFrameCallback(uint64_t nanoTimestamp)
5528 {
5529     if (!frameCallbackFuncs_.empty()) {
5530         decltype(frameCallbackFuncs_) tasks(std::move(frameCallbackFuncs_));
5531         for (const auto& frameCallbackFunc : tasks) {
5532             frameCallbackFunc(nanoTimestamp);
5533         }
5534     }
5535 }
5536 
FlushFrameCallbackFromCAPI(uint64_t nanoTimestamp,uint32_t frameCount)5537 void PipelineContext::FlushFrameCallbackFromCAPI(uint64_t nanoTimestamp, uint32_t frameCount)
5538 {
5539     if (!frameCallbackFuncsFromCAPI_.empty()) {
5540         decltype(frameCallbackFuncsFromCAPI_) tasks;
5541         std::swap(tasks, frameCallbackFuncsFromCAPI_);
5542         for (const auto& frameCallbackFuncFromCAPI : tasks) {
5543             frameCallbackFuncFromCAPI(nanoTimestamp, frameCount);
5544         }
5545     }
5546 }
5547 
RegisterTouchEventListener(const std::shared_ptr<ITouchEventCallback> & listener)5548 void PipelineContext::RegisterTouchEventListener(const std::shared_ptr<ITouchEventCallback>& listener)
5549 {
5550     if (!listener) {
5551         return;
5552     }
5553     listenerVector_.emplace_back(listener);
5554 }
5555 
UnregisterTouchEventListener(const WeakPtr<NG::Pattern> & pattern)5556 void PipelineContext::UnregisterTouchEventListener(const WeakPtr<NG::Pattern>& pattern)
5557 {
5558     for (auto iter = listenerVector_.begin(); iter != listenerVector_.end();) {
5559         auto patternPtr = (*iter)->GetPatternFromListener();
5560         if (patternPtr.Invalid() || patternPtr == pattern) {
5561             iter = listenerVector_.erase(iter);
5562         } else {
5563             iter++;
5564         }
5565     }
5566 }
5567 
RegisterFocusCallback()5568 void PipelineContext::RegisterFocusCallback()
5569 {
5570     focusManager_->AddFocusListener([](const WeakPtr<FocusHub>& last, const RefPtr<FocusHub>& current,
5571         FocusReason focusReason) {
5572         CHECK_NULL_VOID(current);
5573         auto node = current->GetFrameNode();
5574         CHECK_NULL_VOID(node);
5575         InputMethodManager::GetInstance()->OnFocusNodeChange(node, focusReason);
5576     });
5577 }
5578 
GetInspectorTree(bool onlyNeedVisible)5579 void PipelineContext::GetInspectorTree(bool onlyNeedVisible)
5580 {
5581     if (onlyNeedVisible) {
5582         auto root = JsonUtil::Create(true);
5583         RefPtr<NG::FrameNode> topNavNode;
5584         uiTranslateManager_->FindTopNavDestination(rootNode_, topNavNode);
5585         if (topNavNode != nullptr) {
5586             topNavNode->DumpSimplifyTree(0, root);
5587         } else {
5588             rootNode_->DumpSimplifyTree(0, root);
5589         }
5590         auto json = root->ToString();
5591         json.erase(std::remove(json.begin(), json.end(), ' '), json.end());
5592         auto res = JsonUtil::Create(true);
5593         res->Put("0", json.c_str());
5594         UiSessionManager::GetInstance()->ReportInspectorTreeValue(res->ToString());
5595     } else {
5596         bool needThrow = false;
5597         NG::InspectorFilter filter;
5598         filter.AddFilterAttr("content");
5599         auto nodeInfos = NG::Inspector::GetInspector(false, filter, needThrow);
5600         UiSessionManager::GetInstance()->AddValueForTree(0, nodeInfos);
5601         rootNode_->GetInspectorValue();
5602     }
5603 }
5604 
AddFrameNodeChangeListener(const WeakPtr<FrameNode> & node)5605 void PipelineContext::AddFrameNodeChangeListener(const WeakPtr<FrameNode>& node)
5606 {
5607     CHECK_NULL_VOID(node.Upgrade());
5608     if (std::find(changeInfoListeners_.begin(), changeInfoListeners_.end(), node) == changeInfoListeners_.end()) {
5609         changeInfoListeners_.push_back(node);
5610     }
5611 }
5612 
RemoveFrameNodeChangeListener(int32_t nodeId)5613 void PipelineContext::RemoveFrameNodeChangeListener(int32_t nodeId)
5614 {
5615     if (changeInfoListeners_.empty()) {
5616         return;
5617     }
5618     changeInfoListeners_.remove_if([nodeId](const WeakPtr<FrameNode>& node) {
5619         return !node.Upgrade() || nodeId == node.Upgrade()->GetId();
5620     });
5621 }
5622 
AddChangedFrameNode(const WeakPtr<FrameNode> & node)5623 bool PipelineContext::AddChangedFrameNode(const WeakPtr<FrameNode>& node)
5624 {
5625     CHECK_NULL_RETURN(node.Upgrade(), false);
5626     if (changeInfoListeners_.empty()) {
5627         return false;
5628     }
5629     if (std::find(changedNodes_.begin(), changedNodes_.end(), node) == changedNodes_.end()) {
5630         changedNodes_.push_back(node);
5631     }
5632     return true;
5633 }
5634 
RemoveChangedFrameNode(int32_t nodeId)5635 void PipelineContext::RemoveChangedFrameNode(int32_t nodeId)
5636 {
5637     if (changedNodes_.empty()) {
5638         return;
5639     }
5640     changedNodes_.remove_if([nodeId](const WeakPtr<FrameNode>& node) {
5641         return !node.Upgrade() || nodeId == node.Upgrade()->GetId();
5642     });
5643 }
5644 
FlushNodeChangeFlag()5645 void PipelineContext::FlushNodeChangeFlag()
5646 {
5647     ACE_FUNCTION_TRACE();
5648     if (!changeInfoListeners_.empty()) {
5649         for (const auto& it : changeInfoListeners_) {
5650             auto listener = it.Upgrade();
5651             if (listener) {
5652                 listener->ProcessFrameNodeChangeFlag();
5653             }
5654         }
5655     }
5656     CleanNodeChangeFlag();
5657 }
5658 
CleanNodeChangeFlag()5659 void PipelineContext::CleanNodeChangeFlag()
5660 {
5661     auto cleanNodes = std::move(changedNodes_);
5662     changedNodes_.clear();
5663     for (const auto& it : cleanNodes) {
5664         auto changeNode = it.Upgrade();
5665         if (changeNode) {
5666             changeNode->ClearChangeInfoFlag();
5667         }
5668     }
5669 }
5670 
NotifyAllWebPattern(bool isRegister)5671 void PipelineContext::NotifyAllWebPattern(bool isRegister)
5672 {
5673     rootNode_->NotifyWebPattern(isRegister);
5674 }
5675 
UpdateHalfFoldHoverStatus(int32_t windowWidth,int32_t windowHeight)5676 void PipelineContext::UpdateHalfFoldHoverStatus(int32_t windowWidth, int32_t windowHeight)
5677 {
5678     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_THIRTEEN)) {
5679         isHalfFoldHoverStatus_ = false;
5680         return;
5681     }
5682     auto container = Container::Current();
5683     CHECK_NULL_VOID(container);
5684     bool isFoldable = container->IsFoldable();
5685     if (!isFoldable && !SystemProperties::IsSmallFoldProduct()) {
5686         isHalfFoldHoverStatus_ = false;
5687         return;
5688     }
5689     auto displayInfo = container->GetDisplayInfo();
5690     CHECK_NULL_VOID(displayInfo);
5691     auto windowManager = GetWindowManager();
5692     auto windowMode = windowManager->GetWindowMode();
5693     auto isHalfFolded = displayInfo->GetFoldStatus() == FoldStatus::HALF_FOLD;
5694     auto displayWidth = displayInfo->GetWidth();
5695     auto displayHeight = displayInfo->GetHeight();
5696     auto isFullScreen = windowMode == WindowMode::WINDOW_MODE_FULLSCREEN ||
5697         (NearEqual(displayWidth, windowWidth) && NearEqual(displayHeight, windowHeight));
5698     if (!isFullScreen || !isHalfFolded) {
5699         isHalfFoldHoverStatus_ = false;
5700         return;
5701     }
5702     auto rotation = displayInfo->GetRotation();
5703     if (SystemProperties::IsSmallFoldProduct()) {
5704         isHalfFoldHoverStatus_ = rotation == Rotation::ROTATION_0 || rotation == Rotation::ROTATION_180;
5705     } else {
5706         isHalfFoldHoverStatus_ = rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270;
5707     }
5708 }
5709 
OnHalfFoldHoverChangedCallback()5710 void PipelineContext::OnHalfFoldHoverChangedCallback()
5711 {
5712     auto tempHalfFoldHoverChangedCallbackMap = halfFoldHoverChangedCallbackMap_;
5713     for (auto&& [id, callback] : tempHalfFoldHoverChangedCallbackMap) {
5714         if (callback) {
5715             callback(isHalfFoldHoverStatus_);
5716         }
5717     }
5718 }
5719 
StartFoldStatusDelayTask(FoldStatus foldStatus)5720 void PipelineContext::StartFoldStatusDelayTask(FoldStatus foldStatus)
5721 {
5722     if (foldStatusDelayTask_) {
5723         foldStatusDelayTask_.Cancel();
5724     }
5725     foldStatusDelayTask_.Reset([weak = WeakClaim(this)]() {
5726         auto context = weak.Upgrade();
5727         CHECK_NULL_VOID(context);
5728         context->UpdateHalfFoldHoverProperty(context->GetRootWidth(), context->GetRootHeight());
5729         context->OnHalfFoldHoverChangedCallback();
5730     });
5731     taskExecutor_->PostDelayedTask(
5732         foldStatusDelayTask_, TaskExecutor::TaskType::UI, DELAY_TIME, "ArkUIHalfFoldHoverStatusChange");
5733 }
5734 
GetResponseRegion(const RefPtr<FrameNode> & rootNode)5735 std::string PipelineContext::GetResponseRegion(const RefPtr<FrameNode>& rootNode)
5736 {
5737     CHECK_NULL_RETURN(rootNode, "");
5738     std::vector<RectF> responseRegionList;
5739     rootNode->GetResponseRegionListByTraversal(responseRegionList);
5740     std::string responseRegionStrOrigin;
5741     std::string responseRegionStrFilter;
5742     for (const auto& rect : responseRegionList) {
5743         int32_t left = static_cast<int32_t>(rect.Left());
5744         int32_t top = static_cast<int32_t>(rect.Top());
5745         int32_t width = static_cast<int32_t>(rect.Width());
5746         int32_t height = static_cast<int32_t>(rect.Height());
5747         int32_t right = static_cast<int32_t>(rect.Right());
5748         int32_t bottom = static_cast<int32_t>(rect.Bottom());
5749         std::string rectStr = std::to_string(left) + "," +
5750                               std::to_string(top) + "," +
5751                               std::to_string(right) + "," +
5752                               std::to_string(bottom);
5753 
5754         responseRegionStrOrigin += rectStr + "#";
5755         if (thpExtraMgr_ && width <= thpExtraMgr_->GetWidth() && height <= thpExtraMgr_->GetHeight()) {
5756             responseRegionStrFilter += rectStr + "#";
5757         }
5758     }
5759     if (!responseRegionStrFilter.empty()) {
5760         responseRegionStrFilter.pop_back();
5761     }
5762     LOGD("THP_UpdateViewsLocation origin responseRegion = %{public}s", responseRegionStrOrigin.c_str());
5763     return responseRegionStrFilter;
5764 }
5765 
NotifyResponseRegionChanged(const RefPtr<FrameNode> & rootNode)5766 void PipelineContext::NotifyResponseRegionChanged(const RefPtr<FrameNode>& rootNode)
5767 {
5768     ACE_FUNCTION_TRACE();
5769     if (!thpExtraMgr_) {
5770         return;
5771     }
5772     std::string responseRegion = GetResponseRegion(rootNode);
5773     std::string parameters = "thp#Location#" + responseRegion;
5774     LOGD("THP_UpdateViewsLocation responseRegion = %{public}s", parameters.c_str());
5775     thpExtraMgr_->ThpExtraRunCommand("THP_UpdateViewsLocation", parameters.c_str());
5776 }
5777 #if defined(SUPPORT_TOUCH_TARGET_TEST)
5778 
OnTouchTargetHitTest(const TouchEvent & point,bool isSubPipe,const std::string & target)5779 bool PipelineContext::OnTouchTargetHitTest(const TouchEvent& point, bool isSubPipe, const std::string& target)
5780 {
5781     auto scalePoint = point.CreateScalePoint(GetViewScale());
5782     if (scalePoint.type == TouchType::DOWN) {
5783         TouchRestrict touchRestrict { TouchRestrict::NONE };
5784         touchRestrict.sourceType = point.sourceType;
5785         touchRestrict.touchEvent = point;
5786         bool isTouchTarget = eventManager_->TouchTargetHitTest(
5787             scalePoint, rootNode_, touchRestrict, GetPluginEventOffset(), viewScale_, isSubPipe, target);
5788         return isTouchTarget;
5789     }
5790     return false;
5791 }
5792 #endif
5793 
CatchInteractiveAnimations(const std::function<void ()> & animationCallback)5794 bool PipelineContext::CatchInteractiveAnimations(const std::function<void()>& animationCallback)
5795 {
5796     CHECK_NULL_RETURN(navigationMgr_, false);
5797     if (navigationMgr_->IsInteractive()) {
5798         return navigationMgr_->AddInteractiveAnimation(animationCallback);
5799     }
5800     return false;
5801 }
5802 
CheckThreadSafe()5803 bool PipelineContext::CheckThreadSafe()
5804 {
5805     CHECK_NULL_RETURN(taskExecutor_, true);
5806     if (!isFormRender_ && !taskExecutor_->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
5807         LogBacktrace();
5808         return false;
5809     }
5810     return true;
5811 }
5812 
AdjustVsyncTimeStamp(uint64_t nanoTimestamp)5813 uint64_t PipelineContext::AdjustVsyncTimeStamp(uint64_t nanoTimestamp)
5814 {
5815     auto period = window_->GetVSyncPeriod();
5816     if (period > 0 && recvTime_ > static_cast<int64_t>(nanoTimestamp) + MAX_MISS_COUNT * period) {
5817         return static_cast<uint64_t>(recvTime_ - ((recvTime_ - static_cast<int64_t>(nanoTimestamp)) % period));
5818     }
5819     return nanoTimestamp;
5820 }
5821 
FlushModifierAnimation(uint64_t nanoTimestamp)5822 bool PipelineContext::FlushModifierAnimation(uint64_t nanoTimestamp)
5823 {
5824     auto animationTimeStamp = AdjustVsyncTimeStamp(nanoTimestamp);
5825     if (animationTimeStamp < animationTimeStamp_) {
5826         ACE_SCOPED_TRACE("skip ModifierAnimation");
5827         TAG_LOGW(AceLogTag::ACE_ANIMATION,
5828             "Time decreases, skip ModifierAnimation, lastTime:%{public}" PRIu64 ", nowTime:%{public}" PRIu64,
5829             animationTimeStamp_, animationTimeStamp);
5830         return true;
5831     }
5832     animationTimeStamp_ = animationTimeStamp;
5833     return window_->FlushAnimation(animationTimeStamp);
5834 }
5835 
RegisterAttachedNode(UINode * uiNode)5836 void PipelineContext::RegisterAttachedNode(UINode* uiNode)
5837 {
5838     attachedNodeSet_.emplace(uiNode);
5839 }
5840 
RemoveAttachedNode(UINode * uiNode)5841 void PipelineContext::RemoveAttachedNode(UINode* uiNode)
5842 {
5843     attachedNodeSet_.erase(uiNode);
5844 }
5845 
ScopedLayout(PipelineContext * pipeline)5846 ScopedLayout::ScopedLayout(PipelineContext* pipeline)
5847 {
5848     if (!pipeline) {
5849         return;
5850     }
5851     // save flag before measure
5852     pipeline_ = pipeline;
5853     isLayouting_ = pipeline_->IsLayouting();
5854     pipeline_->SetIsLayouting(true);
5855 }
5856 
~ScopedLayout()5857 ScopedLayout::~ScopedLayout()
5858 {
5859     if (!pipeline_) {
5860         return;
5861     }
5862     // set layout flag back
5863     pipeline_->SetIsLayouting(isLayouting_);
5864 }
5865 
GetBundleName()5866 std::string PipelineContext::GetBundleName()
5867 {
5868     auto container = Container::GetContainer(instanceId_);
5869     CHECK_NULL_RETURN(container, "");
5870     return container->GetBundleName();
5871 }
5872 
GetModuleName()5873 std::string PipelineContext::GetModuleName()
5874 {
5875     auto container = Container::GetContainer(instanceId_);
5876     CHECK_NULL_RETURN(container, "");
5877     return container->GetModuleName();
5878 }
5879 
SetEnableSwipeBack(bool isEnable)5880 void PipelineContext::SetEnableSwipeBack(bool isEnable)
5881 {
5882     CHECK_NULL_VOID(rootNode_);
5883     auto rootPattern = rootNode_->GetPattern<RootPattern>();
5884     CHECK_NULL_VOID(rootPattern);
5885     rootPattern->SetEnableSwipeBack(isEnable);
5886 }
5887 
SetHostParentOffsetToWindow(const Offset & offset)5888 void PipelineContext::SetHostParentOffsetToWindow(const Offset& offset)
5889 {
5890     lastHostParentOffsetToWindow_ = offset;
5891     CHECK_NULL_VOID(rootNode_);
5892     auto renderContext = rootNode_->GetRenderContext();
5893     CHECK_NULL_VOID(renderContext);
5894     renderContext->RequestNextFrame();
5895 }
5896 
GetUIContext()5897 RefPtr<Kit::UIContext> PipelineContext::GetUIContext()
5898 {
5899     if (uiContextImpl_) {
5900         return uiContextImpl_;
5901     }
5902     uiContextImpl_ = AceType::MakeRefPtr<Kit::UIContextImpl>(this);
5903     return uiContextImpl_;
5904 }
5905 
GetAllPixelMap()5906 void PipelineContext::GetAllPixelMap()
5907 {
5908     CHECK_NULL_VOID(stageManager_);
5909     auto pageNode = stageManager_->GetLastPage();
5910     CHECK_NULL_VOID(pageNode);
5911     CHECK_NULL_VOID(uiTranslateManager_);
5912     uiTranslateManager_->GetAllPixelMap(pageNode);
5913 }
5914 
SetDisplayWindowRectInfo(const Rect & displayWindowRectInfo)5915 void PipelineContext::SetDisplayWindowRectInfo(const Rect& displayWindowRectInfo)
5916 {
5917     auto offSetPosX_ = displayWindowRectInfo_.Left() - displayWindowRectInfo.Left();
5918     auto offSetPosY_ = displayWindowRectInfo_.Top() - displayWindowRectInfo.Top();
5919     if (!NearZero(offSetPosX_) || !NearZero(offSetPosY_)) {
5920         if (lastMouseEvent_) {
5921             lastMouseEvent_->x += offSetPosX_;
5922             lastMouseEvent_->y += offSetPosY_;
5923         }
5924     }
5925     displayWindowRectInfo_ = displayWindowRectInfo;
5926 }
5927 
SetIsTransFlag(bool result)5928 void PipelineContext::SetIsTransFlag(bool result)
5929 {
5930     isTransFlag_ = result;
5931 }
5932 
FlushMouseEventForHover()5933 void PipelineContext::FlushMouseEventForHover()
5934 {
5935     if (!isTransFlag_ || !lastMouseEvent_ || lastMouseEvent_->sourceType != SourceType::MOUSE ||
5936         lastMouseEvent_->action == MouseAction::PRESS || lastSourceType_ == SourceType::TOUCH) {
5937         return;
5938     }
5939     CHECK_NULL_VOID(rootNode_);
5940     if (lastMouseEvent_->isMockWindowTransFlag || windowSizeChangeReason_ == WindowSizeChangeReason::DRAG ||
5941         windowSizeChangeReason_ == WindowSizeChangeReason::MOVE) {
5942         return;
5943     }
5944     CHECK_RUN_ON(TaskExecutor::TaskType::UI);
5945     auto container = Container::Current();
5946     CHECK_NULL_VOID(container);
5947     MouseEvent event;
5948     event.x = lastMouseEvent_->x;
5949     event.y = lastMouseEvent_->y;
5950     event.screenX = lastMouseEvent_->screenX;
5951     event.screenY = lastMouseEvent_->screenY;
5952     event.button = lastMouseEvent_->button;
5953     event.sourceType = lastMouseEvent_->sourceType;
5954     event.action = lastMouseEvent_->action;
5955     event.time = lastMouseEvent_->time;
5956     event.touchEventId = lastMouseEvent_->touchEventId;
5957     event.mockFlushEvent = true;
5958     event.pointerEvent = lastMouseEvent_->pointerEvent;
5959     TouchRestrict touchRestrict { TouchRestrict::NONE };
5960     touchRestrict.sourceType = event.sourceType;
5961     touchRestrict.hitTestType = SourceType::MOUSE;
5962     touchRestrict.inputEventType = InputEventType::MOUSE_BUTTON;
5963     if (container->IsScenceBoardWindow()) {
5964         eventManager_->MouseTest(event, lastMouseEvent_->node.Upgrade(), touchRestrict);
5965     } else {
5966         eventManager_->MouseTest(event, rootNode_, touchRestrict);
5967     }
5968     eventManager_->DispatchMouseHoverEventNG(event);
5969     eventManager_->DispatchMouseHoverAnimationNG(event);
5970 }
5971 
HandleTouchHoverOut(const TouchEvent & point)5972 void PipelineContext::HandleTouchHoverOut(const TouchEvent& point)
5973 {
5974     if (point.sourceTool != SourceTool::FINGER || NearZero(point.force)) {
5975         return;
5976     }
5977     lastSourceType_ = SourceType::TOUCH;
5978     CHECK_RUN_ON(UI);
5979     eventManager_->CleanHoverStatusForDragBegin();
5980 }
5981 
FlushMouseEventInVsync()5982 void PipelineContext::FlushMouseEventInVsync()
5983 {
5984     auto mouseEventSize = mouseEvents_.size();
5985     if (!mouseEvents_.empty()) {
5986         FlushMouseEvent();
5987         isNeedFlushMouseEvent_ = MockFlushEventType::NONE;
5988         mouseEvents_.clear();
5989     } else if (isNeedFlushMouseEvent_ == MockFlushEventType::REJECT ||
5990                isNeedFlushMouseEvent_ == MockFlushEventType::EXECUTE) {
5991         FlushMouseEventVoluntarily();
5992         isNeedFlushMouseEvent_ = MockFlushEventType::NONE;
5993     }
5994     if (!lastMouseEvent_) {
5995         return;
5996     }
5997     if (isTransFlag_ && (mouseEventSize == 0 || lastMouseEvent_->mockFlushEvent)) {
5998         FlushMouseEventForHover();
5999     }
6000     isTransFlag_ = false;
6001 }
6002 
SetWindowSizeChangeReason(WindowSizeChangeReason reason)6003 void PipelineContext::SetWindowSizeChangeReason(WindowSizeChangeReason reason)
6004 {
6005     windowSizeChangeReason_ = reason;
6006 }
6007 } // namespace OHOS::Ace::NG
6008