• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/pipeline_ng/pipeline_context.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 
24 #include "base/log/log_wrapper.h"
25 
26 #ifdef ENABLE_ROSEN_BACKEND
27 #include "render_service_client/core/transaction/rs_transaction.h"
28 #include "render_service_client/core/ui/rs_ui_director.h"
29 #endif
30 
31 #include "base/geometry/ng/offset_t.h"
32 #include "base/geometry/ng/rect_t.h"
33 #include "base/log/ace_trace.h"
34 #include "base/log/ace_tracker.h"
35 #include "base/log/dump_log.h"
36 #include "base/log/event_report.h"
37 #include "base/memory/ace_type.h"
38 #include "base/memory/referenced.h"
39 #include "base/ressched/ressched_report.h"
40 #include "base/thread/task_executor.h"
41 #include "base/utils/time_util.h"
42 #include "base/utils/utils.h"
43 #include "core/animation/scheduler.h"
44 #include "core/common/ace_application_info.h"
45 #include "core/common/container.h"
46 #include "core/common/font_manager.h"
47 #include "core/common/layout_inspector.h"
48 #include "core/common/text_field_manager.h"
49 #include "core/common/thread_checker.h"
50 #include "core/common/window.h"
51 #include "core/components/common/layout/screen_system_manager.h"
52 #include "core/components_ng/base/frame_node.h"
53 #include "core/components_ng/base/ui_node.h"
54 #include "core/components_ng/event/focus_hub.h"
55 #include "core/components_ng/pattern/app_bar/app_bar_view.h"
56 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
57 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
58 #include "core/components_ng/pattern/container_modal/container_modal_view_factory.h"
59 #include "core/components_ng/pattern/container_modal/enhance/container_modal_pattern_enhance.h"
60 #include "core/components_ng/pattern/custom/custom_node_base.h"
61 #include "core/components_ng/pattern/image/image_layout_property.h"
62 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
63 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
64 #include "core/components_ng/pattern/navigation/title_bar_node.h"
65 #include "core/components_ng/pattern/navrouter/navdestination_group_node.h"
66 #include "core/components_ng/pattern/overlay/overlay_manager.h"
67 #include "core/components_ng/pattern/root/root_pattern.h"
68 #include "core/components_ng/pattern/stage/page_pattern.h"
69 #include "core/components_ng/pattern/stage/stage_pattern.h"
70 #include "core/components_ng/pattern/text_field/text_field_manager.h"
71 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
72 #include "core/components_ng/property/calc_length.h"
73 #include "core/components_ng/property/measure_property.h"
74 #include "core/components_ng/property/safe_area_insets.h"
75 #include "core/components_v2/inspector/inspector_constants.h"
76 #include "core/event/ace_events.h"
77 #include "core/event/touch_event.h"
78 #include "core/image/image_file_cache.h"
79 #include "core/pipeline/base/element_register.h"
80 #include "core/pipeline/pipeline_context.h"
81 #include "core/pipeline_ng/ui_task_scheduler.h"
82 
83 namespace {
84 constexpr uint64_t ONE_MS_IN_NS = 1 * 1000 * 1000;
85 constexpr uint64_t INTERPOLATION_THRESHOLD = 100 * 1000 * 1000; // 100ms
86 constexpr int32_t INDEX_X = 0;
87 constexpr int32_t INDEX_Y = 1;
88 constexpr int32_t INDEX_TIME = 2;
89 constexpr int32_t TIME_THRESHOLD = 2 * 1000000; // 3 millisecond
90 constexpr int32_t PLATFORM_VERSION_TEN = 10;
91 constexpr int32_t USED_ID_FIND_FLAG = 3;                 // if args >3 , it means use id to find
92 constexpr int32_t MILLISECONDS_TO_NANOSECONDS = 1000000; // Milliseconds to nanoseconds
93 } // namespace
94 
95 namespace OHOS::Ace::NG {
96 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,RefPtr<PlatformResRegister> platformResRegister,const RefPtr<Frontend> & frontend,int32_t instanceId)97 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
98     RefPtr<AssetManager> assetManager, RefPtr<PlatformResRegister> platformResRegister,
99     const RefPtr<Frontend>& frontend, int32_t instanceId)
100     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId, platformResRegister)
101 {
102     window_->OnHide();
103 }
104 
PipelineContext(std::shared_ptr<Window> window,RefPtr<TaskExecutor> taskExecutor,RefPtr<AssetManager> assetManager,const RefPtr<Frontend> & frontend,int32_t instanceId)105 PipelineContext::PipelineContext(std::shared_ptr<Window> window, RefPtr<TaskExecutor> taskExecutor,
106     RefPtr<AssetManager> assetManager, const RefPtr<Frontend>& frontend, int32_t instanceId)
107     : PipelineBase(window, std::move(taskExecutor), std::move(assetManager), frontend, instanceId)
108 {
109     window_->OnHide();
110 }
111 
GetCurrentContext()112 RefPtr<PipelineContext> PipelineContext::GetCurrentContext()
113 {
114     auto currentContainer = Container::Current();
115     CHECK_NULL_RETURN(currentContainer, nullptr);
116     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
117 }
118 
GetCurrentContextSafely()119 RefPtr<PipelineContext> PipelineContext::GetCurrentContextSafely()
120 {
121     auto currentContainer = Container::CurrentSafely();
122     CHECK_NULL_RETURN(currentContainer, nullptr);
123     return DynamicCast<PipelineContext>(currentContainer->GetPipelineContext());
124 }
125 
GetMainPipelineContext()126 RefPtr<PipelineContext> PipelineContext::GetMainPipelineContext()
127 {
128     auto pipeline = PipelineBase::GetMainPipelineContext();
129     CHECK_NULL_RETURN(pipeline, nullptr);
130     return DynamicCast<PipelineContext>(pipeline);
131 }
132 
NeedSoftKeyboard()133 bool PipelineContext::NeedSoftKeyboard()
134 {
135     auto focusNode = GetFocusNode();
136     if (!focusNode) {
137         return false;
138     }
139     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Focus node id is: %{public}d, tag is %{public}s", focusNode->GetId(),
140         focusNode->GetTag().c_str());
141     auto pattern = focusNode->GetPattern();
142     CHECK_NULL_RETURN(pattern, false);
143     bool isNeed = pattern->NeedSoftKeyboard();
144 #ifdef WINDOW_SCENE_SUPPORTED
145     if (isNeed) {
146         isNeed = WindowSceneHelper::GetNeedKeyboardOnFocusFlag(focusNode);
147     }
148 #endif
149     TAG_LOGI(AceLogTag::ACE_KEYBOARD, "need soft keyboard %{public}d", isNeed);
150     return isNeed;
151 }
152 
GetContextByContainerId(int32_t containerId)153 RefPtr<PipelineContext> PipelineContext::GetContextByContainerId(int32_t containerId)
154 {
155     auto preContainer = Container::GetContainer(containerId);
156     CHECK_NULL_RETURN(preContainer, nullptr);
157     return DynamicCast<PipelineContext>(preContainer->GetPipelineContext());
158 }
159 
GetCurrentRootWidth()160 float PipelineContext::GetCurrentRootWidth()
161 {
162     auto context = GetCurrentContext();
163     CHECK_NULL_RETURN(context, 0.0f);
164     return static_cast<float>(context->rootWidth_);
165 }
166 
GetCurrentRootHeight()167 float PipelineContext::GetCurrentRootHeight()
168 {
169     auto context = GetCurrentContext();
170     CHECK_NULL_RETURN(context, 0.0f);
171     return static_cast<float>(context->rootHeight_);
172 }
173 
AddDirtyPropertyNode(const RefPtr<FrameNode> & dirtyNode)174 void PipelineContext::AddDirtyPropertyNode(const RefPtr<FrameNode>& dirtyNode)
175 {
176     dirtyPropertyNodes_.emplace(dirtyNode);
177     hasIdleTasks_ = true;
178     RequestFrame();
179 }
180 
AddDirtyCustomNode(const RefPtr<UINode> & dirtyNode)181 void PipelineContext::AddDirtyCustomNode(const RefPtr<UINode>& dirtyNode)
182 {
183     CHECK_RUN_ON(UI);
184     CHECK_NULL_VOID(dirtyNode);
185     auto customNode = DynamicCast<CustomNode>(dirtyNode);
186     if (customNode && !dirtyNode->GetInspectorIdValue("").empty()) {
187         ACE_LAYOUT_SCOPED_TRACE("AddDirtyCustomNode[%s][self:%d][parent:%d][key:%s]",
188             customNode->GetJSViewName().c_str(),
189             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0,
190             dirtyNode->GetInspectorIdValue("").c_str());
191     } else if (customNode) {
192         ACE_LAYOUT_SCOPED_TRACE("AddDirtyCustomNode[%s][self:%d][parent:%d]",
193             customNode->GetJSViewName().c_str(),
194             dirtyNode->GetId(), dirtyNode->GetParent() ? dirtyNode->GetParent()->GetId() : 0);
195     }
196     dirtyNodes_.emplace(dirtyNode);
197     hasIdleTasks_ = true;
198     RequestFrame();
199 }
200 
AddDirtyLayoutNode(const RefPtr<FrameNode> & dirty)201 void PipelineContext::AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty)
202 {
203     CHECK_RUN_ON(UI);
204     CHECK_NULL_VOID(dirty);
205     if (!dirty->GetInspectorIdValue("").empty()) {
206         ACE_LAYOUT_SCOPED_TRACE("AddDirtyLayoutNode[%s][self:%d][parent:%d][key:%s]",
207             dirty->GetTag().c_str(),
208             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
209             dirty->GetInspectorIdValue("").c_str());
210     } else {
211         ACE_LAYOUT_SCOPED_TRACE("AddDirtyLayoutNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
212             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
213     }
214     taskScheduler_->AddDirtyLayoutNode(dirty);
215     ForceLayoutForImplicitAnimation();
216 #ifdef UICAST_COMPONENT_SUPPORTED
217     do {
218         auto container = Container::Current();
219         CHECK_NULL_BREAK(container);
220         auto distributedUI = container->GetDistributedUI();
221         CHECK_NULL_BREAK(distributedUI);
222         distributedUI->AddDirtyLayoutNode(dirty->GetId());
223     } while (false);
224 #endif
225     hasIdleTasks_ = true;
226     RequestFrame();
227 }
228 
AddDirtyRenderNode(const RefPtr<FrameNode> & dirty)229 void PipelineContext::AddDirtyRenderNode(const RefPtr<FrameNode>& dirty)
230 {
231     CHECK_RUN_ON(UI);
232     CHECK_NULL_VOID(dirty);
233     if (!dirty->GetInspectorIdValue("").empty()) {
234         ACE_LAYOUT_SCOPED_TRACE("AddDirtyRenderNode[%s][self:%d][parent:%d][key:%s]", dirty->GetTag().c_str(),
235             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0,
236             dirty->GetInspectorIdValue("").c_str());
237     } else {
238         ACE_LAYOUT_SCOPED_TRACE("AddDirtyRenderNode[%s][self:%d][parent:%d]", dirty->GetTag().c_str(),
239             dirty->GetId(), dirty->GetParent() ? dirty->GetParent()->GetId() : 0);
240     }
241     taskScheduler_->AddDirtyRenderNode(dirty);
242     ForceRenderForImplicitAnimation();
243 #ifdef UICAST_COMPONENT_SUPPORTED
244     do {
245         auto container = Container::Current();
246         CHECK_NULL_BREAK(container);
247         auto distributedUI = container->GetDistributedUI();
248         CHECK_NULL_BREAK(distributedUI);
249         distributedUI->AddDirtyRenderNode(dirty->GetId());
250     } while (false);
251 #endif
252     hasIdleTasks_ = true;
253     RequestFrame();
254 }
255 
FlushDirtyNodeUpdate()256 void PipelineContext::FlushDirtyNodeUpdate()
257 {
258     CHECK_RUN_ON(UI);
259     ACE_FUNCTION_TRACE();
260     if (FrameReport::GetInstance().GetEnable()) {
261         FrameReport::GetInstance().BeginFlushBuild();
262     }
263 
264     // node api property diff before ets update.
265     decltype(dirtyPropertyNodes_) dirtyPropertyNodes(std::move(dirtyPropertyNodes_));
266     dirtyPropertyNodes_.clear();
267     for (const auto& node : dirtyPropertyNodes) {
268         node->ProcessPropertyDiff();
269     }
270 
271     // SomeTimes, customNode->Update may add some dirty custom nodes to dirtyNodes_,
272     // use maxFlushTimes to avoid dead cycle.
273     int maxFlushTimes = 3;
274     while (!dirtyNodes_.empty() && maxFlushTimes > 0) {
275         decltype(dirtyNodes_) dirtyNodes(std::move(dirtyNodes_));
276         for (const auto& node : dirtyNodes) {
277             if (AceType::InstanceOf<NG::CustomNodeBase>(node)) {
278                 auto customNode = AceType::DynamicCast<NG::CustomNodeBase>(node);
279                 ACE_SCOPED_TRACE("CustomNodeUpdate %s", customNode->GetJSViewName().c_str());
280                 customNode->Update();
281             }
282         }
283         --maxFlushTimes;
284     }
285 
286     if (FrameReport::GetInstance().GetEnable()) {
287         FrameReport::GetInstance().EndFlushBuild();
288     }
289 }
290 
AddScheduleTask(const RefPtr<ScheduleTask> & task)291 uint32_t PipelineContext::AddScheduleTask(const RefPtr<ScheduleTask>& task)
292 {
293     CHECK_RUN_ON(UI);
294     scheduleTasks_.try_emplace(++nextScheduleTaskId_, task);
295     RequestFrame();
296     return nextScheduleTaskId_;
297 }
298 
RemoveScheduleTask(uint32_t id)299 void PipelineContext::RemoveScheduleTask(uint32_t id)
300 {
301     CHECK_RUN_ON(UI);
302     scheduleTasks_.erase(id);
303 }
304 
LinearInterpolation(const std::tuple<float,float,uint64_t> & history,const std::tuple<float,float,uint64_t> & current,const uint64_t nanoTimeStamp)305 std::pair<float, float> PipelineContext::LinearInterpolation(const std::tuple<float, float, uint64_t>& history,
306     const std::tuple<float, float, uint64_t>& current, const uint64_t nanoTimeStamp)
307 {
308     if (nanoTimeStamp == std::get<INDEX_TIME>(history) || nanoTimeStamp == std::get<INDEX_TIME>(current)) {
309         return std::make_pair(0.0f, 0.0f);
310     }
311     if (std::get<INDEX_TIME>(current) <= std::get<INDEX_TIME>(history)) {
312         return std::make_pair(0.0f, 0.0f);
313     }
314     if (std::get<INDEX_TIME>(current) - std::get<INDEX_TIME>(history) > INTERPOLATION_THRESHOLD) {
315         return std::make_pair(0.0f, 0.0f);
316     }
317     if (nanoTimeStamp < std::get<INDEX_TIME>(history)) {
318         return std::make_pair(0.0f, 0.0f);
319     }
320     if (nanoTimeStamp < std::get<INDEX_TIME>(current)) {
321         float alpha = (float)(nanoTimeStamp - std::get<INDEX_TIME>(history)) /
322                       (float)(std::get<INDEX_TIME>(current) - std::get<INDEX_TIME>(history));
323         float x = std::get<INDEX_X>(history) + alpha * (std::get<INDEX_X>(current) - std::get<INDEX_X>(history));
324         float y = std::get<INDEX_Y>(history) + alpha * (std::get<INDEX_Y>(current) - std::get<INDEX_Y>(history));
325         return std::make_pair(x, y);
326     } else if (nanoTimeStamp > std::get<INDEX_TIME>(current)) {
327         float alpha = (float)(nanoTimeStamp - std::get<INDEX_TIME>(current)) /
328                       (float)(std::get<INDEX_TIME>(current) - std::get<INDEX_TIME>(history));
329         float x = std::get<INDEX_X>(current) + alpha * (std::get<INDEX_X>(current) - std::get<INDEX_X>(history));
330         float y = std::get<INDEX_Y>(current) + alpha * (std::get<INDEX_Y>(current) - std::get<INDEX_Y>(history));
331         return std::make_pair(x, y);
332     }
333     return std::make_pair(0.0f, 0.0f);
334 }
335 
GetAvgPoint(const std::vector<TouchEvent> & events,const bool isScreen)336 std::tuple<float, float, uint64_t> PipelineContext::GetAvgPoint(
337     const std::vector<TouchEvent>& events, const bool isScreen)
338 {
339     float avgX = 0.0f;
340     float avgY = 0.0f;
341     uint64_t avgTime = 0;
342     int32_t i = 0;
343     uint64_t lastTime = 0;
344     for (auto iter = events.begin(); iter != events.end(); iter++) {
345         if (lastTime == 0 || static_cast<uint64_t>(iter->time.time_since_epoch().count()) != lastTime) {
346             if (!isScreen) {
347                 avgX += iter->x;
348                 avgY += iter->y;
349             } else {
350                 avgX += iter->screenX;
351                 avgY += iter->screenY;
352             }
353             avgTime += static_cast<uint64_t>(iter->time.time_since_epoch().count());
354             i++;
355             lastTime = static_cast<uint64_t>(iter->time.time_since_epoch().count());
356         }
357     }
358     avgX /= i;
359     avgY /= i;
360     avgTime /= i;
361     return std::make_tuple(avgX, avgY, avgTime);
362 }
363 
GetResampleCoord(const std::vector<TouchEvent> & history,const std::vector<TouchEvent> & current,const uint64_t nanoTimeStamp,const bool isScreen)364 std::pair<float, float> PipelineContext::GetResampleCoord(const std::vector<TouchEvent>& history,
365     const std::vector<TouchEvent>& current, const uint64_t nanoTimeStamp, const bool isScreen)
366 {
367     if (history.empty() || current.empty()) {
368         return std::make_pair(0.0f, 0.0f);
369     }
370     auto historyPoint = GetAvgPoint(history, isScreen);
371     auto currentPoint = GetAvgPoint(current, isScreen);
372 
373     if (SystemProperties::GetDebugEnabled()) {
374         LOGI("input time is %{public}" PRIu64 "", nanoTimeStamp);
375         for (auto iter : history) {
376             LOGI("history point x %{public}f, y %{public}f, time %{public}" PRIu64 "", iter.x, iter.y,
377                 static_cast<uint64_t>(iter.time.time_since_epoch().count()));
378         }
379         LOGI("historyAvgPoint is x %{public}f, y %{public}f, time %{public}" PRIu64 "", std::get<INDEX_X>(historyPoint),
380             std::get<INDEX_Y>(historyPoint), std::get<INDEX_TIME>(historyPoint));
381         for (auto iter : current) {
382             LOGI("current point x %{public}f, y %{public}f, time %{public}" PRIu64 "", iter.x, iter.y,
383                 static_cast<uint64_t>(iter.time.time_since_epoch().count()));
384         }
385         LOGI("currentAvgPoint is x %{public}f, y %{public}f, time %{public}" PRIu64 "", std::get<INDEX_X>(currentPoint),
386             std::get<INDEX_Y>(currentPoint), std::get<INDEX_TIME>(currentPoint));
387     }
388     return LinearInterpolation(historyPoint, currentPoint, nanoTimeStamp);
389 }
390 
GetResampleTouchEvent(const std::vector<TouchEvent> & history,const std::vector<TouchEvent> & current,const uint64_t nanoTimeStamp)391 TouchEvent PipelineContext::GetResampleTouchEvent(
392     const std::vector<TouchEvent>& history, const std::vector<TouchEvent>& current, const uint64_t nanoTimeStamp)
393 {
394     auto newXy = GetResampleCoord(history, current, nanoTimeStamp, false);
395     auto newScreenXy = GetResampleCoord(history, current, nanoTimeStamp, true);
396     TouchEvent newTouchEvent = GetLatestPoint(current, nanoTimeStamp);
397     if (newXy.first != 0 && newXy.second != 0) {
398         newTouchEvent.x = newXy.first;
399         newTouchEvent.y = newXy.second;
400         newTouchEvent.screenX = newScreenXy.first;
401         newTouchEvent.screenY = newScreenXy.second;
402         std::chrono::nanoseconds nanoseconds(nanoTimeStamp);
403         newTouchEvent.time = TimeStamp(nanoseconds);
404         newTouchEvent.history = current;
405         newTouchEvent.isInterpolated = true;
406     }
407     if (SystemProperties::GetDebugEnabled()) {
408         LOGI("Interpolate point is %{public}d, %{public}f, %{public}f, %{public}f, %{public}f, %{public}" PRIu64 "",
409             newTouchEvent.id, newTouchEvent.x, newTouchEvent.y, newTouchEvent.screenX, newTouchEvent.screenY,
410             static_cast<uint64_t>(newTouchEvent.time.time_since_epoch().count()));
411     }
412     return newTouchEvent;
413 }
414 
GetLatestPoint(const std::vector<TouchEvent> & current,const uint64_t nanoTimeStamp)415 TouchEvent PipelineContext::GetLatestPoint(const std::vector<TouchEvent>& current, const uint64_t nanoTimeStamp)
416 {
417     TouchEvent result;
418     uint64_t gap = UINT64_MAX;
419     for (auto iter = current.begin(); iter != current.end(); iter++) {
420         uint64_t timeStamp = static_cast<uint64_t>(iter->time.time_since_epoch().count());
421         if (timeStamp == nanoTimeStamp) {
422             result = *iter;
423             return result;
424         } else if (timeStamp > nanoTimeStamp) {
425             if (timeStamp - nanoTimeStamp < gap) {
426                 gap = timeStamp - nanoTimeStamp;
427                 result = *iter;
428             }
429         } else {
430             if (nanoTimeStamp - timeStamp < gap) {
431                 gap = nanoTimeStamp - timeStamp;
432                 result = *iter;
433             }
434         }
435     }
436     return result;
437 }
438 
HandleFocusNode()439 RefPtr<FrameNode> PipelineContext::HandleFocusNode()
440 {
441     auto curRootNode = GetScreenNode();
442     if (curRootNode == nullptr) {
443         curRootNode = rootNode_;
444     }
445     CHECK_NULL_RETURN(curRootNode, nullptr);
446     auto rootFocusHub = curRootNode->GetFocusHub();
447     CHECK_NULL_RETURN(rootFocusHub, nullptr);
448     RefPtr<FocusHub> lastFocusNode;
449     std::list<RefPtr<FocusHub>> focusNodes = rootFocusHub->GetChildren();
450     for (const auto& item : focusNodes) {
451         if (item->IsCurrentFocus()) {
452             lastFocusNode = item;
453         }
454     }
455     while (lastFocusNode) {
456         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "curLastFocusNodeTAG:(%{public}s).", lastFocusNode->GetFrameName().c_str());
457         if (!lastFocusNode->IsCurrentFocus() || !lastFocusNode->IsFocusableNode()) {
458             TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Is not CurrentFocus Or not FocusableNode.");
459             break;
460         }
461         std::list<RefPtr<FocusHub>> focusNodesInner = lastFocusNode->GetChildren();
462         auto openBreak = false;
463         for (const auto& item : focusNodesInner) {
464             if (item->IsCurrentFocus()) {
465                 lastFocusNode = item;
466                 openBreak = true;
467             }
468         }
469         if (!openBreak) {
470             TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Is LastFocusNode, break.");
471             break;
472         }
473     }
474     if (lastFocusNode == nullptr) {
475         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "lastFocusNode is null.");
476         return nullptr;
477     }
478 
479     auto curFrameNode = lastFocusNode->GetFrameNode();
480     if (curFrameNode == nullptr) {
481         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "lastFocusNode-curFrameNode is null.");
482         return nullptr;
483     }
484     return curFrameNode;
485 }
486 
487 #ifdef WINDOW_SCENE_SUPPORTED
IsSCBWindowKeyboard(RefPtr<FrameNode> curFrameNode)488 void PipelineContext::IsSCBWindowKeyboard(RefPtr<FrameNode> curFrameNode)
489 {
490     // Frame other window to SCB window Or inSCB window changes,hide keyboard.
491     if ((windowFocus_.has_value() && windowFocus_.value()) ||
492         curFocusNodeId_ != curFrameNode->GetId()) {
493         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "SCB Windowfocus first, ready to hide keyboard.");
494         windowFocus_.reset();
495         curFocusNodeId_ = curFrameNode->GetId();
496         WindowSceneHelper::IsWindowSceneCloseKeyboard(curFrameNode);
497         return;
498     }
499     // In windowscene, focus change, need close keyboard.
500     if (needSoftKeyboard_.has_value() && !needSoftKeyboard_.value()) {
501         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "SCB WindowscenePage ready to close keyboard.");
502         WindowSceneHelper::IsCloseKeyboard(curFrameNode);
503         needSoftKeyboard_ = std::nullopt;
504     }
505 }
506 
IsNotSCBWindowKeyboard(RefPtr<FrameNode> curFrameNode)507 void PipelineContext::IsNotSCBWindowKeyboard(RefPtr<FrameNode> curFrameNode)
508 {
509     if ((windowFocus_.has_value() && windowFocus_.value()) ||
510         (windowShow_.has_value() && windowShow_.value())) {
511         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Normal Window focus first, set focusflag to window.");
512         windowFocus_.reset();
513         windowShow_.reset();
514         focusOnNodeCallback_();
515         preNodeId_ = curFrameNode->GetId();
516         FocusHub::IsCloseKeyboard(curFrameNode);
517         return;
518     }
519 
520     if (preNodeId_ != -1 && preNodeId_ == curFrameNode->GetId()) {
521         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FocusNode not change.");
522         return;
523     }
524     preNodeId_ = -1;
525 
526     if (needSoftKeyboard_.has_value() && !needSoftKeyboard_.value()) {
527         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Normal WindowPage ready to close keyboard.");
528         FocusHub::IsCloseKeyboard(curFrameNode);
529         needSoftKeyboard_ = std::nullopt;
530     }
531 }
532 #endif
533 
IsCloseSCBKeyboard()534 void PipelineContext::IsCloseSCBKeyboard()
535 {
536     auto container = Container::Current();
537     CHECK_NULL_VOID(container);
538     if (container->IsKeyboard()) {
539         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "focus in keyboard.");
540         return;
541     }
542 
543     RefPtr<FrameNode> curFrameNode = HandleFocusNode();
544     if (curFrameNode == nullptr) {
545         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "curFrameNode null.");
546         return;
547     }
548     TAG_LOGD(AceLogTag::ACE_KEYBOARD, "LastFocusNode,(%{public}s/%{public}d).",
549         curFrameNode->GetTag().c_str(), curFrameNode->GetId());
550 
551 #ifdef WINDOW_SCENE_SUPPORTED
552     auto isSystem = WindowSceneHelper::IsWindowScene(curFrameNode);
553     if (isSystem) {
554         IsSCBWindowKeyboard(curFrameNode);
555     } else {
556         IsNotSCBWindowKeyboard(curFrameNode);
557     }
558 #else
559     FocusHub::IsCloseKeyboard(curFrameNode);
560 #endif
561 }
562 
FlushVsync(uint64_t nanoTimestamp,uint32_t frameCount)563 void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount)
564 {
565     CHECK_RUN_ON(UI);
566     ACE_FUNCTION_TRACE();
567     window_->Lock();
568     auto recvTime = GetSysTimestamp();
569     static const std::string abilityName = AceApplicationInfo::GetInstance().GetProcessName().empty()
570                                                ? AceApplicationInfo::GetInstance().GetPackageName()
571                                                : AceApplicationInfo::GetInstance().GetProcessName();
572     window_->RecordFrameTime(nanoTimestamp, abilityName);
573     FlushFrameTrace();
574     resampleTimeStamp_ = nanoTimestamp - window_->GetVSyncPeriod() + ONE_MS_IN_NS;
575 #ifdef UICAST_COMPONENT_SUPPORTED
576     do {
577         auto container = Container::Current();
578         CHECK_NULL_BREAK(container);
579         auto distributedUI = container->GetDistributedUI();
580         CHECK_NULL_BREAK(distributedUI);
581         distributedUI->ApplyOneUpdate();
582     } while (false);
583 #endif
584     ProcessDelayTasks();
585     DispatchDisplaySync(nanoTimestamp);
586     FlushAnimation(nanoTimestamp);
587     SetVsyncTime(nanoTimestamp);
588     bool hasRunningAnimation = window_->FlushAnimation(nanoTimestamp);
589     FlushTouchEvents();
590     FlushBuild();
591     if (isFormRender_ && drawDelegate_ && rootNode_) {
592         auto renderContext = AceType::DynamicCast<NG::RenderContext>(rootNode_->GetRenderContext());
593         drawDelegate_->DrawRSFrame(renderContext);
594         drawDelegate_ = nullptr;
595     }
596     if (!taskScheduler_->isEmpty()) {
597 #if !defined(PREVIEW)
598         LayoutInspector::SupportInspector();
599 #endif
600     }
601 
602     taskScheduler_->StartRecordFrameInfo(GetCurrentFrameInfo(recvTime, nanoTimestamp));
603     taskScheduler_->FlushTask();
604     taskScheduler_->FinishRecordFrameInfo();
605     FlushAnimationClosure();
606     TryCallNextFrameLayoutCallback();
607 
608 #ifdef UICAST_COMPONENT_SUPPORTED
609     do {
610         auto container = Container::Current();
611         CHECK_NULL_BREAK(container);
612         auto distributedUI = container->GetDistributedUI();
613         CHECK_NULL_BREAK(distributedUI);
614         distributedUI->OnTreeUpdate();
615     } while (false);
616 #endif
617 
618     if (hasRunningAnimation || window_->HasUIAnimation()) {
619         RequestFrame();
620     }
621     window_->FlushModifier();
622     FlushFrameRate();
623     if (dragWindowVisibleCallback_) {
624         dragWindowVisibleCallback_();
625         dragWindowVisibleCallback_ = nullptr;
626     }
627     FlushMessages();
628     InspectDrew();
629     if (!isFormRender_ && onShow_ && onFocus_) {
630         FlushFocus();
631     }
632     // Close input method in the SCB window.
633     IsCloseSCBKeyboard();
634     HandleOnAreaChangeEvent(nanoTimestamp);
635     HandleVisibleAreaChangeEvent();
636     if (isNeedFlushMouseEvent_) {
637         FlushMouseEvent();
638         isNeedFlushMouseEvent_ = false;
639     }
640     if (isNeedFlushAnimationStartTime_) {
641         window_->FlushAnimationStartTime(nanoTimestamp);
642         isNeedFlushAnimationStartTime_ = false;
643     }
644     needRenderNode_.clear();
645     taskScheduler_->FlushAfterRenderTask();
646     // Keep the call sent at the end of the function
647     if (FrameReport::GetInstance().GetEnable()) {
648         FrameReport::GetInstance().FlushEnd();
649     }
650     ResSchedReport::GetInstance().LoadPageEvent(ResDefine::LOAD_PAGE_COMPLETE_EVENT);
651     window_->Unlock();
652 }
653 
InspectDrew()654 void PipelineContext::InspectDrew()
655 {
656     CHECK_RUN_ON(UI);
657     if (!needRenderNode_.empty()) {
658         auto needRenderNode = std::move(needRenderNode_);
659         for (auto&& node : needRenderNode) {
660             if (node) {
661                 OnDrawCompleted(node->GetInspectorId()->c_str());
662             }
663         }
664     }
665 }
666 
ProcessDelayTasks()667 void PipelineContext::ProcessDelayTasks()
668 {
669     if (delayedTasks_.empty()) {
670         return;
671     }
672     auto currentTimeStamp = GetSysTimestamp();
673     auto delayedTasks = std::move(delayedTasks_);
674     auto result = std::remove_if(delayedTasks.begin(), delayedTasks.end(), [this, currentTimeStamp](const auto& task) {
675         if (task.timeStamp + static_cast<int64_t>(task.time) * MILLISECONDS_TO_NANOSECONDS > currentTimeStamp) {
676             delayedTasks_.emplace_back(task);
677             return true;
678         }
679         return false;
680     });
681     delayedTasks.erase(result, delayedTasks.end());
682     std::for_each(delayedTasks.begin(), delayedTasks.end(), [this](auto& delayedTask) {
683         if (delayedTask.task) {
684             delayedTask.task();
685         }
686     });
687 }
688 
FlushFrameTrace()689 void PipelineContext::FlushFrameTrace()
690 {
691     if (FrameReport::GetInstance().GetEnable()) {
692         FrameReport::GetInstance().FlushBegin();
693     }
694 }
695 
DispatchDisplaySync(uint64_t nanoTimestamp)696 void PipelineContext::DispatchDisplaySync(uint64_t nanoTimestamp)
697 {
698     CHECK_RUN_ON(UI);
699     ACE_FUNCTION_TRACE();
700 
701     GetOrCreateUIDisplaySyncManager()->SetRefreshRateMode(window_->GetCurrentRefreshRateMode());
702     GetOrCreateUIDisplaySyncManager()->SetVsyncPeriod(window_->GetVSyncPeriod());
703 
704     if (FrameReport::GetInstance().GetEnable()) {
705         FrameReport::GetInstance().BeginFlushAnimation();
706     }
707 
708     scheduleTasks_.clear();
709     GetOrCreateUIDisplaySyncManager()->DispatchFunc(nanoTimestamp);
710 
711     if (FrameReport::GetInstance().GetEnable()) {
712         FrameReport::GetInstance().EndFlushAnimation();
713     }
714 
715     int32_t displaySyncRate = GetOrCreateUIDisplaySyncManager()->GetDisplaySyncRate();
716     frameRateManager_->SetDisplaySyncRate(displaySyncRate);
717 }
718 
FlushAnimation(uint64_t nanoTimestamp)719 void PipelineContext::FlushAnimation(uint64_t nanoTimestamp)
720 {
721     CHECK_RUN_ON(UI);
722     ACE_FUNCTION_TRACE();
723     if (scheduleTasks_.empty()) {
724         return;
725     }
726 }
727 
FlushMessages()728 void PipelineContext::FlushMessages()
729 {
730     ACE_FUNCTION_TRACE();
731     window_->FlushTasks();
732 }
733 
FlushUITasks()734 void PipelineContext::FlushUITasks()
735 {
736     window_->Lock();
737     taskScheduler_->FlushTask();
738     window_->Unlock();
739 }
740 
SetNeedRenderNode(const RefPtr<FrameNode> & node)741 void PipelineContext::SetNeedRenderNode(const RefPtr<FrameNode>& node)
742 {
743     CHECK_RUN_ON(UI);
744     needRenderNode_.insert(node);
745 }
746 
FlushFocus()747 void PipelineContext::FlushFocus()
748 {
749     CHECK_RUN_ON(UI);
750     ACE_FUNCTION_TRACK();
751     ACE_FUNCTION_TRACE();
752 
753     auto defaultFocusNode = dirtyDefaultFocusNode_.Upgrade();
754     if (!defaultFocusNode) {
755         dirtyDefaultFocusNode_.Reset();
756     } else {
757         auto focusNodeHub = defaultFocusNode->GetFocusHub();
758         if (focusNodeHub) {
759             RequestDefaultFocus(focusNodeHub);
760         }
761         dirtyFocusNode_.Reset();
762         dirtyFocusScope_.Reset();
763         dirtyDefaultFocusNode_.Reset();
764     }
765     auto requestFocusNode = dirtyRequestFocusNode_.Upgrade();
766     if (!requestFocusNode) {
767         dirtyRequestFocusNode_.Reset();
768     } else {
769         auto focusNodeHub = requestFocusNode->GetFocusHub();
770         if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
771             TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus by id on node: %{public}s/%{public}d return false",
772                 requestFocusNode->GetTag().c_str(), requestFocusNode->GetId());
773         }
774         dirtyFocusNode_.Reset();
775         dirtyFocusScope_.Reset();
776         dirtyDefaultFocusNode_.Reset();
777         dirtyRequestFocusNode_.Reset();
778         return;
779     }
780 
781     auto focusNode = dirtyFocusNode_.Upgrade();
782     if (!focusNode || focusNode->GetFocusType() != FocusType::NODE) {
783         dirtyFocusNode_.Reset();
784     } else {
785         auto focusNodeHub = focusNode->GetFocusHub();
786         if (focusNodeHub && !focusNodeHub->RequestFocusImmediately()) {
787             TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus on node: %{public}s/%{public}d return false",
788                 focusNode->GetTag().c_str(), focusNode->GetId());
789         }
790         dirtyFocusNode_.Reset();
791         dirtyFocusScope_.Reset();
792         dirtyDefaultFocusNode_.Reset();
793         dirtyRequestFocusNode_.Reset();
794         return;
795     }
796     auto focusScope = dirtyFocusScope_.Upgrade();
797     if (!focusScope || focusScope->GetFocusType() != FocusType::SCOPE) {
798         dirtyFocusScope_.Reset();
799     } else {
800         auto focusScopeHub = focusScope->GetFocusHub();
801         if (focusScopeHub && !focusScopeHub->RequestFocusImmediately()) {
802             TAG_LOGI(AceLogTag::ACE_FOCUS, "Request focus on scope: %{public}s/%{public}d return false",
803                 focusScope->GetTag().c_str(), focusScope->GetId());
804         }
805         dirtyFocusNode_.Reset();
806         dirtyFocusScope_.Reset();
807         dirtyDefaultFocusNode_.Reset();
808         dirtyRequestFocusNode_.Reset();
809         return;
810     }
811     auto rootFocusHub = rootNode_ ? rootNode_->GetFocusHub() : nullptr;
812     if (rootFocusHub && !rootFocusHub->IsCurrentFocus()) {
813         auto curMainView = FocusHub::GetCurrentMainView();
814         if (curMainView && curMainView->GetIsViewHasFocused()) {
815             rootFocusHub->RequestFocusImmediately();
816         }
817     }
818 }
819 
FlushPipelineImmediately()820 void PipelineContext::FlushPipelineImmediately()
821 {
822     CHECK_RUN_ON(UI);
823     ACE_FUNCTION_TRACE();
824     FlushPipelineWithoutAnimation();
825 }
826 
FlushPipelineWithoutAnimation()827 void PipelineContext::FlushPipelineWithoutAnimation()
828 {
829     ACE_FUNCTION_TRACE();
830     window_->Lock();
831     FlushBuild();
832     FlushTouchEvents();
833     taskScheduler_->FlushTask();
834     FlushAnimationClosure();
835     FlushMessages();
836     FlushFocus();
837     window_->Unlock();
838 }
839 
FlushFrameRate()840 void PipelineContext::FlushFrameRate()
841 {
842     frameRateManager_->SetAnimateRate(window_->GetAnimateExpectedRate());
843     if (frameRateManager_->IsRateChanged()) {
844         auto rate = frameRateManager_->GetExpectedRate();
845         ACE_SCOPED_TRACE("FlushFrameRate Expected frameRate = %d", rate);
846         window_->FlushFrameRate(rate);
847         frameRateManager_->SetIsRateChanged(false);
848     }
849 }
850 
FlushBuild()851 void PipelineContext::FlushBuild()
852 {
853     isRebuildFinished_ = false;
854     FlushDirtyNodeUpdate();
855     isRebuildFinished_ = true;
856     FlushBuildFinishCallbacks();
857 }
858 
AddAnimationClosure(std::function<void ()> && animation)859 void PipelineContext::AddAnimationClosure(std::function<void()>&& animation)
860 {
861     animationClosuresList_.emplace_back(std::move(animation));
862 }
863 
FlushAnimationClosure()864 void PipelineContext::FlushAnimationClosure()
865 {
866     if (animationClosuresList_.empty()) {
867         return;
868     }
869     window_->Lock();
870     taskScheduler_->FlushTask();
871 
872     decltype(animationClosuresList_) temp(std::move(animationClosuresList_));
873     auto scheduler = std::move(taskScheduler_);
874     taskScheduler_ = std::make_unique<UITaskScheduler>();
875     for (const auto& animation : temp) {
876         animation();
877         taskScheduler_->CleanUp();
878     }
879     taskScheduler_ = std::move(scheduler);
880     window_->Unlock();
881 }
882 
FlushBuildFinishCallbacks()883 void PipelineContext::FlushBuildFinishCallbacks()
884 {
885     decltype(buildFinishCallbacks_) buildFinishCallbacks(std::move(buildFinishCallbacks_));
886     for (const auto& func : buildFinishCallbacks) {
887         if (func) {
888             func();
889         }
890     }
891 }
892 
RegisterRootEvent()893 void PipelineContext::RegisterRootEvent()
894 {
895     if (!IsFormRender()) {
896         return;
897     }
898 
899     // To avoid conflicts between longPress and click events on the card,
900     // use an empty longPress event placeholder in the EtsCard scenario
901     auto hub = rootNode_->GetOrCreateGestureEventHub();
902     CHECK_NULL_VOID(hub);
903     auto event = [](const GestureEvent& info) mutable {};
904     auto longPress = AceType::MakeRefPtr<NG::LongPressEvent>(std::move(event));
905     hub->SetLongPressEvent(longPress, false, true);
906 }
907 
SetupRootElement()908 void PipelineContext::SetupRootElement()
909 {
910     CHECK_RUN_ON(UI);
911     rootNode_ = FrameNode::CreateFrameNodeWithTree(
912         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
913     rootNode_->SetHostRootId(GetInstanceId());
914     rootNode_->SetHostPageId(-1);
915     rootNode_->SetActive(true);
916     RegisterRootEvent();
917     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
918     MeasureProperty layoutConstraint;
919     layoutConstraint.selfIdealSize = idealSize;
920     layoutConstraint.maxSize = idealSize;
921     rootNode_->UpdateLayoutConstraint(layoutConstraint);
922     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
923     rootFocusHub->SetFocusType(FocusType::SCOPE);
924     rootFocusHub->SetFocusable(true);
925     window_->SetRootFrameNode(rootNode_);
926     rootNode_->AttachToMainTree();
927 
928     auto stageNode = FrameNode::CreateFrameNode(
929         V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<StagePattern>());
930     auto atomicService = installationFree_ ? AppBarView::Create(stageNode) : nullptr;
931     auto container = Container::Current();
932     if (container && atomicService) {
933         auto appBar = Referenced::MakeRefPtr<AppBarView>(atomicService);
934         appBar->iniBehavior();
935         container->SetAppBar(appBar);
936     }
937     if (windowModal_ == WindowModal::CONTAINER_MODAL) {
938         MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
939         rootNode_->AddChild(
940             ContainerModalViewFactory::GetView(atomicService ? atomicService : stageNode, maximizeMode));
941     } else {
942         rootNode_->AddChild(atomicService ? atomicService : stageNode);
943     }
944 #ifdef ENABLE_ROSEN_BACKEND
945     if (!IsJsCard() && !isFormRender_) {
946         auto window = GetWindow();
947         if (window) {
948             auto rsUIDirector = window->GetRSUIDirector();
949             if (rsUIDirector) {
950                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
951             }
952         }
953     }
954 #endif
955 #ifdef WINDOW_SCENE_SUPPORTED
956     uiExtensionManager_ = MakeRefPtr<UIExtensionManager>();
957 #endif
958     stageManager_ = MakeRefPtr<StageManager>(stageNode);
959     overlayManager_ = MakeRefPtr<OverlayManager>(
960         DynamicCast<FrameNode>(installationFree_ ? stageNode->GetParent()->GetParent() : stageNode->GetParent()));
961     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
962     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
963     postEventManager_ = MakeRefPtr<PostEventManager>();
964     dragDropManager_ = MakeRefPtr<DragDropManager>();
965     sharedTransitionManager_ = MakeRefPtr<SharedOverlayManager>(
966         DynamicCast<FrameNode>(installationFree_ ? stageNode->GetParent()->GetParent() : stageNode->GetParent()));
967 
968     OnAreaChangedFunc onAreaChangedFunc = [weakOverlayManger = AceType::WeakClaim(AceType::RawPtr(overlayManager_))](
969                                               const RectF& /* oldRect */, const OffsetF& /* oldOrigin */,
970                                               const RectF& /* rect */, const OffsetF& /* origin */) {
971         auto overlay = weakOverlayManger.Upgrade();
972         CHECK_NULL_VOID(overlay);
973         overlay->HideAllMenus();
974         SubwindowManager::GetInstance()->HideMenuNG(false);
975         overlay->HideCustomPopups();
976     };
977     rootNode_->SetOnAreaChangeCallback(std::move(onAreaChangedFunc));
978     AddOnAreaChangeNode(rootNode_->GetId());
979 }
980 
SetupSubRootElement()981 void PipelineContext::SetupSubRootElement()
982 {
983     CHECK_RUN_ON(UI);
984     appBgColor_ = Color::TRANSPARENT;
985     rootNode_ = FrameNode::CreateFrameNodeWithTree(
986         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
987     rootNode_->SetHostRootId(GetInstanceId());
988     rootNode_->SetHostPageId(-1);
989     rootNode_->SetActive(true);
990     CalcSize idealSize { CalcLength(rootWidth_), CalcLength(rootHeight_) };
991     MeasureProperty layoutConstraint;
992     layoutConstraint.selfIdealSize = idealSize;
993     layoutConstraint.maxSize = idealSize;
994     rootNode_->UpdateLayoutConstraint(layoutConstraint);
995     auto rootFocusHub = rootNode_->GetOrCreateFocusHub();
996     rootFocusHub->SetFocusType(FocusType::SCOPE);
997     rootFocusHub->SetFocusable(true);
998     window_->SetRootFrameNode(rootNode_);
999     rootNode_->AttachToMainTree();
1000 
1001 #ifdef ENABLE_ROSEN_BACKEND
1002     if (!IsJsCard()) {
1003         auto window = GetWindow();
1004         if (window) {
1005             auto rsUIDirector = window->GetRSUIDirector();
1006             if (rsUIDirector) {
1007                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
1008             }
1009         }
1010     }
1011 #endif
1012 #ifdef WINDOW_SCENE_SUPPORTED
1013     uiExtensionManager_ = MakeRefPtr<UIExtensionManager>();
1014 #endif
1015     // the subwindow for overlay not need stage
1016     stageManager_ = MakeRefPtr<StageManager>(nullptr);
1017     overlayManager_ = MakeRefPtr<OverlayManager>(rootNode_);
1018     fullScreenManager_ = MakeRefPtr<FullScreenManager>(rootNode_);
1019     selectOverlayManager_ = MakeRefPtr<SelectOverlayManager>(rootNode_);
1020     dragDropManager_ = MakeRefPtr<DragDropManager>();
1021     postEventManager_ = MakeRefPtr<PostEventManager>();
1022 }
1023 
GetStageManager()1024 const RefPtr<StageManager>& PipelineContext::GetStageManager()
1025 {
1026     return stageManager_;
1027 }
1028 
GetDragDropManager()1029 const RefPtr<DragDropManager>& PipelineContext::GetDragDropManager()
1030 {
1031     return dragDropManager_;
1032 }
1033 
GetSelectOverlayManager()1034 const RefPtr<SelectOverlayManager>& PipelineContext::GetSelectOverlayManager()
1035 {
1036     return selectOverlayManager_;
1037 }
1038 
GetOverlayManager()1039 const RefPtr<OverlayManager>& PipelineContext::GetOverlayManager()
1040 {
1041     return overlayManager_;
1042 }
1043 
GetFullScreenManager()1044 const RefPtr<FullScreenManager>& PipelineContext::GetFullScreenManager()
1045 {
1046     return fullScreenManager_;
1047 }
1048 
OnSurfaceChanged(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1049 void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type,
1050     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1051 {
1052     CHECK_RUN_ON(UI);
1053     ACE_FUNCTION_TRACE();
1054     if (NearEqual(rootWidth_, width) && NearEqual(rootHeight_, height) &&
1055         type == WindowSizeChangeReason::CUSTOM_ANIMATION && !isDensityChanged_) {
1056         TryCallNextFrameLayoutCallback();
1057         return;
1058     }
1059     ExecuteSurfaceChangedCallbacks(width, height, type);
1060     // TODO: add adjust for textFieldManager when ime is show.
1061     auto callback = [weakFrontend = weakFrontend_, width, height]() {
1062         auto frontend = weakFrontend.Upgrade();
1063         if (frontend) {
1064             frontend->OnSurfaceChanged(width, height);
1065         }
1066     };
1067     auto container = Container::Current();
1068     if (!container) {
1069         return;
1070     }
1071     if (container->IsUseStageModel()) {
1072         callback();
1073         FlushBuild();
1074     } else {
1075         taskExecutor_->PostTask(callback, TaskExecutor::TaskType::JS);
1076     }
1077 
1078     FlushWindowSizeChangeCallback(width, height, type);
1079 
1080 #ifdef ENABLE_ROSEN_BACKEND
1081     StartWindowSizeChangeAnimate(width, height, type, rsTransaction);
1082 #else
1083     SetRootRect(width, height, 0.0);
1084 #endif
1085 }
1086 
OnLayoutCompleted(const std::string & componentId)1087 void PipelineContext::OnLayoutCompleted(const std::string& componentId)
1088 {
1089     CHECK_RUN_ON(UI);
1090     auto frontend = weakFrontend_.Upgrade();
1091     if (frontend) {
1092         frontend->OnLayoutCompleted(componentId);
1093     }
1094 }
1095 
OnDrawCompleted(const std::string & componentId)1096 void PipelineContext::OnDrawCompleted(const std::string& componentId)
1097 {
1098     CHECK_RUN_ON(UI);
1099     auto frontend = weakFrontend_.Upgrade();
1100     if (frontend) {
1101         frontend->OnDrawCompleted(componentId);
1102     }
1103 }
1104 
ExecuteSurfaceChangedCallbacks(int32_t newWidth,int32_t newHeight,WindowSizeChangeReason type)1105 void PipelineContext::ExecuteSurfaceChangedCallbacks(int32_t newWidth, int32_t newHeight, WindowSizeChangeReason type)
1106 {
1107     for (auto&& [id, callback] : surfaceChangedCallbackMap_) {
1108         if (callback) {
1109             callback(newWidth, newHeight, rootWidth_, rootHeight_, type);
1110         }
1111     }
1112 }
1113 
OnSurfacePositionChanged(int32_t posX,int32_t posY)1114 void PipelineContext::OnSurfacePositionChanged(int32_t posX, int32_t posY)
1115 {
1116     for (auto&& [id, callback] : surfacePositionChangedCallbackMap_) {
1117         if (callback) {
1118             callback(posX, posY);
1119         }
1120     }
1121 }
1122 
OnFoldStatusChange(FoldStatus foldStatus)1123 void PipelineContext::OnFoldStatusChange(FoldStatus foldStatus)
1124 {
1125     for (auto&& [id, callback] : foldStatusChangedCallbackMap_) {
1126         if (callback) {
1127             callback(foldStatus);
1128         }
1129     }
1130 }
1131 
OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)1132 void PipelineContext::OnFoldDisplayModeChange(FoldDisplayMode foldDisplayMode)
1133 {
1134     for (auto&& [id, callback] : foldDisplayModeChangedCallbackMap_) {
1135         if (callback) {
1136             callback(foldDisplayMode);
1137         }
1138     }
1139 }
1140 
StartWindowSizeChangeAnimate(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1141 void PipelineContext::StartWindowSizeChangeAnimate(int32_t width, int32_t height, WindowSizeChangeReason type,
1142     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1143 {
1144     static const bool IsWindowSizeAnimationEnabled = SystemProperties::IsWindowSizeAnimationEnabled();
1145     if (!IsWindowSizeAnimationEnabled) {
1146         SetRootRect(width, height, 0.0);
1147         return;
1148     }
1149     switch (type) {
1150         case WindowSizeChangeReason::FULL_TO_SPLIT:
1151         case WindowSizeChangeReason::FULL_TO_FLOATING: {
1152             StartFullToMultWindowAnimation(width, height, type, rsTransaction);
1153             break;
1154         }
1155         case WindowSizeChangeReason::RECOVER:
1156         case WindowSizeChangeReason::MAXIMIZE: {
1157             StartWindowMaximizeAnimation(width, height, rsTransaction);
1158             break;
1159         }
1160         case WindowSizeChangeReason::ROTATION: {
1161             safeAreaManager_->UpdateKeyboardOffset(0.0);
1162             SetRootRect(width, height, 0.0);
1163             FlushUITasks();
1164             if (textFieldManager_) {
1165                 DynamicCast<TextFieldManagerNG>(textFieldManager_)->ScrollTextFieldToSafeArea();
1166             }
1167             FlushUITasks();
1168             break;
1169         }
1170         case WindowSizeChangeReason::DRAG_START:
1171         case WindowSizeChangeReason::DRAG:
1172         case WindowSizeChangeReason::DRAG_END:
1173         case WindowSizeChangeReason::RESIZE:
1174         case WindowSizeChangeReason::UNDEFINED:
1175         default: {
1176             SetRootRect(width, height, 0.0f);
1177         }
1178     }
1179 }
1180 
StartWindowMaximizeAnimation(int32_t width,int32_t height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1181 void PipelineContext::StartWindowMaximizeAnimation(
1182     int32_t width, int32_t height, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1183 {
1184     LOGI("Root node start RECOVER/MAXIMIZE animation, width = %{public}d, height = %{public}d", width, height);
1185 #ifdef ENABLE_ROSEN_BACKEND
1186     if (rsTransaction) {
1187         FlushMessages();
1188         rsTransaction->Begin();
1189     }
1190 #endif
1191     AnimationOption option;
1192     int32_t duration = 400;
1193     MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode();
1194     if (maximizeMode == MaximizeMode::MODE_FULL_FILL || maximizeMode == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
1195         int32_t preWidth = GetRootRect().Width();
1196         int32_t preHeight = GetRootRect().Height();
1197         if (width > preWidth && height > preHeight) {
1198             duration = 0;
1199         }
1200     }
1201     option.SetDuration(duration);
1202     auto curve = Curves::EASE_OUT;
1203     option.SetCurve(curve);
1204     auto weak = WeakClaim(this);
1205     Animate(option, curve, [width, height, weak]() {
1206         auto pipeline = weak.Upgrade();
1207         CHECK_NULL_VOID(pipeline);
1208         pipeline->SetRootRect(width, height, 0.0);
1209         pipeline->FlushUITasks();
1210     });
1211 #ifdef ENABLE_ROSEN_BACKEND
1212     if (rsTransaction) {
1213         rsTransaction->Commit();
1214     }
1215 #endif
1216 }
1217 
StartFullToMultWindowAnimation(int32_t width,int32_t height,WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1218 void PipelineContext::StartFullToMultWindowAnimation(int32_t width, int32_t height, WindowSizeChangeReason type,
1219     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1220 {
1221     LOGI("Root node start multiple window animation, type = %{public}d, width = %{public}d, height = %{public}d", type,
1222         width, height);
1223 #ifdef ENABLE_ROSEN_BACKEND
1224     if (rsTransaction) {
1225         FlushMessages();
1226         rsTransaction->Begin();
1227     }
1228 #endif
1229     float response = 0.5f;
1230     float dampingFraction = 1.0f;
1231     AnimationOption option;
1232     if (type == WindowSizeChangeReason::FULL_TO_FLOATING) {
1233         response = 0.45f;
1234         dampingFraction = 0.75f;
1235     }
1236     auto springMotion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingFraction, 0);
1237     option.SetCurve(springMotion);
1238     auto weak = WeakClaim(this);
1239     Animate(option, springMotion, [width, height, weak]() {
1240         auto pipeline = weak.Upgrade();
1241         CHECK_NULL_VOID(pipeline);
1242         pipeline->SetRootRect(width, height, 0.0);
1243         pipeline->FlushUITasks();
1244     });
1245 #ifdef ENABLE_ROSEN_BACKEND
1246     if (rsTransaction) {
1247         rsTransaction->Commit();
1248     }
1249 #endif
1250 }
1251 
SetRootRect(double width,double height,double offset)1252 void PipelineContext::SetRootRect(double width, double height, double offset)
1253 {
1254     CHECK_RUN_ON(UI);
1255     UpdateRootSizeAndScale(width, height);
1256     CHECK_NULL_VOID(rootNode_);
1257     if (Container::CurrentId() < MIN_SUBCONTAINER_ID) {
1258         ScreenSystemManager::GetInstance().SetWindowInfo(rootWidth_, density_, dipScale_);
1259         ScreenSystemManager::GetInstance().OnSurfaceChanged(width);
1260     }
1261     SizeF sizeF { static_cast<float>(width), static_cast<float>(height) };
1262     if (rootNode_->GetGeometryNode()->GetFrameSize() != sizeF || rootNode_->IsLayoutDirtyMarked()) {
1263         CalcSize idealSize { CalcLength(width), CalcLength(height) };
1264         MeasureProperty layoutConstraint;
1265         layoutConstraint.selfIdealSize = idealSize;
1266         layoutConstraint.maxSize = idealSize;
1267         rootNode_->UpdateLayoutConstraint(layoutConstraint);
1268         // reset parentLayoutConstraint to update itself when next measure task
1269         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1270         rootNode_->MarkDirtyNode();
1271     }
1272     if (rootNode_->GetGeometryNode()->GetFrameOffset().GetY() != offset) {
1273         OffsetF newOffset = rootNode_->GetGeometryNode()->GetFrameOffset();
1274         newOffset.SetY(static_cast<float>(offset));
1275         rootNode_->GetGeometryNode()->SetMarginFrameOffset(newOffset);
1276         auto rootContext = rootNode_->GetRenderContext();
1277         rootContext->SyncGeometryProperties(RawPtr(rootNode_->GetGeometryNode()));
1278         RequestFrame();
1279     }
1280     if (isDensityChanged_) {
1281         rootNode_->GetGeometryNode()->ResetParentLayoutConstraint();
1282         rootNode_->MarkForceMeasure();
1283         isDensityChanged_ = false;
1284     }
1285 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1286     // For cross-platform build, flush tasks when first resize, speed up for fisrt frame.
1287     if (window_ && rootNode_->GetRenderContext() && !NearZero(width) && !NearZero(height)) {
1288         rootNode_->GetRenderContext()->SetBounds(0.0, 0.0, width, height);
1289         window_->FlushTasks();
1290         FlushVsync(GetTimeFromExternalTimer(), 0);
1291     }
1292 #endif
1293 }
1294 
UpdateSystemSafeArea(const SafeAreaInsets & systemSafeArea)1295 void PipelineContext::UpdateSystemSafeArea(const SafeAreaInsets& systemSafeArea)
1296 {
1297     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1298     if (safeAreaManager_->UpdateSystemSafeArea(systemSafeArea)) {
1299         AnimateOnSafeAreaUpdate();
1300     }
1301 }
1302 
UpdateCutoutSafeArea(const SafeAreaInsets & cutoutSafeArea)1303 void PipelineContext::UpdateCutoutSafeArea(const SafeAreaInsets& cutoutSafeArea)
1304 {
1305     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1306     if (safeAreaManager_->UpdateCutoutSafeArea(cutoutSafeArea)) {
1307         AnimateOnSafeAreaUpdate();
1308     }
1309 }
1310 
UpdateNavSafeArea(const SafeAreaInsets & navSafeArea)1311 void PipelineContext::UpdateNavSafeArea(const SafeAreaInsets& navSafeArea)
1312 {
1313     CHECK_NULL_VOID(minPlatformVersion_ >= PLATFORM_VERSION_TEN);
1314     if (safeAreaManager_->UpdateNavArea(navSafeArea)) {
1315         AnimateOnSafeAreaUpdate();
1316     }
1317 }
1318 
UpdateOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)1319 void PipelineContext::UpdateOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
1320 {
1321 #ifdef WINDOW_SCENE_SUPPORTED
1322     CHECK_NULL_VOID(uiExtensionManager_);
1323     uiExtensionManager_->TransferOriginAvoidArea(avoidArea, type);
1324 #endif
1325 }
1326 
SetEnableKeyBoardAvoidMode(bool value)1327 void PipelineContext::SetEnableKeyBoardAvoidMode(bool value)
1328 {
1329     safeAreaManager_->SetKeyBoardAvoidMode(value);
1330 }
1331 
IsEnableKeyBoardAvoidMode()1332 bool PipelineContext::IsEnableKeyBoardAvoidMode()
1333 {
1334     return safeAreaManager_->KeyboardSafeAreaEnabled();
1335 }
1336 
SetIgnoreViewSafeArea(bool value)1337 void PipelineContext::SetIgnoreViewSafeArea(bool value)
1338 {
1339     if (safeAreaManager_->SetIgnoreSafeArea(value)) {
1340         SyncSafeArea();
1341     }
1342 }
1343 
SetIsLayoutFullScreen(bool value)1344 void PipelineContext::SetIsLayoutFullScreen(bool value)
1345 {
1346     if (safeAreaManager_->SetIsFullScreen(value)) {
1347         SyncSafeArea();
1348     }
1349 }
1350 
SetIsNeedAvoidWindow(bool value)1351 void PipelineContext::SetIsNeedAvoidWindow(bool value)
1352 {
1353     if (safeAreaManager_->SetIsNeedAvoidWindow(value)) {
1354         SyncSafeArea();
1355     }
1356 }
1357 
GetSafeArea() const1358 PipelineBase::SafeAreaInsets PipelineContext::GetSafeArea() const
1359 {
1360     return safeAreaManager_->GetSafeArea();
1361 }
1362 
SyncSafeArea(bool onKeyboard)1363 void PipelineContext::SyncSafeArea(bool onKeyboard)
1364 {
1365     CHECK_NULL_VOID(stageManager_);
1366     auto page = stageManager_->GetLastPage();
1367     if (page) {
1368         page->MarkDirtyNode(onKeyboard && !safeAreaManager_->KeyboardSafeAreaEnabled() ? PROPERTY_UPDATE_LAYOUT
1369                                                                                        : PROPERTY_UPDATE_MEASURE);
1370     }
1371     if (overlayManager_) {
1372         overlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1373     }
1374     if (selectOverlayManager_) {
1375         selectOverlayManager_->MarkDirty(PROPERTY_UPDATE_MEASURE);
1376     }
1377     auto&& restoreNodes = safeAreaManager_->GetGeoRestoreNodes();
1378     for (auto&& wk : restoreNodes) {
1379         auto node = wk.Upgrade();
1380         if (node) {
1381             node->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
1382         }
1383     }
1384 }
1385 
OnVirtualKeyboardHeightChange(float keyboardHeight,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1386 void PipelineContext::OnVirtualKeyboardHeightChange(
1387     float keyboardHeight, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1388 {
1389     CHECK_RUN_ON(UI);
1390     // prevent repeated trigger with same keyboardHeight
1391     if (NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length())) {
1392         return;
1393     }
1394 
1395     ACE_FUNCTION_TRACE();
1396 #ifdef ENABLE_ROSEN_BACKEND
1397     if (rsTransaction) {
1398         FlushMessages();
1399         rsTransaction->Begin();
1400     }
1401 #endif
1402 
1403     auto func = [this, keyboardHeight]() mutable {
1404         safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1405         if (keyboardHeight > 0) {
1406             // add height of navigation bar
1407             keyboardHeight += safeAreaManager_->GetSystemSafeArea().bottom_.Length();
1408         }
1409         float positionY = 0.0f;
1410         auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1411         float height = 0.0f;
1412         if (manager) {
1413             height = manager->GetHeight();
1414             positionY = static_cast<float>(manager->GetClickPosition().GetY());
1415         }
1416         SizeF rootSize { static_cast<float>(rootWidth_), static_cast<float>(rootHeight_) };
1417         float keyboardOffset = safeAreaManager_->GetKeyboardOffset();
1418         float positionYWithOffset = positionY - keyboardOffset;
1419         float offsetFix = (rootSize.Height() - positionYWithOffset) > 100.0f
1420                               ? keyboardHeight - (rootSize.Height() - positionYWithOffset) / 2.0f
1421                               : keyboardHeight;
1422 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
1423         if (offsetFix > 0.0f && positionYWithOffset < offsetFix) {
1424             offsetFix = keyboardHeight - (rootSize.Height() - positionYWithOffset - height);
1425         }
1426 #endif
1427         if (NearZero(keyboardHeight)) {
1428             safeAreaManager_->UpdateKeyboardOffset(0.0f);
1429         } else if (LessOrEqual(rootSize.Height() - positionYWithOffset - height, height) &&
1430                    LessOrEqual(rootSize.Height() - positionYWithOffset, keyboardHeight)) {
1431             safeAreaManager_->UpdateKeyboardOffset(-keyboardHeight);
1432         } else if (positionYWithOffset + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
1433             safeAreaManager_->UpdateKeyboardOffset(-offsetFix);
1434         } else if ((positionYWithOffset + height > rootSize.Height() - keyboardHeight &&
1435                        positionYWithOffset < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
1436                    NearZero(rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
1437             safeAreaManager_->UpdateKeyboardOffset(-height - offsetFix / 2.0f);
1438         } else {
1439             safeAreaManager_->UpdateKeyboardOffset(0.0f);
1440         }
1441         SyncSafeArea(true);
1442         // layout immediately
1443         FlushUITasks();
1444 
1445         CHECK_NULL_VOID(manager);
1446         manager->ScrollTextFieldToSafeArea();
1447         FlushUITasks();
1448     };
1449 
1450     AnimationOption option = AnimationUtil::CreateKeyboardAnimationOption(keyboardAnimationConfig_, keyboardHeight);
1451     Animate(option, option.GetCurve(), func);
1452 
1453 #ifdef ENABLE_ROSEN_BACKEND
1454     if (rsTransaction) {
1455         rsTransaction->Commit();
1456     }
1457 #endif
1458 }
1459 
OnVirtualKeyboardHeightChange(float keyboardHeight,double positionY,double height,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)1460 void PipelineContext::OnVirtualKeyboardHeightChange(
1461     float keyboardHeight, double positionY, double height, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
1462 {
1463     CHECK_RUN_ON(UI);
1464     // prevent repeated trigger with same keyboardHeight
1465     CHECK_NULL_VOID(safeAreaManager_);
1466     auto manager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1467     CHECK_NULL_VOID(manager);
1468     if (NearEqual(keyboardHeight, safeAreaManager_->GetKeyboardInset().Length()) &&
1469         prevKeyboardAvoidMode_ == safeAreaManager_->KeyboardSafeAreaEnabled() && manager->PrevHasTextFieldPattern()) {
1470         return;
1471     }
1472     manager->UpdatePrevHasTextFieldPattern();
1473     prevKeyboardAvoidMode_ = safeAreaManager_->KeyboardSafeAreaEnabled();
1474 
1475     ACE_FUNCTION_TRACE();
1476 #ifdef ENABLE_ROSEN_BACKEND
1477     if (rsTransaction) {
1478         FlushMessages();
1479         rsTransaction->Begin();
1480     }
1481 #endif
1482 
1483     auto weak = WeakClaim(this);
1484     auto func = [weak, keyboardHeight, positionY, height, manager]() mutable {
1485         auto context = weak.Upgrade();
1486         CHECK_NULL_VOID(context);
1487         context->safeAreaManager_->UpdateKeyboardSafeArea(keyboardHeight);
1488         if (keyboardHeight > 0) {
1489             // add height of navigation bar
1490             keyboardHeight += context->safeAreaManager_->GetSystemSafeArea().bottom_.Length();
1491         }
1492 
1493         SizeF rootSize { static_cast<float>(context->rootWidth_), static_cast<float>(context->rootHeight_) };
1494         float keyboardOffset = context->safeAreaManager_->GetKeyboardOffset();
1495         float positionYWithOffset = positionY - keyboardOffset;
1496         if (rootSize.Height() - positionY - height < 0) {
1497             height = rootSize.Height() - positionY;
1498         }
1499         float offsetFix = (rootSize.Height() - positionY - height) < keyboardHeight
1500                               ? keyboardHeight - (rootSize.Height() - positionY - height)
1501                               : keyboardHeight;
1502         if (NearZero(keyboardHeight)) {
1503             context->safeAreaManager_->UpdateKeyboardOffset(0.0f);
1504         } else if (positionYWithOffset + height > (rootSize.Height() - keyboardHeight) && offsetFix > 0.0f) {
1505             context->safeAreaManager_->UpdateKeyboardOffset(-offsetFix);
1506         } else if (LessOrEqual(rootSize.Height() - positionYWithOffset - height, height) &&
1507                    LessOrEqual(rootSize.Height() - positionYWithOffset, keyboardHeight)) {
1508             context->safeAreaManager_->UpdateKeyboardOffset(-keyboardHeight);
1509         } else if ((positionYWithOffset + height > rootSize.Height() - keyboardHeight &&
1510                        positionYWithOffset < rootSize.Height() - keyboardHeight && height < keyboardHeight / 2.0f) &&
1511                    NearZero(context->rootNode_->GetGeometryNode()->GetFrameOffset().GetY())) {
1512             context->safeAreaManager_->UpdateKeyboardOffset(-height - offsetFix / 2.0f);
1513         } else {
1514             context->safeAreaManager_->UpdateKeyboardOffset(0.0f);
1515         }
1516         context->SyncSafeArea(true);
1517         // layout immediately
1518         context->FlushUITasks();
1519 
1520         manager->ScrollTextFieldToSafeArea();
1521         context->FlushUITasks();
1522     };
1523 
1524     AnimationOption option = AnimationUtil::CreateKeyboardAnimationOption(keyboardAnimationConfig_, keyboardHeight);
1525     Animate(option, option.GetCurve(), func);
1526 
1527 #ifdef ENABLE_ROSEN_BACKEND
1528     if (rsTransaction) {
1529         rsTransaction->Commit();
1530     }
1531 #endif
1532 }
1533 
OnBackPressed()1534 bool PipelineContext::OnBackPressed()
1535 {
1536     CHECK_RUN_ON(PLATFORM);
1537     auto frontend = weakFrontend_.Upgrade();
1538     if (!frontend) {
1539         // return back.
1540         return false;
1541     }
1542 
1543     // If the tag of the last child of the rootnode is video, exit full screen.
1544     if (fullScreenManager_->OnBackPressed()) {
1545         return true;
1546     }
1547 
1548     // if has sharedTransition, back press will stop the sharedTransition
1549     if (sharedTransitionManager_->OnBackPressed()) {
1550         return true;
1551     }
1552 
1553     // if has popup, back press would hide popup and not trigger page back
1554     auto hasOverlay = false;
1555     taskExecutor_->PostSyncTask(
1556         [weakOverlay = AceType::WeakClaim(AceType::RawPtr(overlayManager_)),
1557             weakSelectOverlay = AceType::WeakClaim(AceType::RawPtr(selectOverlayManager_)), &hasOverlay]() {
1558             // Destroy behaviour of Select Overlay shouble be adjusted.
1559             auto overlay = weakOverlay.Upgrade();
1560             CHECK_NULL_VOID(overlay);
1561             auto selectOverlay = weakSelectOverlay.Upgrade();
1562             CHECK_NULL_VOID(selectOverlay);
1563             hasOverlay = selectOverlay->ResetSelectionAndDestroySelectOverlay();
1564             hasOverlay |= overlay->RemoveOverlay(true);
1565         },
1566         TaskExecutor::TaskType::UI);
1567     if (hasOverlay) {
1568         return true;
1569     }
1570 
1571     auto textfieldManager = DynamicCast<TextFieldManagerNG>(PipelineBase::GetTextFieldManager());
1572     if (textfieldManager && textfieldManager->OnBackPressed()) {
1573         return true;
1574     }
1575 
1576     auto result = false;
1577     taskExecutor_->PostSyncTask(
1578         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), stageManager = stageManager_, &result]() {
1579             auto frontend = weakFrontend.Upgrade();
1580             if (!frontend) {
1581                 result = false;
1582                 return;
1583             }
1584             auto context = weakPipelineContext.Upgrade();
1585             if (!context) {
1586                 result = false;
1587                 return;
1588             }
1589             CHECK_NULL_VOID(stageManager);
1590             auto lastPage = stageManager->GetLastPage();
1591             CHECK_NULL_VOID(lastPage);
1592             auto navigationGroupNode =
1593                 AceType::DynamicCast<NavigationGroupNode>(context->FindNavigationNodeToHandleBack(lastPage));
1594             if (navigationGroupNode) {
1595                 result = true;
1596             }
1597         },
1598         TaskExecutor::TaskType::UI);
1599 
1600     if (result) {
1601         // user accept
1602         return true;
1603     }
1604 
1605     taskExecutor_->PostSyncTask(
1606         [weakFrontend = weakFrontend_, weakPipelineContext = WeakClaim(this), &result]() {
1607             auto frontend = weakFrontend.Upgrade();
1608             if (!frontend) {
1609                 result = false;
1610                 return;
1611             }
1612             result = frontend->OnBackPressed();
1613         },
1614         TaskExecutor::TaskType::JS);
1615 
1616     if (result) {
1617         // user accept
1618         return true;
1619     }
1620     return false;
1621 }
1622 
FindNavigationNodeToHandleBack(const RefPtr<UINode> & node)1623 RefPtr<FrameNode> PipelineContext::FindNavigationNodeToHandleBack(const RefPtr<UINode>& node)
1624 {
1625     const auto& children = node->GetChildren();
1626     for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
1627         auto& child = *iter;
1628         auto destinationNode = AceType::DynamicCast<NavDestinationGroupNode>(child);
1629         if (destinationNode && destinationNode->GetLayoutProperty()) {
1630             auto property = destinationNode->GetLayoutProperty<LayoutProperty>();
1631             if (property->GetVisibilityValue(VisibleType::VISIBLE) != VisibleType::VISIBLE) {
1632                 continue;
1633             }
1634         }
1635         auto target = FindNavigationNodeToHandleBack(child);
1636         if (target) {
1637             return target;
1638         }
1639     }
1640     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(node);
1641     if (navigationGroupNode && navigationGroupNode->CheckCanHandleBack()) {
1642         return navigationGroupNode;
1643     }
1644     return nullptr;
1645 }
1646 
SetIsFocusActive(bool isFocusActive)1647 bool PipelineContext::SetIsFocusActive(bool isFocusActive)
1648 {
1649     if (isFocusActive_ == isFocusActive) {
1650         return false;
1651     }
1652     isFocusActive_ = isFocusActive;
1653     for (auto& pair : isFocusActiveUpdateEvents_) {
1654         if (pair.second) {
1655             pair.second(isFocusActive_);
1656         }
1657     }
1658     CHECK_NULL_RETURN(rootNode_, false);
1659     auto rootFocusHub = rootNode_->GetFocusHub();
1660     CHECK_NULL_RETURN(rootFocusHub, false);
1661     if (isFocusActive_) {
1662         return rootFocusHub->PaintAllFocusState();
1663     }
1664     rootFocusHub->ClearAllFocusState();
1665     return true;
1666 }
1667 
OnTouchEvent(const TouchEvent & point,bool isSubPipe)1668 void PipelineContext::OnTouchEvent(const TouchEvent& point, bool isSubPipe)
1669 {
1670     OnTouchEvent(point, rootNode_, isSubPipe);
1671 }
1672 
OnMouseEvent(const MouseEvent & event)1673 void PipelineContext::OnMouseEvent(const MouseEvent& event)
1674 {
1675     OnMouseEvent(event, rootNode_);
1676 }
1677 
OnAxisEvent(const AxisEvent & event)1678 void PipelineContext::OnAxisEvent(const AxisEvent& event)
1679 {
1680     OnAxisEvent(event, rootNode_);
1681 }
1682 
OnTouchEvent(const TouchEvent & point,const RefPtr<FrameNode> & node,bool isSubPipe)1683 void PipelineContext::OnTouchEvent(const TouchEvent& point, const RefPtr<FrameNode>& node, bool isSubPipe)
1684 {
1685     CHECK_RUN_ON(UI);
1686 
1687 #ifdef UICAST_COMPONENT_SUPPORTED
1688     do {
1689         auto container = Container::Current();
1690         CHECK_NULL_BREAK(container);
1691         auto distributedUI = container->GetDistributedUI();
1692         CHECK_NULL_BREAK(distributedUI);
1693         if (distributedUI->IsSinkMode()) {
1694             distributedUI->BypassEvent(point, isSubPipe);
1695             return;
1696         }
1697     } while (false);
1698 #endif
1699 
1700     SerializedGesture etsSerializedGesture;
1701     if (point.type != TouchType::DOWN) {
1702         HandleEtsCardTouchEvent(point, etsSerializedGesture);
1703     }
1704 
1705     auto oriPoint = point;
1706     auto scalePoint = point.CreateScalePoint(GetViewScale());
1707     ResSchedReport::GetInstance().OnTouchEvent(scalePoint.type);
1708     if (scalePoint.type != TouchType::MOVE && scalePoint.type != TouchType::PULL_MOVE) {
1709         eventManager_->GetEventTreeRecord().AddTouchPoint(scalePoint);
1710         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
1711             "TouchEvent Process in ace_container: "
1712             "eventInfo: id:%{public}d, pointX=%{public}f pointY=%{public}f "
1713             "type=%{public}d",
1714             scalePoint.id, scalePoint.x, scalePoint.y, (int)scalePoint.type);
1715     }
1716     eventManager_->SetInstanceId(GetInstanceId());
1717     if (scalePoint.type != TouchType::MOVE && historyPointsById_.find(scalePoint.id) != historyPointsById_.end()) {
1718         historyPointsById_.erase(scalePoint.id);
1719     }
1720     if (scalePoint.type == TouchType::DOWN) {
1721         // Set focus state inactive while touch down event received
1722         SetIsFocusActive(false);
1723         TouchRestrict touchRestrict { TouchRestrict::NONE };
1724         touchRestrict.sourceType = point.sourceType;
1725         touchRestrict.touchEvent = point;
1726         eventManager_->TouchTest(scalePoint, node, touchRestrict, GetPluginEventOffset(), viewScale_, isSubPipe);
1727         if (!touchRestrict.childTouchTestList.empty()) {
1728             scalePoint.childTouchTestList = touchRestrict.childTouchTestList;
1729         }
1730         touchTestResults_ = eventManager_->touchTestResults_;
1731 
1732         HandleEtsCardTouchEvent(oriPoint, etsSerializedGesture);
1733 
1734         if (etsSerializedGesture.data.size() != 0) {
1735             GestureGroup rebirth(GestureMode::Exclusive);
1736             rebirth.Deserialize(etsSerializedGesture.data.data());
1737             auto recognizer = rebirth.CreateRecognizer();
1738             if (recognizer) {
1739                 recognizer->SetInnerFlag(true);
1740                 recognizer->BeginReferee(scalePoint.id, true);
1741                 std::list<RefPtr<NGGestureRecognizer>> combined;
1742                 combined.emplace_back(recognizer);
1743                 for (auto iter = touchTestResults_[point.id].begin();
1744                     iter != touchTestResults_[point.id].end(); iter++) {
1745                     auto outRecognizer = AceType::DynamicCast<NGGestureRecognizer>(*iter);
1746                     if (outRecognizer) {
1747                         combined.emplace_back(outRecognizer);
1748                         touchTestResults_[point.id].erase(iter);
1749                         break;
1750                     }
1751                 }
1752                 auto exclusiveRecognizer = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(combined));
1753                 exclusiveRecognizer->AttachFrameNode(node);
1754                 exclusiveRecognizer->BeginReferee(scalePoint.id);
1755                 touchTestResults_[point.id].emplace_back(exclusiveRecognizer);
1756                 eventManager_->touchTestResults_ = touchTestResults_;
1757                 eventManager_->SetInnerFlag(true);
1758             }
1759         }
1760         if (IsFormRender() && touchTestResults_.find(point.id) != touchTestResults_.end()) {
1761             for (const auto& touchResult : touchTestResults_[point.id]) {
1762                 auto recognizer = AceType::DynamicCast<NG::RecognizerGroup>(touchResult);
1763                 if (recognizer) {
1764                     auto gesture = recognizer->CreateGestureFromRecognizer();
1765                     if (gesture) {
1766                         serializedGesture_.data = std::vector<char>(gesture->SizeofMe());
1767                         gesture->Serialize(serializedGesture_.data.data());
1768                     }
1769                     break;
1770                 }
1771             }
1772         }
1773         for (const auto& weakContext : touchPluginPipelineContext_) {
1774             auto pipelineContext = DynamicCast<OHOS::Ace::PipelineBase>(weakContext.Upgrade());
1775             if (!pipelineContext) {
1776                 continue;
1777             }
1778             auto pluginPoint =
1779                 point.UpdateScalePoint(viewScale_, static_cast<float>(pipelineContext->GetPluginEventOffset().GetX()),
1780                     static_cast<float>(pipelineContext->GetPluginEventOffset().GetY()), point.id);
1781             // eventManager_ instance Id may changed.
1782             pipelineContext->OnTouchEvent(pluginPoint, true);
1783         }
1784 
1785         // restore instance Id.
1786         eventManager_->SetInstanceId(GetInstanceId());
1787     }
1788     auto rootOffset = GetRootRect().GetOffset();
1789     eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
1790 
1791     if (isSubPipe) {
1792         return;
1793     }
1794 
1795     if (scalePoint.type == TouchType::MOVE) {
1796         if (!eventManager_->GetInnerFlag()) {
1797             auto mockPoint = point;
1798             mockPoint.type = TouchType::CANCEL;
1799             HandleEtsCardTouchEvent(mockPoint, etsSerializedGesture);
1800             RemoveEtsCardTouchEventCallback(mockPoint.id);
1801         }
1802         touchEvents_.emplace_back(point);
1803         hasIdleTasks_ = true;
1804         RequestFrame();
1805         return;
1806     }
1807 
1808     if (scalePoint.type == TouchType::UP) {
1809         lastTouchTime_ = GetTimeFromExternalTimer();
1810     }
1811 
1812     std::optional<TouchEvent> lastMoveEvent;
1813     if (scalePoint.type == TouchType::UP && !touchEvents_.empty()) {
1814         for (auto iter = touchEvents_.begin(); iter != touchEvents_.end();) {
1815             auto movePoint = (*iter).CreateScalePoint(GetViewScale());
1816             if (scalePoint.id == movePoint.id) {
1817                 lastMoveEvent = movePoint;
1818                 iter = touchEvents_.erase(iter);
1819             } else {
1820                 ++iter;
1821             }
1822         }
1823         if (lastMoveEvent.has_value()) {
1824             eventManager_->SetLastMoveBeforeUp(scalePoint.sourceType == SourceType::MOUSE);
1825             eventManager_->DispatchTouchEvent(lastMoveEvent.value());
1826             eventManager_->SetLastMoveBeforeUp(false);
1827         }
1828     }
1829 
1830     eventManager_->DispatchTouchEvent(scalePoint);
1831 
1832     if ((scalePoint.type == TouchType::UP) || (scalePoint.type == TouchType::CANCEL)) {
1833         // need to reset touchPluginPipelineContext_ for next touch down event.
1834         touchPluginPipelineContext_.clear();
1835         RemoveEtsCardTouchEventCallback(point.id);
1836         ResetDraggingStatus(scalePoint);
1837     }
1838 
1839     hasIdleTasks_ = true;
1840     RequestFrame();
1841 }
1842 
ResetDraggingStatus(const TouchEvent & touchPoint)1843 void PipelineContext::ResetDraggingStatus(const TouchEvent& touchPoint)
1844 {
1845     auto manager = GetDragDropManager();
1846     CHECK_NULL_VOID(manager);
1847     if (manager->IsDraggingPressed(touchPoint.id)) {
1848         manager->SetDraggingPressedState(false);
1849     }
1850     if (manager->IsDragging() && manager->IsSameDraggingPointer(touchPoint.id)) {
1851         manager->OnDragEnd(PointerEvent(touchPoint.x, touchPoint.y), "");
1852     }
1853 }
1854 
OnSurfaceDensityChanged(double density)1855 void PipelineContext::OnSurfaceDensityChanged(double density)
1856 {
1857     CHECK_RUN_ON(UI);
1858     if (!NearEqual(density, density_)) {
1859         isDensityChanged_ = true;
1860     }
1861     density_ = density;
1862     if (!NearZero(viewScale_)) {
1863         dipScale_ = density_ / viewScale_;
1864     }
1865 }
1866 
RegisterDumpInfoListener(const std::function<void (const std::vector<std::string> &)> & callback)1867 void PipelineContext::RegisterDumpInfoListener(const std::function<void(const std::vector<std::string>&)>& callback)
1868 {
1869     dumpListeners_.push_back(callback);
1870 }
1871 
DumpPageViewData(const RefPtr<FrameNode> & node,RefPtr<ViewDataWrap> viewDataWrap)1872 bool PipelineContext::DumpPageViewData(const RefPtr<FrameNode>& node, RefPtr<ViewDataWrap> viewDataWrap)
1873 {
1874     CHECK_NULL_RETURN(viewDataWrap, false);
1875     RefPtr<FrameNode> pageNode = nullptr;
1876     if (node == nullptr) {
1877         if (stageManager_) {
1878             pageNode = stageManager_->GetLastPage();
1879         }
1880     } else {
1881         pageNode = node->GetPageNode();
1882     }
1883     CHECK_NULL_RETURN(pageNode, false);
1884     pageNode->DumpViewDataPageNodes(viewDataWrap);
1885     auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
1886     CHECK_NULL_RETURN(pagePattern, false);
1887     auto pageInfo = pagePattern->GetPageInfo();
1888     CHECK_NULL_RETURN(pageInfo, false);
1889     viewDataWrap->SetPageUrl(pageInfo->GetPageUrl());
1890     return true;
1891 }
1892 
CheckNeedAutoSave()1893 bool PipelineContext::CheckNeedAutoSave()
1894 {
1895     CHECK_NULL_RETURN(stageManager_, false);
1896     auto pageNode = stageManager_->GetLastPage();
1897     CHECK_NULL_RETURN(pageNode, false);
1898     return pageNode->NeedRequestAutoSave();
1899 }
1900 
CheckPageFocus()1901 bool PipelineContext::CheckPageFocus()
1902 {
1903     CHECK_NULL_RETURN(stageManager_, true);
1904     auto pageNode = stageManager_->GetLastPage();
1905     CHECK_NULL_RETURN(pageNode, true);
1906     return pageNode->GetFocusHub() && pageNode->GetFocusHub()->IsCurrentFocus();
1907 }
1908 
NotifyFillRequestSuccess(AceAutoFillType autoFillType,RefPtr<ViewDataWrap> viewDataWrap)1909 void PipelineContext::NotifyFillRequestSuccess(AceAutoFillType autoFillType, RefPtr<ViewDataWrap> viewDataWrap)
1910 {
1911     CHECK_NULL_VOID(viewDataWrap);
1912     auto pageNodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
1913     for (const auto& item : pageNodeInfoWraps) {
1914         if (item == nullptr) {
1915             continue;
1916         }
1917         auto frameNode = DynamicCast<FrameNode>(ElementRegister::GetInstance()->GetUINodeById(item->GetId()));
1918         if (frameNode == nullptr) {
1919             TAG_LOGW(AceLogTag::ACE_AUTO_FILL, "frameNode is not found, id=%{public}d", item->GetId());
1920             continue;
1921         }
1922         frameNode->NotifyFillRequestSuccess(item, autoFillType);
1923     }
1924 }
1925 
NotifyFillRequestFailed(RefPtr<FrameNode> node,int32_t errCode)1926 void PipelineContext::NotifyFillRequestFailed(RefPtr<FrameNode> node, int32_t errCode)
1927 {
1928     CHECK_NULL_VOID(node);
1929     node->NotifyFillRequestFailed(errCode);
1930 }
1931 
OnDumpInfo(const std::vector<std::string> & params) const1932 bool PipelineContext::OnDumpInfo(const std::vector<std::string>& params) const
1933 {
1934     ACE_DCHECK(!params.empty());
1935     if (params[0] == "-element") {
1936         if (params.size() > 1 && params[1] == "-lastpage") {
1937             auto lastPage = stageManager_->GetLastPage();
1938             if (params.size() < USED_ID_FIND_FLAG && lastPage) {
1939                 lastPage->DumpTree(0);
1940                 DumpLog::GetInstance().OutPutBySize();
1941             }
1942             if (params.size() == USED_ID_FIND_FLAG && lastPage && !lastPage->DumpTreeById(0, params[2])) {
1943                 DumpLog::GetInstance().Print(
1944                     "There is no id matching the ID in the parameter,please check whether the id is correct");
1945             }
1946         } else {
1947             rootNode_->DumpTree(0);
1948             DumpLog::GetInstance().OutPutBySize();
1949         }
1950     } else if (params[0] == "-focus") {
1951         if (rootNode_->GetFocusHub()) {
1952             rootNode_->GetFocusHub()->DumpFocusTree(0);
1953         }
1954     } else if (params[0] == "-accessibility" || params[0] == "-inspector") {
1955         auto accessibilityManager = GetAccessibilityManager();
1956         if (accessibilityManager) {
1957             accessibilityManager->OnDumpInfo(params);
1958         }
1959     } else if (params[0] == "-rotation" && params.size() >= 2) {
1960     } else if (params[0] == "-animationscale" && params.size() >= 2) {
1961     } else if (params[0] == "-velocityscale" && params.size() >= 2) {
1962     } else if (params[0] == "-scrollfriction" && params.size() >= 2) {
1963     } else if (params[0] == "-threadstuck" && params.size() >= 3) {
1964     } else if (params[0] == "-pipeline") {
1965         DumpPipelineInfo();
1966     } else if (params[0] == "-jsdump") {
1967         std::vector<std::string> jsParams;
1968         if (params.begin() != params.end()) {
1969             jsParams = std::vector<std::string>(params.begin() + 1, params.end());
1970         }
1971 
1972         for (const auto& func : dumpListeners_) {
1973             func(jsParams);
1974         }
1975     } else if (params[0] == "-event") {
1976         if (eventManager_) {
1977             eventManager_->DumpEvent();
1978         }
1979     } else if (params[0] == "-imagecache") {
1980         if (imageCache_) {
1981             imageCache_->DumpCacheInfo();
1982         }
1983     } else if (params[0] == "-imagefilecache") {
1984         ImageFileCache::GetInstance().DumpCacheInfo();
1985     }
1986     return true;
1987 }
1988 
GetCurrentFrameInfo(uint64_t recvTime,uint64_t timeStamp)1989 FrameInfo* PipelineContext::GetCurrentFrameInfo(uint64_t recvTime, uint64_t timeStamp)
1990 {
1991     if (SystemProperties::GetDumpFrameCount() == 0) {
1992         return nullptr;
1993     }
1994     if (dumpFrameInfos_.size() >= SystemProperties::GetDumpFrameCount()) {
1995         dumpFrameInfos_.pop_front();
1996     }
1997 
1998     dumpFrameInfos_.push_back({ .frameRecvTime_ = recvTime, .frameTimeStamp_ = timeStamp });
1999     return &dumpFrameInfos_.back();
2000 }
2001 
DumpPipelineInfo() const2002 void PipelineContext::DumpPipelineInfo() const
2003 {
2004     DumpLog::GetInstance().Print("PipelineInfo:");
2005     if (window_) {
2006         DumpLog::GetInstance().Print(1, "DisplayRefreshRate: " + std::to_string(window_->GetRefreshRate()));
2007         DumpLog::GetInstance().Print(1, "LastRequestVsyncTime: " + std::to_string(window_->GetLastRequestVsyncTime()));
2008         DumpLog::GetInstance().Print(1, "NowTime: " + std::to_string(GetSysTimestamp()));
2009     }
2010     if (!dumpFrameInfos_.empty()) {
2011         DumpLog::GetInstance().Print("==================================FrameTask==================================");
2012         for (const auto& info : dumpFrameInfos_) {
2013             DumpLog::GetInstance().Print("Task: " + info.GetTimeInfo());
2014             DumpLog::GetInstance().Print(1, "LayoutTask:");
2015             for (const auto& layout : info.layoutInfos_) {
2016                 DumpLog::GetInstance().Print(2, layout.ToString());
2017             }
2018             DumpLog::GetInstance().Print(1, "RenderTask:");
2019             for (const auto& layout : info.renderInfos_) {
2020                 DumpLog::GetInstance().Print(2, layout.ToString());
2021             }
2022             DumpLog::GetInstance().Print(
2023                 "==================================FrameTask==================================");
2024         }
2025     }
2026 }
2027 
FlushTouchEvents()2028 void PipelineContext::FlushTouchEvents()
2029 {
2030     CHECK_RUN_ON(UI);
2031     CHECK_NULL_VOID(rootNode_);
2032     {
2033         std::unordered_set<int32_t> moveEventIds;
2034         decltype(touchEvents_) touchEvents(std::move(touchEvents_));
2035         if (touchEvents.empty()) {
2036             canUseLongPredictTask_ = true;
2037             return;
2038         }
2039         canUseLongPredictTask_ = false;
2040         eventManager_->FlushTouchEventsBegin(touchEvents_);
2041         std::unordered_map<int, TouchEvent> idToTouchPoints;
2042         bool needInterpolation = true;
2043         std::unordered_map<int32_t, TouchEvent> newIdTouchPoints;
2044         for (auto iter = touchEvents.rbegin(); iter != touchEvents.rend(); ++iter) {
2045             auto scalePoint = (*iter).CreateScalePoint(GetViewScale());
2046             idToTouchPoints.emplace(scalePoint.id, scalePoint);
2047             idToTouchPoints[scalePoint.id].history.insert(idToTouchPoints[scalePoint.id].history.begin(), scalePoint);
2048             needInterpolation = iter->type != TouchType::MOVE ? false : true;
2049         }
2050         if (focusWindowId_.has_value()) {
2051             needInterpolation = false;
2052         }
2053         if (needInterpolation) {
2054             auto targetTimeStamp = resampleTimeStamp_;
2055             for (const auto& idIter : idToTouchPoints) {
2056                 TouchEvent newTouchEvent =
2057                     GetResampleTouchEvent(historyPointsById_[idIter.first], idIter.second.history, targetTimeStamp);
2058                 if (newTouchEvent.x != 0 && newTouchEvent.y != 0) {
2059                     newIdTouchPoints[idIter.first] = newTouchEvent;
2060                 }
2061                 historyPointsById_[idIter.first] = idIter.second.history;
2062             }
2063         }
2064         std::list<TouchEvent> touchPoints;
2065         for (const auto& iter : idToTouchPoints) {
2066             if (newIdTouchPoints.find(iter.first) != newIdTouchPoints.end()) {
2067                 touchPoints.emplace_back(newIdTouchPoints[iter.first]);
2068             } else {
2069                 touchPoints.emplace_back(iter.second);
2070             }
2071         }
2072         auto maxSize = touchPoints.size();
2073         for (auto iter = touchPoints.rbegin(); iter != touchPoints.rend(); ++iter) {
2074             maxSize--;
2075             if (maxSize == 0) {
2076                 eventManager_->FlushTouchEventsEnd(touchPoints);
2077             }
2078             eventManager_->DispatchTouchEvent(*iter);
2079         }
2080     }
2081 }
2082 
OnMouseEvent(const MouseEvent & event,const RefPtr<FrameNode> & node)2083 void PipelineContext::OnMouseEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
2084 {
2085     CHECK_RUN_ON(UI);
2086     if (!lastMouseEvent_) {
2087         lastMouseEvent_ = std::make_unique<MouseEvent>();
2088     }
2089     lastMouseEvent_->x = event.x;
2090     lastMouseEvent_->y = event.y;
2091     lastMouseEvent_->button = event.button;
2092     lastMouseEvent_->action = event.action;
2093     lastMouseEvent_->sourceType = event.sourceType;
2094     lastMouseEvent_->time = event.time;
2095 
2096     if (event.button == MouseButton::RIGHT_BUTTON && event.action == MouseAction::PRESS) {
2097         // Mouse right button press event set focus inactive here.
2098         // Mouse left button press event will set focus inactive in touch process.
2099         SetIsFocusActive(false);
2100     }
2101 
2102     auto manager = GetDragDropManager();
2103     CHECK_NULL_VOID(manager);
2104 
2105     if (event.button == MouseButton::RIGHT_BUTTON &&
2106         (event.action == MouseAction::PRESS || event.action == MouseAction::PULL_UP)) {
2107         manager->SetIsDragCancel(true);
2108     } else {
2109         manager->SetIsDragCancel(false);
2110     }
2111 
2112     auto container = Container::Current();
2113     if ((event.action == MouseAction::RELEASE || event.action == MouseAction::PRESS ||
2114             event.action == MouseAction::MOVE) &&
2115         (event.button == MouseButton::LEFT_BUTTON || event.pressedButtons == MOUSE_PRESS_LEFT)) {
2116         auto touchPoint = event.CreateTouchPoint();
2117         if (event.pullAction == MouseAction::PULL_MOVE) {
2118             touchPoint.pullType = TouchType::PULL_MOVE;
2119         }
2120         OnTouchEvent(touchPoint, node);
2121     } else {
2122         auto touchPoint = event.CreateTouchPoint();
2123         auto scalePoint = touchPoint.CreateScalePoint(GetViewScale());
2124         auto rootOffset = GetRootRect().GetOffset();
2125         eventManager_->HandleGlobalEventNG(scalePoint, selectOverlayManager_, rootOffset);
2126     }
2127 
2128     CHECK_NULL_VOID(node);
2129     auto scaleEvent = event.CreateScaleEvent(viewScale_);
2130     TouchRestrict touchRestrict { TouchRestrict::NONE };
2131     touchRestrict.sourceType = event.sourceType;
2132     touchRestrict.hitTestType = SourceType::MOUSE;
2133     eventManager_->MouseTest(scaleEvent, node, touchRestrict);
2134     eventManager_->DispatchMouseEventNG(scaleEvent);
2135     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
2136     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
2137     RequestFrame();
2138 }
2139 
FlushMouseEvent()2140 void PipelineContext::FlushMouseEvent()
2141 {
2142     if (!lastMouseEvent_ || lastMouseEvent_->action == MouseAction::WINDOW_LEAVE) {
2143         return;
2144     }
2145     MouseEvent event;
2146     event.x = lastMouseEvent_->x;
2147     event.y = lastMouseEvent_->y;
2148     event.time = lastMouseEvent_->time;
2149     event.action = MouseAction::MOVE;
2150     event.button = MouseButton::NONE_BUTTON;
2151     event.sourceType = SourceType::MOUSE;
2152 
2153     CHECK_RUN_ON(UI);
2154     CHECK_NULL_VOID(rootNode_);
2155     auto scaleEvent = event.CreateScaleEvent(viewScale_);
2156     TouchRestrict touchRestrict { TouchRestrict::NONE };
2157     touchRestrict.sourceType = event.sourceType;
2158     touchRestrict.hitTestType = SourceType::MOUSE;
2159     eventManager_->MouseTest(scaleEvent, rootNode_, touchRestrict);
2160     eventManager_->DispatchMouseEventNG(scaleEvent);
2161     eventManager_->DispatchMouseHoverEventNG(scaleEvent);
2162     eventManager_->DispatchMouseHoverAnimationNG(scaleEvent);
2163 }
2164 
ChangeMouseStyle(int32_t nodeId,MouseFormat format)2165 bool PipelineContext::ChangeMouseStyle(int32_t nodeId, MouseFormat format)
2166 {
2167     auto window = GetWindow();
2168     if (window && window->IsUserSetCursor()) {
2169         return false;
2170     }
2171     if (mouseStyleNodeId_ != nodeId) {
2172         return false;
2173     }
2174     auto mouseStyle = MouseStyle::CreateMouseStyle();
2175     CHECK_NULL_RETURN(mouseStyle, false);
2176     return mouseStyle->ChangePointerStyle(GetWindowId(), format);
2177 }
2178 
OnKeyEvent(const KeyEvent & event)2179 bool PipelineContext::OnKeyEvent(const KeyEvent& event)
2180 {
2181     eventManager_->SetPressedKeyCodes(event.pressedCodes);
2182     CHECK_NULL_RETURN(eventManager_, false);
2183     if (event.action == KeyAction::DOWN) {
2184         eventManager_->DispatchKeyboardShortcut(event);
2185     }
2186     if (event.code == KeyCode::KEY_ESCAPE) {
2187         auto manager = GetDragDropManager();
2188         if (manager && manager->IsMsdpDragging()) {
2189             manager->SetIsDragCancel(true);
2190             manager->OnDragEnd(PointerEvent(0, 0), "");
2191             manager->SetIsDragCancel(false);
2192             return true;
2193         }
2194     }
2195 
2196     auto isKeyTabDown = event.action == KeyAction::DOWN && event.IsKey({ KeyCode::KEY_TAB });
2197     auto curMainView = FocusHub::GetCurrentMainView();
2198     auto isViewRootScopeFocused = curMainView ? curMainView->GetIsViewRootScopeFocused() : true;
2199     isTabJustTriggerOnKeyEvent_ = false;
2200     if (isKeyTabDown && isViewRootScopeFocused && curMainView) {
2201         // Current focused on the view root scope. Tab key used to extend focus.
2202         // If return true. This tab key will just trigger onKeyEvent process.
2203         isTabJustTriggerOnKeyEvent_ = curMainView->HandleFocusOnMainView();
2204     }
2205 
2206     // Tab key set focus state from inactive to active.
2207     // If return true. This tab key will just trigger onKeyEvent process.
2208     bool isHandleFocusActive = isKeyTabDown && SetIsFocusActive(true);
2209     isTabJustTriggerOnKeyEvent_ = isTabJustTriggerOnKeyEvent_ || isHandleFocusActive;
2210 
2211     auto curMainViewFrameNode = curMainView ? curMainView->GetFrameNode() : nullptr;
2212     if (!eventManager_->DispatchTabIndexEventNG(event, curMainViewFrameNode)) {
2213         auto result = eventManager_->DispatchKeyEventNG(event, rootNode_);
2214         if (!result && event.code == KeyCode::KEY_ESCAPE && event.action == KeyAction::DOWN) {
2215             CHECK_NULL_RETURN(overlayManager_, false);
2216             auto currentContainer = Container::Current();
2217             if (currentContainer->IsSubContainer() || currentContainer->IsDialogContainer()) {
2218                 return overlayManager_->RemoveOverlayInSubwindow();
2219             } else {
2220                 return overlayManager_->RemoveOverlay(false);
2221             }
2222         } else {
2223             return result;
2224         }
2225     }
2226     return true;
2227 }
2228 
RequestDefaultFocus(const RefPtr<FocusHub> & mainView)2229 bool PipelineContext::RequestDefaultFocus(const RefPtr<FocusHub>& mainView)
2230 {
2231     if (!mainView || mainView->GetFocusType() != FocusType::SCOPE) {
2232         return false;
2233     }
2234     mainView->SetIsViewHasFocused(true);
2235     auto viewRootScope = mainView->GetMainViewRootScope();
2236     auto defaultFocusNode = mainView->GetChildFocusNodeByType(FocusNodeType::DEFAULT);
2237     if (!mainView->IsDefaultHasFocused() && defaultFocusNode && defaultFocusNode->IsFocusableWholePath()) {
2238         mainView->SetIsViewRootScopeFocused(viewRootScope, false);
2239         auto ret = defaultFocusNode->RequestFocusImmediately();
2240         mainView->SetIsDefaultHasFocused(true);
2241         TAG_LOGI(AceLogTag::ACE_FOCUS,
2242             "Target view's default focus is %{public}s/%{public}d. Request default focus return: %{public}d.",
2243             defaultFocusNode->GetFrameName().c_str(), defaultFocusNode->GetFrameId(), ret);
2244         return ret;
2245     }
2246     if (mainView->GetIsViewRootScopeFocused() && viewRootScope) {
2247         mainView->SetIsViewRootScopeFocused(viewRootScope, true);
2248         auto ret = viewRootScope->RequestFocusImmediately();
2249         TAG_LOGI(AceLogTag::ACE_FOCUS,
2250             "Target view has no default focus. Request focus on view root: %{public}s/%{public}d return: %{public}d.",
2251             viewRootScope->GetFrameName().c_str(), viewRootScope->GetFrameId(), ret);
2252         return ret;
2253     }
2254     mainView->SetIsViewRootScopeFocused(viewRootScope, false);
2255     auto ret = mainView->RequestFocusImmediately();
2256     TAG_LOGI(AceLogTag::ACE_FOCUS,
2257         "Target view's default focus has been focused. Request view focus return: %{public}d.", ret);
2258     return ret;
2259 }
2260 
RequestFocus(const std::string & targetNodeId)2261 bool PipelineContext::RequestFocus(const std::string& targetNodeId)
2262 {
2263     CHECK_NULL_RETURN(rootNode_, false);
2264     auto focusHub = rootNode_->GetFocusHub();
2265     CHECK_NULL_RETURN(focusHub, false);
2266     auto currentFocusChecked = focusHub->RequestFocusImmediatelyById(targetNodeId);
2267     if (!isSubPipeline_ || currentFocusChecked) {
2268         return currentFocusChecked;
2269     }
2270     auto parentPipelineBase = parentPipeline_.Upgrade();
2271     CHECK_NULL_RETURN(parentPipelineBase, false);
2272     auto parentPipelineContext = AceType::DynamicCast<NG::PipelineContext>(parentPipelineBase);
2273     CHECK_NULL_RETURN(parentPipelineContext, false);
2274     return parentPipelineContext->RequestFocus(targetNodeId);
2275 }
2276 
AddDirtyFocus(const RefPtr<FrameNode> & node)2277 void PipelineContext::AddDirtyFocus(const RefPtr<FrameNode>& node)
2278 {
2279     CHECK_RUN_ON(UI);
2280     CHECK_NULL_VOID(node);
2281     if (node->GetFocusType() == FocusType::NODE) {
2282         dirtyFocusNode_ = WeakClaim(RawPtr(node));
2283     } else {
2284         dirtyFocusScope_ = WeakClaim(RawPtr(node));
2285     }
2286     RequestFrame();
2287 }
2288 
AddDirtyDefaultFocus(const RefPtr<FrameNode> & node)2289 void PipelineContext::AddDirtyDefaultFocus(const RefPtr<FrameNode>& node)
2290 {
2291     CHECK_RUN_ON(UI);
2292     CHECK_NULL_VOID(node);
2293     dirtyDefaultFocusNode_ = WeakPtr<FrameNode>(node);
2294     RequestFrame();
2295 }
2296 
AddDirtyRequestFocus(const RefPtr<FrameNode> & node)2297 void PipelineContext::AddDirtyRequestFocus(const RefPtr<FrameNode>& node)
2298 {
2299     CHECK_RUN_ON(UI);
2300     CHECK_NULL_VOID(node);
2301     dirtyRequestFocusNode_ = WeakPtr<FrameNode>(node);
2302     RequestFrame();
2303 }
2304 
RootLostFocus(BlurReason reason) const2305 void PipelineContext::RootLostFocus(BlurReason reason) const
2306 {
2307     CHECK_NULL_VOID(rootNode_);
2308     auto focusHub = rootNode_->GetFocusHub();
2309     CHECK_NULL_VOID(focusHub);
2310     focusHub->LostFocus(reason);
2311     CHECK_NULL_VOID(overlayManager_);
2312     overlayManager_->HideAllMenus();
2313     overlayManager_->HideCustomPopups();
2314 }
2315 
ConvertAxisToMouse(const AxisEvent & event)2316 MouseEvent ConvertAxisToMouse(const AxisEvent& event)
2317 {
2318     MouseEvent result;
2319     result.x = event.x;
2320     result.y = event.y;
2321     result.action = MouseAction::MOVE;
2322     result.button = MouseButton::NONE_BUTTON;
2323     result.time = event.time;
2324     result.deviceId = event.deviceId;
2325     result.sourceType = event.sourceType;
2326     result.pointerEvent = event.pointerEvent;
2327     return result;
2328 }
2329 
OnAxisEvent(const AxisEvent & event,const RefPtr<FrameNode> & node)2330 void PipelineContext::OnAxisEvent(const AxisEvent& event, const RefPtr<FrameNode>& node)
2331 {
2332     auto scaleEvent = event.CreateScaleEvent(viewScale_);
2333 
2334     auto dragManager = GetDragDropManager();
2335     if (dragManager && !dragManager->IsDragged()) {
2336         if (event.action == AxisAction::BEGIN) {
2337             isBeforeDragHandleAxis_ = true;
2338             TouchRestrict touchRestrict { TouchRestrict::NONE };
2339             touchRestrict.sourceType = event.sourceType;
2340             touchRestrict.hitTestType = SourceType::TOUCH;
2341             eventManager_->TouchTest(scaleEvent, node, touchRestrict);
2342         }
2343         eventManager_->DispatchTouchEvent(scaleEvent);
2344     } else if (isBeforeDragHandleAxis_ && event.action == AxisAction::END) {
2345         eventManager_->DispatchTouchEvent(scaleEvent);
2346         isBeforeDragHandleAxis_ = false;
2347     }
2348 
2349     if (event.action == AxisAction::BEGIN || event.action == AxisAction::UPDATE) {
2350         eventManager_->AxisTest(scaleEvent, node);
2351         eventManager_->DispatchAxisEventNG(scaleEvent);
2352     }
2353 
2354     auto mouseEvent = ConvertAxisToMouse(event);
2355     OnMouseEvent(mouseEvent, node);
2356 }
2357 
HasDifferentDirectionGesture() const2358 bool PipelineContext::HasDifferentDirectionGesture() const
2359 {
2360     CHECK_NULL_RETURN(eventManager_, false);
2361     return eventManager_->HasDifferentDirectionGesture();
2362 }
2363 
AddVisibleAreaChangeNode(const RefPtr<FrameNode> & node,double ratio,const VisibleRatioCallback & callback,bool isUserCallback)2364 void PipelineContext::AddVisibleAreaChangeNode(
2365     const RefPtr<FrameNode>& node, double ratio, const VisibleRatioCallback& callback, bool isUserCallback)
2366 {
2367     CHECK_NULL_VOID(node);
2368     VisibleCallbackInfo addInfo;
2369     addInfo.callback = callback;
2370     addInfo.isCurrentVisible = false;
2371     onVisibleAreaChangeNodeIds_.emplace(node->GetId());
2372     if (isUserCallback) {
2373         node->AddVisibleAreaUserCallback(ratio, addInfo);
2374     } else {
2375         node->AddVisibleAreaInnerCallback(ratio, addInfo);
2376     }
2377 }
2378 
RemoveVisibleAreaChangeNode(int32_t nodeId)2379 void PipelineContext::RemoveVisibleAreaChangeNode(int32_t nodeId)
2380 {
2381     onVisibleAreaChangeNodeIds_.erase(nodeId);
2382 }
2383 
HandleVisibleAreaChangeEvent()2384 void PipelineContext::HandleVisibleAreaChangeEvent()
2385 {
2386     ACE_FUNCTION_TRACE();
2387     if (onVisibleAreaChangeNodeIds_.empty()) {
2388         return;
2389     }
2390     auto nodes = FrameNode::GetNodesById(onVisibleAreaChangeNodeIds_);
2391     for (auto&& frameNode : nodes) {
2392         frameNode->TriggerVisibleAreaChangeCallback();
2393     }
2394 }
2395 
AddFormVisibleChangeNode(const RefPtr<FrameNode> & node,const std::function<void (bool)> & callback)2396 void PipelineContext::AddFormVisibleChangeNode(const RefPtr<FrameNode>& node, const std::function<void(bool)>& callback)
2397 {
2398     CHECK_NULL_VOID(node);
2399     onFormVisibleChangeNodeIds_.emplace(node->GetId());
2400     onFormVisibleChangeEvents_.insert_or_assign(node->GetId(), callback);
2401 }
2402 
RemoveFormVisibleChangeNode(int32_t nodeId)2403 void PipelineContext::RemoveFormVisibleChangeNode(int32_t nodeId)
2404 {
2405     onFormVisibleChangeNodeIds_.erase(nodeId);
2406     auto iter = onFormVisibleChangeEvents_.find(nodeId);
2407     if (iter != onFormVisibleChangeEvents_.end()) {
2408         onFormVisibleChangeEvents_.erase(iter);
2409     }
2410 }
2411 
HandleFormVisibleChangeEvent(bool isVisible)2412 void PipelineContext::HandleFormVisibleChangeEvent(bool isVisible)
2413 {
2414     auto nodes = FrameNode::GetNodesById(onFormVisibleChangeNodeIds_);
2415     for (auto& pair : onFormVisibleChangeEvents_) {
2416         if (pair.second) {
2417             pair.second(isVisible);
2418         }
2419     }
2420 }
2421 
AddOnAreaChangeNode(int32_t nodeId)2422 void PipelineContext::AddOnAreaChangeNode(int32_t nodeId)
2423 {
2424     onAreaChangeNodeIds_.emplace(nodeId);
2425 }
2426 
RemoveOnAreaChangeNode(int32_t nodeId)2427 void PipelineContext::RemoveOnAreaChangeNode(int32_t nodeId)
2428 {
2429     onAreaChangeNodeIds_.erase(nodeId);
2430 }
2431 
HandleOnAreaChangeEvent(uint64_t nanoTimestamp)2432 void PipelineContext::HandleOnAreaChangeEvent(uint64_t nanoTimestamp)
2433 {
2434     ACE_FUNCTION_TRACE();
2435     if (onAreaChangeNodeIds_.empty()) {
2436         return;
2437     }
2438     auto nodes = FrameNode::GetNodesById(onAreaChangeNodeIds_);
2439     for (auto&& frameNode : nodes) {
2440         frameNode->TriggerOnAreaChangeCallback(nanoTimestamp);
2441     }
2442     UpdateFormLinkInfos();
2443 }
2444 
UpdateFormLinkInfos()2445 void PipelineContext::UpdateFormLinkInfos()
2446 {
2447     if (formLinkInfoUpdateHandler_ && !formLinkInfoMap_.empty()) {
2448         std::vector<std::string> formLinkInfos;
2449         for (auto iter = formLinkInfoMap_.rbegin(); iter != formLinkInfoMap_.rend(); ++iter) {
2450             auto info = iter->second;
2451             formLinkInfos.push_back(info);
2452         }
2453         formLinkInfoUpdateHandler_(formLinkInfos);
2454     }
2455 }
2456 
OnShow()2457 void PipelineContext::OnShow()
2458 {
2459     CHECK_RUN_ON(UI);
2460     onShow_ = true;
2461     if (focusOnNodeCallback_) {
2462         windowShow_ = true;
2463         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "windowShow is OK.");
2464     }
2465     window_->OnShow();
2466     RequestFrame();
2467     FlushWindowStateChangedCallback(true);
2468     AccessibilityEvent event;
2469     event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
2470     event.type = AccessibilityEventType::PAGE_CHANGE;
2471     SendEventToAccessibility(event);
2472 }
2473 
OnHide()2474 void PipelineContext::OnHide()
2475 {
2476     CHECK_RUN_ON(UI);
2477     auto dragDropManager = GetDragDropManager();
2478     if (dragDropManager && dragDropManager->IsItemDragging()) {
2479         dragDropManager->CancelItemDrag();
2480     }
2481     onShow_ = false;
2482     window_->OnHide();
2483     RequestFrame();
2484     OnVirtualKeyboardAreaChange(Rect());
2485     FlushWindowStateChangedCallback(false);
2486     AccessibilityEvent event;
2487     event.type = AccessibilityEventType::PAGE_CHANGE;
2488     SendEventToAccessibility(event);
2489 }
2490 
WindowFocus(bool isFocus)2491 void PipelineContext::WindowFocus(bool isFocus)
2492 {
2493     CHECK_RUN_ON(UI);
2494     onFocus_ = isFocus;
2495     if (!isFocus) {
2496         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window id: %{public}d lost focus.", windowId_);
2497         RestoreDefault();
2498         RootLostFocus(BlurReason::WINDOW_BLUR);
2499         NotifyPopupDismiss();
2500     } else {
2501         TAG_LOGI(AceLogTag::ACE_FOCUS, "Window id: %{public}d get focus.", windowId_);
2502         auto rootFocusHub = rootNode_ ? rootNode_->GetFocusHub() : nullptr;
2503         auto curMainView = FocusHub::GetCurrentMainView();
2504         if (curMainView && curMainView->GetIsViewHasFocused() && rootFocusHub && !rootFocusHub->IsCurrentFocus()) {
2505             rootFocusHub->RequestFocusImmediately();
2506         }
2507         if (focusWindowId_.has_value()) {
2508             if (curMainView) {
2509                 curMainView->HandleFocusOnMainView();
2510             }
2511         }
2512         if (focusOnNodeCallback_) {
2513             windowFocus_ = true;
2514             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "windowfocus focusOnNodeCallback_.");
2515         }
2516         RequestFrame();
2517     }
2518     FlushWindowFocusChangedCallback(isFocus);
2519 }
2520 
ContainerModalUnFocus()2521 void PipelineContext::ContainerModalUnFocus()
2522 {
2523     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2524         return;
2525     }
2526     CHECK_NULL_VOID(rootNode_);
2527     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2528     CHECK_NULL_VOID(containerNode);
2529     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
2530     CHECK_NULL_VOID(containerPattern);
2531     containerPattern->OnWindowForceUnfocused();
2532 }
2533 
ShowContainerTitle(bool isShow,bool hasDeco,bool needUpdate)2534 void PipelineContext::ShowContainerTitle(bool isShow, bool hasDeco, bool needUpdate)
2535 {
2536     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2537         return;
2538     }
2539     CHECK_NULL_VOID(rootNode_);
2540     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2541     CHECK_NULL_VOID(containerNode);
2542     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
2543     CHECK_NULL_VOID(containerPattern);
2544     containerPattern->ShowTitle(isShow, hasDeco, needUpdate);
2545 }
2546 
UpdateTitleInTargetPos(bool isShow,int32_t height)2547 void PipelineContext::UpdateTitleInTargetPos(bool isShow, int32_t height)
2548 {
2549     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2550         return;
2551     }
2552     CHECK_NULL_VOID(rootNode_);
2553     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2554     CHECK_NULL_VOID(containerNode);
2555     auto containerPattern = containerNode->GetPattern<ContainerModalPatternEnhance>();
2556     CHECK_NULL_VOID(containerPattern);
2557     containerPattern->UpdateTitleInTargetPos(isShow, height);
2558 }
2559 
SetContainerWindow(bool isShow)2560 void PipelineContext::SetContainerWindow(bool isShow)
2561 {
2562 #ifdef ENABLE_ROSEN_BACKEND
2563     if (!IsJsCard()) {
2564         auto window = GetWindow();
2565         if (window) {
2566             auto rsUIDirector = window->GetRSUIDirector();
2567             if (rsUIDirector) {
2568                 // set container window show state to render service
2569                 rsUIDirector->SetContainerWindow(isShow, density_);
2570             }
2571         }
2572     }
2573 #endif
2574 }
2575 
SetAppBgColor(const Color & color)2576 void PipelineContext::SetAppBgColor(const Color& color)
2577 {
2578     appBgColor_ = color;
2579 #ifdef ENABLE_ROSEN_BACKEND
2580     if (!IsJsCard()) {
2581         auto window = GetWindow();
2582         if (window) {
2583             auto rsUIDirector = window->GetRSUIDirector();
2584             if (rsUIDirector) {
2585                 rsUIDirector->SetAbilityBGAlpha(appBgColor_.GetAlpha());
2586             }
2587         }
2588     }
2589 #endif
2590     CHECK_NULL_VOID(rootNode_);
2591     auto rootPattern = rootNode_->GetPattern<RootPattern>();
2592     CHECK_NULL_VOID(rootPattern);
2593     rootPattern->SetAppBgColor(appBgColor_, windowModal_ == WindowModal::CONTAINER_MODAL);
2594 }
2595 
SetAppTitle(const std::string & title)2596 void PipelineContext::SetAppTitle(const std::string& title)
2597 {
2598     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2599         return;
2600     }
2601     CHECK_NULL_VOID(rootNode_);
2602     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2603     CHECK_NULL_VOID(containerNode);
2604     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
2605     CHECK_NULL_VOID(containerPattern);
2606     containerPattern->SetAppTitle(title);
2607 }
2608 
SetAppIcon(const RefPtr<PixelMap> & icon)2609 void PipelineContext::SetAppIcon(const RefPtr<PixelMap>& icon)
2610 {
2611     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2612         return;
2613     }
2614     CHECK_NULL_VOID(rootNode_);
2615     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2616     CHECK_NULL_VOID(containerNode);
2617     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
2618     CHECK_NULL_VOID(containerPattern);
2619     containerPattern->SetAppIcon(icon);
2620 }
2621 
FlushReload(const ConfigurationChange & configurationChange)2622 void PipelineContext::FlushReload(const ConfigurationChange& configurationChange)
2623 {
2624     AnimationOption option;
2625     const int32_t duration = 400;
2626     option.SetDuration(duration);
2627     option.SetCurve(Curves::FRICTION);
2628     AnimationUtils::Animate(option, [weak = WeakClaim(this), configurationChange]() {
2629         auto pipeline = weak.Upgrade();
2630         CHECK_NULL_VOID(pipeline);
2631         if (configurationChange.IsNeedUpdate()) {
2632             auto rootNode = pipeline->GetRootElement();
2633             rootNode->UpdateConfigurationUpdate(configurationChange);
2634         }
2635         CHECK_NULL_VOID(pipeline->stageManager_);
2636         pipeline->SetIsReloading(true);
2637         pipeline->stageManager_->ReloadStage();
2638         pipeline->SetIsReloading(false);
2639         pipeline->FlushUITasks();
2640     });
2641 }
2642 
Destroy()2643 void PipelineContext::Destroy()
2644 {
2645     CHECK_RUN_ON(UI);
2646     taskScheduler_->CleanUp();
2647     scheduleTasks_.clear();
2648     dirtyNodes_.clear();
2649     rootNode_.Reset();
2650     stageManager_.Reset();
2651     overlayManager_.Reset();
2652     sharedTransitionManager_.Reset();
2653     dragDropManager_.Reset();
2654     selectOverlayManager_.Reset();
2655     fullScreenManager_.Reset();
2656     touchEvents_.clear();
2657     buildFinishCallbacks_.clear();
2658     onWindowStateChangedCallbacks_.clear();
2659     onWindowFocusChangedCallbacks_.clear();
2660     nodesToNotifyMemoryLevel_.clear();
2661     dirtyFocusNode_.Reset();
2662     dirtyFocusScope_.Reset();
2663     needRenderNode_.clear();
2664     dirtyDefaultFocusNode_.Reset();
2665     dirtyRequestFocusNode_.Reset();
2666     if (textFieldManager_->GetImeShow()) {
2667         FocusHub::CloseKeyboard();
2668     }
2669 #ifdef WINDOW_SCENE_SUPPORTED
2670     uiExtensionManager_.Reset();
2671 #endif
2672     PipelineBase::Destroy();
2673 }
2674 
AddBuildFinishCallBack(std::function<void ()> && callback)2675 void PipelineContext::AddBuildFinishCallBack(std::function<void()>&& callback)
2676 {
2677     buildFinishCallbacks_.emplace_back(std::move(callback));
2678 }
2679 
AddWindowStateChangedCallback(int32_t nodeId)2680 void PipelineContext::AddWindowStateChangedCallback(int32_t nodeId)
2681 {
2682     onWindowStateChangedCallbacks_.emplace(nodeId);
2683 }
2684 
RemoveWindowStateChangedCallback(int32_t nodeId)2685 void PipelineContext::RemoveWindowStateChangedCallback(int32_t nodeId)
2686 {
2687     onWindowStateChangedCallbacks_.erase(nodeId);
2688 }
2689 
FlushWindowStateChangedCallback(bool isShow)2690 void PipelineContext::FlushWindowStateChangedCallback(bool isShow)
2691 {
2692     auto iter = onWindowStateChangedCallbacks_.begin();
2693     while (iter != onWindowStateChangedCallbacks_.end()) {
2694         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
2695         if (!node) {
2696             iter = onWindowStateChangedCallbacks_.erase(iter);
2697         } else {
2698             if (isShow) {
2699                 node->OnWindowShow();
2700             } else {
2701                 node->OnWindowHide();
2702             }
2703             ++iter;
2704         }
2705     }
2706     HandleVisibleAreaChangeEvent();
2707     HandleSubwindow(isShow);
2708 }
2709 
AddWindowFocusChangedCallback(int32_t nodeId)2710 void PipelineContext::AddWindowFocusChangedCallback(int32_t nodeId)
2711 {
2712     onWindowFocusChangedCallbacks_.emplace_back(nodeId);
2713 }
2714 
RemoveWindowFocusChangedCallback(int32_t nodeId)2715 void PipelineContext::RemoveWindowFocusChangedCallback(int32_t nodeId)
2716 {
2717     onWindowFocusChangedCallbacks_.remove(nodeId);
2718 }
2719 
FlushWindowFocusChangedCallback(bool isFocus)2720 void PipelineContext::FlushWindowFocusChangedCallback(bool isFocus)
2721 {
2722     auto iter = onWindowFocusChangedCallbacks_.begin();
2723     while (iter != onWindowFocusChangedCallbacks_.end()) {
2724         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
2725         if (!node) {
2726             iter = onWindowFocusChangedCallbacks_.erase(iter);
2727         } else {
2728             if (isFocus) {
2729                 node->OnWindowFocused();
2730             } else {
2731                 node->OnWindowUnfocused();
2732             }
2733             ++iter;
2734         }
2735     }
2736 }
2737 
AddWindowSizeChangeCallback(int32_t nodeId)2738 void PipelineContext::AddWindowSizeChangeCallback(int32_t nodeId)
2739 {
2740     onWindowSizeChangeCallbacks_.emplace_back(nodeId);
2741 }
2742 
RemoveWindowSizeChangeCallback(int32_t nodeId)2743 void PipelineContext::RemoveWindowSizeChangeCallback(int32_t nodeId)
2744 {
2745     onWindowSizeChangeCallbacks_.remove(nodeId);
2746 }
2747 
AddNavigationStateCallback(int32_t pageId,int32_t nodeId,const std::function<void ()> & callback,bool isOnShow)2748 void PipelineContext::AddNavigationStateCallback(
2749     int32_t pageId, int32_t nodeId, const std::function<void()>& callback, bool isOnShow)
2750 {
2751     CHECK_RUN_ON(UI);
2752     if (isOnShow) {
2753         auto it = pageIdOnShowMap_.find(pageId);
2754         if (it != pageIdOnShowMap_.end()) {
2755             it->second.push_back({nodeId, callback});
2756         } else {
2757             std::list<std::pair<int32_t, std::function<void()>>> callbacks;
2758             callbacks.push_back({nodeId, callback});
2759             pageIdOnShowMap_[pageId] = std::move(callbacks);
2760         }
2761     } else {
2762         auto it = pageIdOnHideMap_.find(pageId);
2763         if (it != pageIdOnHideMap_.end()) {
2764             it->second.push_back({nodeId, callback});
2765         } else {
2766             std::list<std::pair<int32_t, std::function<void()>>> callbacks;
2767             callbacks.push_back({nodeId, callback});
2768             pageIdOnHideMap_[pageId] = std::move(callbacks);
2769         }
2770     }
2771 }
2772 
RemoveNavigationStateCallback(int32_t pageId,int32_t nodeId)2773 void PipelineContext::RemoveNavigationStateCallback(int32_t pageId, int32_t nodeId)
2774 {
2775     CHECK_RUN_ON(UI);
2776     auto it = pageIdOnShowMap_.find(pageId);
2777     if (it != pageIdOnShowMap_.end() && !it->second.empty()) {
2778         for (auto iter = it->second.begin(); iter != it->second.end();) {
2779             if (iter->first == nodeId) {
2780                 iter = it->second.erase(iter);
2781             } else {
2782                 iter++;
2783             }
2784         }
2785     }
2786     it = pageIdOnHideMap_.find(pageId);
2787     if (it != pageIdOnHideMap_.end() && !it->second.empty()) {
2788         for (auto iter = it->second.begin(); iter != it->second.end();) {
2789             if (iter->first == nodeId) {
2790                 iter = it->second.erase(iter);
2791             } else {
2792                 iter++;
2793             }
2794         }
2795     }
2796 }
2797 
FirePageChanged(int32_t pageId,bool isOnShow)2798 void PipelineContext::FirePageChanged(int32_t pageId, bool isOnShow)
2799 {
2800     CHECK_RUN_ON(UI);
2801     if (isOnShow) {
2802         auto it = pageIdOnShowMap_.find(pageId);
2803         if (it != pageIdOnShowMap_.end() && !it->second.empty()) {
2804             for (auto [nodeId, callback] : it->second) {
2805                 callback();
2806             }
2807         }
2808     } else {
2809         auto it = pageIdOnHideMap_.find(pageId);
2810         if (it != pageIdOnHideMap_.end() && !it->second.empty()) {
2811             for (auto [nodeId, callback] : it->second) {
2812                 callback();
2813             }
2814         }
2815     }
2816 }
2817 
FlushWindowSizeChangeCallback(int32_t width,int32_t height,WindowSizeChangeReason type)2818 void PipelineContext::FlushWindowSizeChangeCallback(int32_t width, int32_t height, WindowSizeChangeReason type)
2819 {
2820     auto iter = onWindowSizeChangeCallbacks_.begin();
2821     while (iter != onWindowSizeChangeCallbacks_.end()) {
2822         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
2823         if (!node) {
2824             iter = onWindowSizeChangeCallbacks_.erase(iter);
2825         } else {
2826             node->OnWindowSizeChanged(width, height, type);
2827             ++iter;
2828         }
2829     }
2830 }
2831 
OnDragEvent(const PointerEvent & pointerEvent,DragEventAction action)2832 void PipelineContext::OnDragEvent(const PointerEvent& pointerEvent, DragEventAction action)
2833 {
2834     auto manager = GetDragDropManager();
2835     CHECK_NULL_VOID(manager);
2836     std::string extraInfo;
2837     auto container = Container::Current();
2838     if (container && container->IsScenceBoardWindow()) {
2839         if (!manager->IsDragged() && manager->IsWindowConsumed()) {
2840             manager->SetIsWindowConsumed(false);
2841             return;
2842         }
2843     }
2844     if (action == DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER) {
2845         manager->RequireSummary();
2846         manager->OnDragStart(pointerEvent.GetPoint());
2847         return;
2848     }
2849     if (action == DragEventAction::DRAG_EVENT_OUT) {
2850         manager->OnDragMoveOut(pointerEvent);
2851         manager->ClearSummary();
2852         manager->ClearExtraInfo();
2853         return;
2854     }
2855 
2856     if (action == DragEventAction::DRAG_EVENT_START) {
2857         manager->RequireSummary();
2858     }
2859     extraInfo = manager->GetExtraInfo();
2860     if (action == DragEventAction::DRAG_EVENT_END) {
2861         manager->OnDragEnd(pointerEvent, extraInfo);
2862         return;
2863     }
2864     if (action == DragEventAction::DRAG_EVENT_MOVE) {
2865         manager->DoDragMoveAnimate(pointerEvent);
2866     }
2867     manager->OnDragMove(pointerEvent, extraInfo);
2868 }
2869 
AddNodesToNotifyMemoryLevel(int32_t nodeId)2870 void PipelineContext::AddNodesToNotifyMemoryLevel(int32_t nodeId)
2871 {
2872     nodesToNotifyMemoryLevel_.emplace_back(nodeId);
2873 }
2874 
RemoveNodesToNotifyMemoryLevel(int32_t nodeId)2875 void PipelineContext::RemoveNodesToNotifyMemoryLevel(int32_t nodeId)
2876 {
2877     nodesToNotifyMemoryLevel_.remove(nodeId);
2878 }
2879 
NotifyMemoryLevel(int32_t level)2880 void PipelineContext::NotifyMemoryLevel(int32_t level)
2881 {
2882     auto iter = nodesToNotifyMemoryLevel_.begin();
2883     while (iter != nodesToNotifyMemoryLevel_.end()) {
2884         auto node = ElementRegister::GetInstance()->GetUINodeById(*iter);
2885         if (!node) {
2886             iter = nodesToNotifyMemoryLevel_.erase(iter);
2887         } else {
2888             node->OnNotifyMemoryLevel(level);
2889             ++iter;
2890         }
2891     }
2892 }
AddPredictTask(PredictTask && task)2893 void PipelineContext::AddPredictTask(PredictTask&& task)
2894 {
2895     taskScheduler_->AddPredictTask(std::move(task));
2896     RequestFrame();
2897 }
2898 
OnIdle(int64_t deadline)2899 void PipelineContext::OnIdle(int64_t deadline)
2900 {
2901     if (deadline == 0 || isWindowAnimation_) {
2902         canUseLongPredictTask_ = false;
2903         return;
2904     }
2905     if (canUseLongPredictTask_) {
2906         // check new incoming event after vsync.
2907         if (!touchEvents_.empty()) {
2908             canUseLongPredictTask_ = false;
2909         }
2910     }
2911     CHECK_RUN_ON(UI);
2912     ACE_SCOPED_TRACE("OnIdle, targettime:%" PRId64 "", deadline);
2913     taskScheduler_->FlushPredictTask(deadline - TIME_THRESHOLD, canUseLongPredictTask_);
2914     canUseLongPredictTask_ = false;
2915     if (GetSysTimestamp() < deadline) {
2916         ElementRegister::GetInstance()->CallJSCleanUpIdleTaskFunc();
2917     }
2918 }
2919 
Finish(bool) const2920 void PipelineContext::Finish(bool /* autoFinish */) const
2921 {
2922     CHECK_RUN_ON(UI);
2923     if (finishEventHandler_) {
2924         finishEventHandler_();
2925     }
2926 }
2927 
AddAfterLayoutTask(std::function<void ()> && task)2928 void PipelineContext::AddAfterLayoutTask(std::function<void()>&& task)
2929 {
2930     taskScheduler_->AddAfterLayoutTask(std::move(task));
2931 }
2932 
AddPersistAfterLayoutTask(std::function<void ()> && task)2933 void PipelineContext::AddPersistAfterLayoutTask(std::function<void()>&& task)
2934 {
2935     taskScheduler_->AddPersistAfterLayoutTask(std::move(task));
2936 }
2937 
AddAfterRenderTask(std::function<void ()> && task)2938 void PipelineContext::AddAfterRenderTask(std::function<void()>&& task)
2939 {
2940     taskScheduler_->AddAfterRenderTask(std::move(task));
2941 }
2942 
RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)2943 void PipelineContext::RestoreNodeInfo(std::unique_ptr<JsonValue> nodeInfo)
2944 {
2945     auto child = nodeInfo->GetChild();
2946     while (child->IsValid()) {
2947         auto key = child->GetKey();
2948         auto value = child->GetString();
2949         restoreNodeInfo_.try_emplace(StringUtils::StringToInt(key), value);
2950         child = child->GetNext();
2951     }
2952 }
2953 
GetStoredNodeInfo()2954 std::unique_ptr<JsonValue> PipelineContext::GetStoredNodeInfo()
2955 {
2956     auto jsonNodeInfo = JsonUtil::Create(true);
2957     auto iter = storeNode_.begin();
2958     while (iter != storeNode_.end()) {
2959         auto node = (iter->second).Upgrade();
2960         if (node) {
2961             std::string info = node->ProvideRestoreInfo();
2962             if (!info.empty()) {
2963                 jsonNodeInfo->Put(std::to_string(iter->first).c_str(), info.c_str());
2964             }
2965         }
2966         ++iter;
2967     }
2968     return jsonNodeInfo;
2969 }
2970 
StoreNode(int32_t restoreId,const WeakPtr<FrameNode> & node)2971 void PipelineContext::StoreNode(int32_t restoreId, const WeakPtr<FrameNode>& node)
2972 {
2973     auto ret = storeNode_.try_emplace(restoreId, node);
2974     if (!ret.second) {
2975         storeNode_[restoreId] = node;
2976     }
2977 }
2978 
GetRestoreInfo(int32_t restoreId,std::string & restoreInfo)2979 bool PipelineContext::GetRestoreInfo(int32_t restoreId, std::string& restoreInfo)
2980 {
2981     auto iter = restoreNodeInfo_.find(restoreId);
2982     if (iter != restoreNodeInfo_.end()) {
2983         restoreInfo = iter->second;
2984         restoreNodeInfo_.erase(iter);
2985         return true;
2986     }
2987     return false;
2988 }
2989 
SetContainerButtonHide(bool hideSplit,bool hideMaximize,bool hideMinimize)2990 void PipelineContext::SetContainerButtonHide(bool hideSplit, bool hideMaximize, bool hideMinimize)
2991 {
2992     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
2993         LOGW("Set app icon failed, Window modal is not container.");
2994         return;
2995     }
2996     CHECK_NULL_VOID(rootNode_);
2997     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
2998     CHECK_NULL_VOID(containerNode);
2999     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3000     CHECK_NULL_VOID(containerPattern);
3001     containerPattern->SetContainerButtonHide(hideSplit, hideMaximize, hideMinimize);
3002 }
3003 
AddFontNodeNG(const WeakPtr<UINode> & node)3004 void PipelineContext::AddFontNodeNG(const WeakPtr<UINode>& node)
3005 {
3006     if (fontManager_) {
3007         fontManager_->AddFontNodeNG(node);
3008     }
3009 }
3010 
RemoveFontNodeNG(const WeakPtr<UINode> & node)3011 void PipelineContext::RemoveFontNodeNG(const WeakPtr<UINode>& node)
3012 {
3013     if (fontManager_) {
3014         fontManager_->RemoveFontNodeNG(node);
3015     }
3016 }
3017 
SetWindowSceneConsumed(bool isConsumed)3018 void PipelineContext::SetWindowSceneConsumed(bool isConsumed)
3019 {
3020     isWindowSceneConsumed_ = isConsumed;
3021 }
3022 
IsWindowSceneConsumed()3023 bool PipelineContext::IsWindowSceneConsumed()
3024 {
3025     return isWindowSceneConsumed_;
3026 }
3027 
SetCloseButtonStatus(bool isEnabled)3028 void PipelineContext::SetCloseButtonStatus(bool isEnabled)
3029 {
3030     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3031         return;
3032     }
3033     CHECK_NULL_VOID(rootNode_);
3034     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetChildren().front());
3035     CHECK_NULL_VOID(containerNode);
3036     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3037     CHECK_NULL_VOID(containerPattern);
3038     containerPattern->SetCloseButtonStatus(isEnabled);
3039 }
3040 
AnimateOnSafeAreaUpdate()3041 void PipelineContext::AnimateOnSafeAreaUpdate()
3042 {
3043     // complete other layout tasks before animation
3044     FlushUITasks();
3045     AnimationOption option;
3046     option.SetCurve(safeAreaManager_->GetSafeAreaCurve());
3047     AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
3048         auto self = weak.Upgrade();
3049         CHECK_NULL_VOID(self);
3050         self->SyncSafeArea();
3051         self->FlushUITasks();
3052     });
3053 }
3054 
HandleSubwindow(bool isShow)3055 void PipelineContext::HandleSubwindow(bool isShow)
3056 {
3057     // When the main window is applied to the background,
3058     // there are sub windows that do not immediately hide, such as Toast floating window
3059     if (!isShow) {
3060         overlayManager_->ClearToastInSubwindow();
3061     }
3062 }
3063 
AddIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node,const std::function<void (bool)> & eventCallback)3064 void PipelineContext::AddIsFocusActiveUpdateEvent(
3065     const RefPtr<FrameNode>& node, const std::function<void(bool)>& eventCallback)
3066 {
3067     CHECK_NULL_VOID(node);
3068     isFocusActiveUpdateEvents_.insert_or_assign(node->GetId(), eventCallback);
3069 }
3070 
RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode> & node)3071 void PipelineContext::RemoveIsFocusActiveUpdateEvent(const RefPtr<FrameNode>& node)
3072 {
3073     CHECK_NULL_VOID(node);
3074     auto iter = isFocusActiveUpdateEvents_.find(node->GetId());
3075     if (iter != isFocusActiveUpdateEvents_.end()) {
3076         isFocusActiveUpdateEvents_.erase(iter);
3077     }
3078 }
3079 
GetNavigationController(const std::string & id)3080 std::shared_ptr<NavigationController> PipelineContext::GetNavigationController(const std::string& id)
3081 {
3082     std::lock_guard lock(navigationMutex_);
3083     auto iter = navigationNodes_.find(id);
3084     if (iter == navigationNodes_.end()) {
3085         return nullptr;
3086     }
3087 
3088     auto navigationGroupNode = iter->second.Upgrade();
3089     CHECK_NULL_RETURN(navigationGroupNode, nullptr);
3090 
3091     auto navigationPattern = navigationGroupNode->GetPattern<NavigationPattern>();
3092     CHECK_NULL_RETURN(navigationPattern, nullptr);
3093     return navigationPattern->GetNavigationController();
3094 }
3095 
AddOrReplaceNavigationNode(const std::string & id,const WeakPtr<FrameNode> & node)3096 void PipelineContext::AddOrReplaceNavigationNode(const std::string& id, const WeakPtr<FrameNode>& node)
3097 {
3098     std::lock_guard lock(navigationMutex_);
3099     auto frameNode = node.Upgrade();
3100     CHECK_NULL_VOID(frameNode);
3101     auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(frameNode);
3102     CHECK_NULL_VOID(navigationGroupNode);
3103     auto oldId = navigationGroupNode->GetCurId();
3104     if (!oldId.empty() && navigationNodes_.find(oldId) != navigationNodes_.end()) {
3105         navigationNodes_.erase(oldId);
3106     }
3107 
3108     if (!id.empty()) {
3109         navigationNodes_[id] = node;
3110     }
3111 }
3112 
DeleteNavigationNode(const std::string & id)3113 void PipelineContext::DeleteNavigationNode(const std::string& id)
3114 {
3115     std::lock_guard lock(navigationMutex_);
3116     if (!id.empty() && navigationNodes_.find(id) != navigationNodes_.end()) {
3117         navigationNodes_.erase(id);
3118     }
3119 }
3120 
SetJSViewActive(bool active,WeakPtr<CustomNode> custom)3121 void PipelineContext::SetJSViewActive(bool active, WeakPtr<CustomNode> custom)
3122 {
3123     taskScheduler_->SetJSViewActive(active, custom);
3124 }
3125 
GetCurrentExtraInfo()3126 std::string PipelineContext::GetCurrentExtraInfo()
3127 {
3128     auto node = activeNode_.Upgrade();
3129     return node ? node->GetCurrentCustomNodeInfo() : std::string();
3130 }
3131 
SetCursor(int32_t cursorValue)3132 void PipelineContext::SetCursor(int32_t cursorValue)
3133 {
3134     if (cursorValue >= 0 && cursorValue <= static_cast<int32_t>(MouseFormat::RUNNING)) {
3135         auto window = GetWindow();
3136         CHECK_NULL_VOID(window);
3137         auto mouseStyle = MouseStyle::CreateMouseStyle();
3138         CHECK_NULL_VOID(mouseStyle);
3139         auto cursor = static_cast<MouseFormat>(cursorValue);
3140         window->SetCursor(cursor);
3141         window->SetUserSetCursor(true);
3142         mouseStyle->ChangePointerStyle(GetWindowId(), cursor);
3143     }
3144 }
3145 
RestoreDefault()3146 void PipelineContext::RestoreDefault()
3147 {
3148     auto window = GetWindow();
3149     CHECK_NULL_VOID(window);
3150     auto mouseStyle = MouseStyle::CreateMouseStyle();
3151     CHECK_NULL_VOID(mouseStyle);
3152     window->SetCursor(MouseFormat::DEFAULT);
3153     window->SetUserSetCursor(false);
3154     mouseStyle->ChangePointerStyle(GetWindowId(), MouseFormat::DEFAULT);
3155 }
3156 
OpenFrontendAnimation(const AnimationOption & option,const RefPtr<Curve> & curve,const std::function<void ()> & finishCallback)3157 void PipelineContext::OpenFrontendAnimation(
3158     const AnimationOption& option, const RefPtr<Curve>& curve, const std::function<void()>& finishCallback)
3159 {
3160     // push false to show we already open a animation closure.
3161     pendingFrontendAnimation_.push(false);
3162 
3163     // flush ui tasks before open animation closure.
3164     if (!isReloading_ && !IsLayouting()) {
3165         FlushUITasks();
3166     }
3167     auto wrapFinishCallback = GetWrappedAnimationCallback(finishCallback);
3168     if (IsFormRender()) {
3169         SetIsFormAnimation(true);
3170         if (!IsFormAnimationFinishCallback()) {
3171             SetFormAnimationStartTime(GetMicroTickCount());
3172         }
3173     }
3174     AnimationUtils::OpenImplicitAnimation(option, curve, wrapFinishCallback);
3175 }
3176 
CloseFrontendAnimation()3177 void PipelineContext::CloseFrontendAnimation()
3178 {
3179     if (pendingFrontendAnimation_.empty()) {
3180         return;
3181     }
3182 
3183     if (pendingFrontendAnimation_.top()) {
3184         if (!isReloading_ && !IsLayouting()) {
3185             FlushUITasks();
3186         } else if (IsLayouting()) {
3187             TAG_LOGW(AceLogTag::ACE_ANIMATION,
3188                 "IsLayouting, CloseFrontendAnimation has tasks not flushed, maybe some layout animation not generated");
3189         }
3190     }
3191     if (!pendingFrontendAnimation_.empty()) {
3192         pendingFrontendAnimation_.pop();
3193     }
3194     AnimationUtils::CloseImplicitAnimation();
3195 }
3196 
IsDragging() const3197 bool PipelineContext::IsDragging() const
3198 {
3199     if (!dragDropManager_) {
3200         return false;
3201     }
3202     bool isDragging = dragDropManager_->IsDragging();
3203     isDragging = (isDragging || dragDropManager_->IsMsdpDragging());
3204     return isDragging;
3205 }
3206 
SetIsDragging(bool isDragging)3207 void PipelineContext::SetIsDragging(bool isDragging)
3208 {
3209     if (!eventManager_) {
3210         return;
3211     }
3212     eventManager_->SetIsDragging(isDragging);
3213 }
3214 
ResetDragging()3215 void PipelineContext::ResetDragging()
3216 {
3217     CHECK_NULL_VOID(dragDropManager_);
3218     dragDropManager_->ResetDragging();
3219 }
3220 
SetContainerModalTitleVisible(bool customTitleSettedShow,bool floatingTitleSettedShow)3221 void PipelineContext::SetContainerModalTitleVisible(bool customTitleSettedShow, bool floatingTitleSettedShow)
3222 {
3223     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3224         return;
3225     }
3226     CHECK_NULL_VOID(rootNode_);
3227     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
3228     CHECK_NULL_VOID(containerNode);
3229     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3230     CHECK_NULL_VOID(containerPattern);
3231     containerPattern->SetContainerModalTitleVisible(customTitleSettedShow, floatingTitleSettedShow);
3232 }
3233 
SetContainerModalTitleHeight(int32_t height)3234 void PipelineContext::SetContainerModalTitleHeight(int32_t height)
3235 {
3236     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3237         return;
3238     }
3239     CHECK_NULL_VOID(rootNode_);
3240     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
3241     CHECK_NULL_VOID(containerNode);
3242     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3243     CHECK_NULL_VOID(containerPattern);
3244     containerPattern->SetContainerModalTitleHeight(height);
3245 }
3246 
GetContainerModalTitleHeight()3247 int32_t PipelineContext::GetContainerModalTitleHeight()
3248 {
3249     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3250         return -1;
3251     }
3252     CHECK_NULL_RETURN(rootNode_, -1);
3253     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
3254     CHECK_NULL_RETURN(containerNode, -1);
3255     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3256     CHECK_NULL_RETURN(containerPattern, -1);
3257     return containerPattern->GetContainerModalTitleHeight();
3258 }
3259 
GetContainerModalButtonsRect(RectF & containerModal,RectF & buttons)3260 bool PipelineContext::GetContainerModalButtonsRect(RectF& containerModal, RectF& buttons)
3261 {
3262     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3263         return false;
3264     }
3265     CHECK_NULL_RETURN(rootNode_, false);
3266     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
3267     CHECK_NULL_RETURN(containerNode, false);
3268     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3269     CHECK_NULL_RETURN(containerPattern, false);
3270     return containerPattern->GetContainerModalButtonsRect(containerModal, buttons);
3271 }
3272 
SubscribeContainerModalButtonsRectChange(std::function<void (RectF & containerModal,RectF & buttons)> && callback)3273 void PipelineContext::SubscribeContainerModalButtonsRectChange(
3274     std::function<void(RectF& containerModal, RectF& buttons)>&& callback)
3275 {
3276     if (windowModal_ != WindowModal::CONTAINER_MODAL) {
3277         return;
3278     }
3279     CHECK_NULL_VOID(rootNode_);
3280     auto containerNode = AceType::DynamicCast<FrameNode>(rootNode_->GetFirstChild());
3281     CHECK_NULL_VOID(containerNode);
3282     auto containerPattern = containerNode->GetPattern<ContainerModalPattern>();
3283     CHECK_NULL_VOID(containerPattern);
3284     containerPattern->SubscribeContainerModalButtonsRectChange(std::move(callback));
3285 }
3286 
GetPostEventManager()3287 const RefPtr<PostEventManager>& PipelineContext::GetPostEventManager()
3288 {
3289     return postEventManager_;
3290 }
3291 
GetSerializedGesture() const3292 const SerializedGesture& PipelineContext::GetSerializedGesture() const
3293 {
3294     return serializedGesture_;
3295 }
3296 
PrintVsyncInfoIfNeed() const3297 bool PipelineContext::PrintVsyncInfoIfNeed() const
3298 {
3299     if (dumpFrameInfos_.empty()) {
3300         return false;
3301     }
3302     auto lastFrameInfo = dumpFrameInfos_.back();
3303     const uint64_t timeout = 1000000000; // unit is ns, 1s
3304     if (lastFrameInfo.frameRecvTime_ < window_->GetLastRequestVsyncTime() &&
3305         GetSysTimestamp() - window_->GetLastRequestVsyncTime() >= timeout) {
3306         LOGW("lastRequestVsyncTime is %{public}" PRIu64 ", now time is %{public}" PRId64
3307              ", timeout, window foreground:%{public}d, lastReceiveVsync info:%{public}s",
3308             window_->GetLastRequestVsyncTime(), GetSysTimestamp(), onShow_, lastFrameInfo.GetTimeInfo().c_str());
3309         return true;
3310     }
3311     return false;
3312 }
3313 
AddSyncGeometryNodeTask(std::function<void ()> && task)3314 void PipelineContext::AddSyncGeometryNodeTask(std::function<void()>&& task)
3315 {
3316     taskScheduler_->AddSyncGeometryNodeTask(std::move(task));
3317 }
3318 
FlushSyncGeometryNodeTasks()3319 void PipelineContext::FlushSyncGeometryNodeTasks()
3320 {
3321     taskScheduler_->FlushSyncGeometryNodeTasks();
3322 }
3323 
SetUIExtensionImeShow(bool imeShow)3324 void PipelineContext::SetUIExtensionImeShow(bool imeShow)
3325 {
3326     textFieldManager_->SetUIExtensionImeShow(imeShow);
3327 }
3328 } // namespace OHOS::Ace::NG
3329