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