1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/base/frame_node.h"
17
18 #include "core/components_ng/layout/layout_algorithm.h"
19 #include "core/components_ng/render/paint_wrapper.h"
20 #include "core/pipeline/base/element_register.h"
21
22 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
23 #include "core/common/layout_inspector.h"
24 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
25 #include "core/components_ng/pattern/web/web_pattern.h"
26 #endif
27 #include "ui/view/frame_node.h"
28 #include "ui/view/pattern.h"
29
30 #include "base/geometry/ng/offset_t.h"
31 #include "base/geometry/ng/point_t.h"
32 #include "base/log/ace_performance_monitor.h"
33 #include "base/log/ace_trace.h"
34 #include "base/log/event_report.h"
35 #include "base/log/dump_log.h"
36 #include "base/log/log_wrapper.h"
37 #include "base/memory/ace_type.h"
38 #include "base/memory/referenced.h"
39 #include "base/thread/cancelable_callback.h"
40 #include "base/thread/task_executor.h"
41 #include "base/utils/system_properties.h"
42 #include "base/utils/time_util.h"
43 #include "base/utils/utils.h"
44 #include "core/common/ace_application_info.h"
45 #include "core/common/container.h"
46 #include "core/common/recorder/event_recorder.h"
47 #include "core/common/recorder/node_data_cache.h"
48 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
49 #include "core/components_ng/pattern/stage/page_pattern.h"
50 #ifdef WINDOW_SCENE_SUPPORTED
51 #include "core/components_ng/pattern/ui_extension/dynamic_component/dynamic_component_manager.h"
52 #endif
53 #include "core/components_ng/syntax/lazy_for_each_node.h"
54 #include "core/components_ng/syntax/repeat_virtual_scroll_node.h"
55
56 namespace {
57 constexpr double VISIBLE_RATIO_MIN = 0.0;
58 constexpr double VISIBLE_RATIO_MAX = 1.0;
59 constexpr int32_t SUBSTR_LENGTH = 3;
60 const char DIMENSION_UNIT_VP[] = "vp";
61 constexpr int32_t SIZE_CHANGE_DUMP_SIZE = 5;
62 constexpr double MIN_WIDTH = 5.0;
63 constexpr double MIN_HEIGHT = 5.0;
64 constexpr double MIN_OPACITY = 0.1;
65 constexpr uint64_t MATRIX_CACHE_TIME_THRESHOLD = 15000000000;
66 /* suggestOpIncByte_s status mask, to indicate different aspects of node status
67 * related with suggestion OPINC improvements.
68 * for internal use; subject to change.
69 */
70 // suggest opinc marked.
71 constexpr uint8_t SUGGEST_OPINC_MARKED_MASK = 1;
72 // Whether the node can be suggest opinc marked.
73 constexpr uint8_t CAN_SUGGEST_OPINC_MASK = 1 << 1;
74 // The node already activated for suggest opinc.
75 constexpr uint8_t SUGGEST_OPINC_ACTIVATED_ONCE = 1 << 2;
76 // The node already checked for suggest opinc.
77 constexpr uint8_t SUGGEST_OPINC_CHCKED_ONCE = 1 << 3;
78 // The node has checked through for lazy new nodes.
79 constexpr uint8_t SUGGEST_OPINC_CHECKED_THROUGH = 1 << 4;
80 // Node has rendergroup marked.
81 constexpr uint8_t APP_RENDER_GROUP_MARKED_MASK = 1 << 7;
82 // OPINC max ratio for scroll scope(height);
83 constexpr float HIGHT_RATIO_LIMIT = 0.8;
84 // Min area for OPINC
85 constexpr int32_t MIN_OPINC_AREA = 10000;
86 } // namespace
87 namespace OHOS::Ace::NG {
88
89 class FrameNode::FrameProxy final : public RecursiveLock {
90 public:
91 struct FrameChildNode {
92 RefPtr<UINode> node;
93 uint32_t startIndex = 0;
94 uint32_t count = 0;
95 };
96
Lock()97 void Lock() override
98 {
99 ++inUse_;
100 }
101
Unlock()102 void Unlock() override
103 {
104 --inUse_;
105 if (!inUse_ && delayReset_) {
106 auto it = &hostNode_->frameProxy_;
107 while ((*it)) {
108 if (this == (*it)->prevFrameProxy_.get()) {
109 auto me = std::move((*it)->prevFrameProxy_);
110 (*it)->prevFrameProxy_ = std::move(me->prevFrameProxy_);
111 break;
112 }
113 it = &(*it)->prevFrameProxy_;
114 }
115 }
116 }
117
GetGuard()118 RecursionGuard GetGuard()
119 {
120 return RecursionGuard(*this);
121 }
122
FrameProxy(FrameNode * frameNode)123 explicit FrameProxy(FrameNode* frameNode) : hostNode_(frameNode)
124 {
125 prevFrameProxy_ = std::move(hostNode_->frameProxy_);
126 if (prevFrameProxy_ && !prevFrameProxy_->needResetChild_) {
127 children_ = prevFrameProxy_->children_;
128 cursor_ = children_.end();
129 if (prevFrameProxy_->cursor_ != prevFrameProxy_->children_.end()) {
130 cursor_ = std::find_if(children_.begin(), children_.end(),
131 [this](FrameChildNode& node) { return prevFrameProxy_->cursor_->node == node.node; });
132 }
133 }
134 }
135
Build()136 void Build()
137 {
138 if (hostNode_ == nullptr || !children_.empty()) {
139 return;
140 }
141 totalCount_ = 0;
142 auto children = hostNode_->GetChildren();
143 int32_t startIndex = 0;
144 int32_t count = 0;
145 for (const auto& child : children) {
146 count = child->FrameCount();
147 child->SetNodeIndexOffset(startIndex, count);
148 children_.push_back({ child, startIndex, count });
149 startIndex += count;
150 totalCount_ += count;
151 }
152 cursor_ = children_.begin();
153 }
154
AddFrameNode(const RefPtr<UINode> & UiNode,std::list<RefPtr<LayoutWrapper>> & allFrameNodeChildren,std::map<uint32_t,RefPtr<LayoutWrapper>> & partFrameNodeChildren,uint32_t & count)155 static void AddFrameNode(const RefPtr<UINode>& UiNode, std::list<RefPtr<LayoutWrapper>>& allFrameNodeChildren,
156 std::map<uint32_t, RefPtr<LayoutWrapper>>& partFrameNodeChildren, uint32_t& count)
157 {
158 auto frameNode = AceType::DynamicCast<FrameNode>(UiNode);
159 if (frameNode) {
160 allFrameNodeChildren.emplace_back(frameNode);
161 partFrameNodeChildren[count++] = frameNode;
162 return;
163 }
164 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(UiNode);
165 auto repeatVirtualScrollNode = AceType::DynamicCast<RepeatVirtualScrollNode>(UiNode);
166 if (lazyForEachNode) {
167 lazyForEachNode->BuildAllChildren();
168 } else if (repeatVirtualScrollNode) {
169 TAG_LOGE(AceLogTag::ACE_REPEAT, "repeatVirtualScroll not support in non scoll container!");
170 } else {
171 auto customNode = AceType::DynamicCast<CustomNode>(UiNode);
172 if (customNode) {
173 customNode->Render();
174 }
175 }
176 for (const auto& child : UiNode->GetChildren()) {
177 auto frameNode = AceType::DynamicCast<FrameNode>(child);
178 if (frameNode) {
179 allFrameNodeChildren.emplace_back(frameNode);
180 partFrameNodeChildren[count++] = frameNode;
181 continue;
182 }
183 AddFrameNode(child, allFrameNodeChildren, partFrameNodeChildren, count);
184 }
185 }
186
GetAllFrameChildren()187 ChildrenListWithGuard GetAllFrameChildren()
188 {
189 auto guard = GetGuard();
190 if (allFrameNodeChildren_.empty()) {
191 Build();
192 uint32_t count = 0;
193 for (const auto& child : children_) {
194 AddFrameNode(child.node, allFrameNodeChildren_, partFrameNodeChildren_, count);
195 }
196 }
197 return ChildrenListWithGuard(allFrameNodeChildren_, *this);
198 }
199
FindFrameNodeByIndex(uint32_t index,bool needBuild,bool isCache,bool addToRenderTree)200 RefPtr<LayoutWrapper> FindFrameNodeByIndex(uint32_t index, bool needBuild, bool isCache, bool addToRenderTree)
201 {
202 while (cursor_ != children_.end()) {
203 if (cursor_->startIndex > index) {
204 cursor_--;
205 continue;
206 }
207
208 if (cursor_->startIndex + cursor_->count > index) {
209 auto frameNode = AceType::DynamicCast<FrameNode>(cursor_->node->GetFrameChildByIndex(
210 index - cursor_->startIndex, needBuild, isCache, addToRenderTree));
211 return frameNode;
212 }
213 cursor_++;
214 if (cursor_ == children_.end()) {
215 cursor_ = children_.begin();
216 return nullptr;
217 }
218 }
219 return nullptr;
220 }
221
GetFrameNodeByIndex(uint32_t index,bool needBuild,bool isCache,bool addToRenderTree)222 RefPtr<LayoutWrapper> GetFrameNodeByIndex(uint32_t index, bool needBuild, bool isCache, bool addToRenderTree)
223 {
224 auto itor = partFrameNodeChildren_.find(index);
225 if (itor == partFrameNodeChildren_.end()) {
226 Build();
227 auto child = FindFrameNodeByIndex(index, needBuild, isCache, addToRenderTree);
228 if (child && !isCache) {
229 partFrameNodeChildren_[index] = child;
230 }
231 return child;
232 }
233 return itor->second;
234 }
235
236 /**
237 * @brief Find child's index in parent's map. Only works on children that are already created and recorded.
238 *
239 * @param target child LayoutWrapper
240 * @return index of children
241 */
GetChildIndex(const RefPtr<LayoutWrapper> & target) const242 int32_t GetChildIndex(const RefPtr<LayoutWrapper>& target) const
243 {
244 for (auto it : partFrameNodeChildren_) {
245 if (it.second == target) {
246 return it.first;
247 }
248 }
249 return -1;
250 }
251
ResetChildren(bool needResetChild=false)252 void ResetChildren(bool needResetChild = false)
253 {
254 if (inUse_) {
255 if (SystemProperties::GetLayoutDetectEnabled()) {
256 LOGF_ABORT("[%{public}d:%{public}s] reset children while in use",
257 hostNode_->GetId(), hostNode_->GetTag().c_str());
258 } else {
259 LOGW("[%{public}d:%{public}s] reset children while in use",
260 hostNode_->GetId(), hostNode_->GetTag().c_str());
261 }
262 delayReset_ = true;
263 needResetChild_ = needResetChild;
264 hostNode_->frameProxy_ = std::make_unique<FrameProxy>(hostNode_);
265 return;
266 }
267 auto guard = GetGuard();
268 delayReset_ = false;
269 allFrameNodeChildren_.clear();
270 partFrameNodeChildren_.clear();
271 totalCount_ = 0;
272 if (needResetChild) {
273 children_.clear();
274 cursor_ = children_.begin();
275 }
276 }
277
RemoveChildInRenderTree(uint32_t index)278 void RemoveChildInRenderTree(uint32_t index)
279 {
280 auto itor = partFrameNodeChildren_.find(index);
281 if (itor == partFrameNodeChildren_.end()) {
282 return;
283 }
284 itor->second->SetActive(false);
285 partFrameNodeChildren_.erase(itor);
286 while (cursor_ != children_.end()) {
287 if (cursor_->startIndex > index) {
288 cursor_--;
289 continue;
290 }
291 if (cursor_->startIndex + cursor_->count > index) {
292 cursor_->node->DoRemoveChildInRenderTree(index - cursor_->startIndex);
293 return;
294 }
295 cursor_++;
296 if (cursor_ == children_.end()) {
297 cursor_ = children_.begin();
298 return;
299 }
300 }
301 }
302
SetActiveChildRange(int32_t start,int32_t end,int32_t cacheStart,int32_t cacheEnd,bool showCache=false)303 void SetActiveChildRange(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache = false)
304 {
305 int32_t startIndex = showCache ? start - cacheStart : start;
306 int32_t endIndex = showCache ? end + cacheEnd : end;
307 for (auto itor = partFrameNodeChildren_.begin(); itor != partFrameNodeChildren_.end();) {
308 int32_t index = itor->first;
309 if ((startIndex <= endIndex && index >= startIndex && index <= endIndex) ||
310 (startIndex > endIndex && (index <= endIndex || startIndex <= index))) {
311 itor++;
312 } else {
313 itor = partFrameNodeChildren_.erase(itor);
314 }
315 }
316 auto guard = GetGuard();
317 for (const auto& child : children_) {
318 child.node->DoSetActiveChildRange(
319 start - child.startIndex, end - child.startIndex, cacheStart, cacheEnd, showCache);
320 }
321 }
322
SetActiveChildRange(const std::optional<ActiveChildSets> & activeChildSets,const std::optional<ActiveChildRange> & activeChildRange)323 void SetActiveChildRange(
324 const std::optional<ActiveChildSets>& activeChildSets, const std::optional<ActiveChildRange>& activeChildRange)
325 {
326 if (!activeChildSets.has_value()) {
327 return;
328 }
329 for (auto itor = partFrameNodeChildren_.begin(); itor != partFrameNodeChildren_.end();) {
330 int32_t index = itor->first;
331 if (activeChildSets->activeItems.find(index) != activeChildSets->activeItems.end()) {
332 itor++;
333 } else {
334 itor = partFrameNodeChildren_.erase(itor);
335 }
336 }
337 auto guard = GetGuard();
338 // repeat node will use active node sets, V1 node(as lazyforeach) will still use active ndoe range.
339 for (const auto& child : children_) {
340 if (child.node->GetTag() == V2::JS_REPEAT_ETS_TAG) {
341 child.node->DoSetActiveChildRange(
342 activeChildSets->activeItems, activeChildSets->cachedItems, child.startIndex);
343 } else if (activeChildRange.has_value()) {
344 child.node->DoSetActiveChildRange(activeChildRange->start - child.startIndex,
345 activeChildRange->end - child.startIndex, activeChildRange->cacheStart, activeChildRange->cacheEnd);
346 }
347 }
348 }
349
RecycleItemsByIndex(uint32_t start,uint32_t end)350 void RecycleItemsByIndex(uint32_t start, uint32_t end)
351 {
352 for (auto it = partFrameNodeChildren_.begin(); it != partFrameNodeChildren_.end();) {
353 if (it->first >= start && it->first < end) {
354 it = partFrameNodeChildren_.erase(it);
355 } else {
356 it++;
357 }
358 }
359 }
360
RemoveAllChildInRenderTreeAfterReset()361 void RemoveAllChildInRenderTreeAfterReset()
362 {
363 Build();
364 auto guard = GetGuard();
365 for (const auto& child : children_) {
366 child.node->DoRemoveChildInRenderTree(0, true);
367 }
368 }
369
RemoveAllChildInRenderTree()370 void RemoveAllChildInRenderTree()
371 {
372 SetAllChildrenInactive();
373 ResetChildren();
374 hostNode_->frameProxy_->RemoveAllChildInRenderTreeAfterReset();
375 }
376
GetTotalCount()377 uint32_t GetTotalCount()
378 {
379 return totalCount_;
380 }
381
SetAllChildrenInactive()382 void SetAllChildrenInactive()
383 {
384 auto guard = GetGuard();
385 for (const auto& child : partFrameNodeChildren_) {
386 child.second->SetActive(false);
387 }
388 }
389
Dump()390 std::string Dump()
391 {
392 if (totalCount_ == 0) {
393 return "totalCount is 0";
394 }
395 std::string info = "FrameChildNode:[";
396 auto guard = GetGuard();
397 for (const auto& child : children_) {
398 info += std::to_string(child.node->GetId());
399 info += "-";
400 info += std::to_string(child.startIndex);
401 info += "-";
402 info += std::to_string(child.count);
403 info += ",";
404 }
405 info += "] partFrameNodeChildren:[";
406 for (const auto& child : partFrameNodeChildren_) {
407 info += std::to_string(child.second->GetHostNode()->GetId());
408 info += ",";
409 }
410 info += "] TotalCount:";
411 info += std::to_string(totalCount_);
412 return info;
413 }
414
SetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)415 void SetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint)
416 {
417 auto guard = GetGuard();
418 for (const auto& child : children_) {
419 child.node->OnSetCacheCount(cacheCount, itemConstraint);
420 }
421 }
422
423 private:
424 std::list<FrameChildNode> children_;
425 std::list<FrameChildNode>::iterator cursor_ = children_.begin();
426 std::list<RefPtr<LayoutWrapper>> allFrameNodeChildren_;
427 std::map<uint32_t, RefPtr<LayoutWrapper>> partFrameNodeChildren_;
428 std::unique_ptr<FrameProxy> prevFrameProxy_;
429 int32_t totalCount_ = 0;
430 FrameNode* hostNode_ { nullptr };
431 uint32_t inUse_ = 0;
432 bool delayReset_ = false;
433 bool needResetChild_ = false;
434 }; // namespace OHOS::Ace::NG
435
FrameNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern,bool isRoot,bool isLayoutNode)436 FrameNode::FrameNode(
437 const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern, bool isRoot, bool isLayoutNode)
438 : UINode(tag, nodeId, isRoot), LayoutWrapper(WeakClaim(this)), pattern_(pattern)
439 {
440 isLayoutNode_ = isLayoutNode;
441 frameProxy_ = std::make_unique<FrameProxy>(this);
442 renderContext_->InitContext(IsRootNode(), pattern_->GetContextParam(), isLayoutNode);
443 paintProperty_ = pattern->CreatePaintProperty();
444 layoutProperty_ = pattern->CreateLayoutProperty();
445 accessibilityProperty_ = pattern->CreateAccessibilityProperty();
446 // first create make layout property dirty.
447 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
448 layoutProperty_->SetHost(WeakClaim(this));
449 layoutSeperately_ = true;
450 paintProperty_->SetHost(WeakClaim(this));
451 }
452
~FrameNode()453 FrameNode::~FrameNode()
454 {
455 ResetPredictNodes();
456 for (const auto& destroyCallback : destroyCallbacksMap_) {
457 if (destroyCallback.second) {
458 destroyCallback.second();
459 }
460 }
461 if (removeCustomProperties_) {
462 removeCustomProperties_();
463 removeCustomProperties_ = nullptr;
464 }
465
466 pattern_->DetachFromFrameNode(this);
467 if (IsOnMainTree()) {
468 OnDetachFromMainTree(false, GetContextWithCheck());
469 }
470 HandleAreaChangeDestruct();
471 auto pipeline = PipelineContext::GetCurrentContext();
472 if (pipeline) {
473 pipeline->RemoveOnAreaChangeNode(GetId());
474 pipeline->RemoveVisibleAreaChangeNode(GetId());
475 pipeline->ChangeMouseStyle(GetId(), MouseFormat::DEFAULT);
476 pipeline->FreeMouseStyleHoldNode(GetId());
477 pipeline->RemoveStoredNode(GetRestoreId());
478 auto dragManager = pipeline->GetDragDropManager();
479 if (dragManager) {
480 dragManager->RemoveDragFrameNode(GetId());
481 dragManager->UnRegisterDragStatusListener(GetId());
482 }
483 auto frameRateManager = pipeline->GetFrameRateManager();
484 if (frameRateManager) {
485 frameRateManager->RemoveNodeRate(GetId());
486 }
487 pipeline->RemoveChangedFrameNode(GetId());
488 pipeline->RemoveFrameNodeChangeListener(GetId());
489 }
490 FireOnNodeDestroyCallback();
491 FireOnExtraNodeDestroyCallback();
492 FireFrameNodeDestructorCallback();
493 if (kitNode_) {
494 kitNode_->Reset();
495 }
496 }
497
CreateEventHubInner()498 void FrameNode::CreateEventHubInner()
499 {
500 if (eventHub_ || !pattern_) {
501 return;
502 }
503 eventHub_ = pattern_->CreateEventHub();
504 if (eventHub_) {
505 eventHub_->AttachHost(WeakClaim(this));
506 }
507 }
508
CreateFrameNodeWithTree(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern)509 RefPtr<FrameNode> FrameNode::CreateFrameNodeWithTree(
510 const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
511 {
512 auto newChild = CreateFrameNode(tag, nodeId, pattern, true);
513 newChild->SetDepth(1);
514 return newChild;
515 }
516
GetOrCreateFrameNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)517 RefPtr<FrameNode> FrameNode::GetOrCreateFrameNode(
518 const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
519 {
520 auto frameNode = GetFrameNode(tag, nodeId);
521 if (frameNode) {
522 return frameNode;
523 }
524 auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
525 return CreateFrameNode(tag, nodeId, pattern);
526 }
527
GetOrCreateCommonNode(const std::string & tag,int32_t nodeId,bool isLayoutNode,const std::function<RefPtr<Pattern> (void)> & patternCreator)528 RefPtr<FrameNode> FrameNode::GetOrCreateCommonNode(const std::string& tag, int32_t nodeId, bool isLayoutNode,
529 const std::function<RefPtr<Pattern>(void)>& patternCreator)
530 {
531 auto commonNode = GetFrameNode(tag, nodeId);
532 if (commonNode) {
533 commonNode->isLayoutNode_ = isLayoutNode;
534 return commonNode;
535 }
536 auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
537 return CreateCommonNode(tag, nodeId, isLayoutNode, pattern);
538 }
539
GetFrameNode(const std::string & tag,int32_t nodeId)540 RefPtr<FrameNode> FrameNode::GetFrameNode(const std::string& tag, int32_t nodeId)
541 {
542 auto frameNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(nodeId);
543 CHECK_NULL_RETURN(frameNode, nullptr);
544 if (frameNode->GetTag() != tag) {
545 ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
546 auto parent = frameNode->GetParent();
547 if (parent) {
548 parent->RemoveChild(frameNode);
549 }
550 return nullptr;
551 }
552 return frameNode;
553 }
554
GetFrameNodeOnly(const std::string & tag,int32_t nodeId)555 RefPtr<FrameNode> FrameNode::GetFrameNodeOnly(const std::string& tag, int32_t nodeId)
556 {
557 auto frameNode = ElementRegister::GetInstance()->GetSpecificItemById<FrameNode>(nodeId);
558 CHECK_NULL_RETURN(frameNode, nullptr);
559 if (frameNode->GetTag() != tag) {
560 return nullptr;
561 }
562 return frameNode;
563 }
564
CreateFrameNode(const std::string & tag,int32_t nodeId,const RefPtr<Pattern> & pattern,bool isRoot)565 RefPtr<FrameNode> FrameNode::CreateFrameNode(
566 const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern, bool isRoot)
567 {
568 auto frameNode = MakeRefPtr<FrameNode>(tag, nodeId, pattern, isRoot);
569 ElementRegister::GetInstance()->AddUINode(frameNode);
570 frameNode->InitializePatternAndContext();
571 return frameNode;
572 }
573
CreateCommonNode(const std::string & tag,int32_t nodeId,bool isLayoutNode,const RefPtr<Pattern> & pattern,bool isRoot)574 RefPtr<FrameNode> FrameNode::CreateCommonNode(
575 const std::string& tag, int32_t nodeId, bool isLayoutNode, const RefPtr<Pattern>& pattern, bool isRoot)
576 {
577 auto frameNode = MakeRefPtr<FrameNode>(tag, nodeId, pattern, isRoot, isLayoutNode);
578 ElementRegister::GetInstance()->AddUINode(frameNode);
579 frameNode->InitializePatternAndContext();
580 return frameNode;
581 }
582
GetIsLayoutNode()583 bool FrameNode::GetIsLayoutNode()
584 {
585 return isLayoutNode_;
586 }
587
GetIsFind()588 bool FrameNode::GetIsFind()
589 {
590 return isFind_;
591 }
592
SetIsFind(bool isFind)593 void FrameNode::SetIsFind(bool isFind)
594 {
595 isFind_ = isFind;
596 }
597
GetOneDepthVisibleFrame(std::list<RefPtr<FrameNode>> & children)598 void FrameNode::GetOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& children)
599 {
600 GenerateOneDepthVisibleFrameWithTransition(children);
601 if (overlayNode_) {
602 children.emplace_back(overlayNode_);
603 }
604 }
605
GetOneDepthVisibleFrameWithOffset(std::list<RefPtr<FrameNode>> & children,OffsetF & offset)606 void FrameNode::GetOneDepthVisibleFrameWithOffset(std::list<RefPtr<FrameNode>>& children, OffsetF& offset)
607 {
608 auto context = GetRenderContext();
609 CHECK_NULL_VOID(context);
610 offset += context->GetPaintRectWithoutTransform().GetOffset();
611 GenerateOneDepthVisibleFrameWithOffset(children, offset);
612 if (overlayNode_) {
613 children.emplace_back(overlayNode_);
614 }
615 }
616
IsSupportDrawModifier()617 bool FrameNode::IsSupportDrawModifier()
618 {
619 CHECK_NULL_RETURN(pattern_, false);
620 return pattern_->IsSupportDrawModifier();
621 }
622
ProcessOffscreenNode(const RefPtr<FrameNode> & node,bool needRemainActive)623 void FrameNode::ProcessOffscreenNode(const RefPtr<FrameNode>& node, bool needRemainActive)
624 {
625 CHECK_NULL_VOID(node);
626 auto task = [weak = AceType::WeakClaim(AceType::RawPtr(node)), needRemainActive]() {
627 auto node = weak.Upgrade();
628 CHECK_NULL_VOID(node);
629 node->ProcessOffscreenTask();
630 node->MarkModifyDone();
631 node->UpdateLayoutPropertyFlag();
632 bool isActive = node->IsActive();
633 node->SetActive();
634 node->isLayoutDirtyMarked_ = true;
635 auto pipeline = node->GetContext();
636 if (pipeline) {
637 pipeline->FlushUITaskWithSingleDirtyNode(node);
638 }
639 auto predictLayoutNode = std::move(node->predictLayoutNode_);
640 for (auto& node : predictLayoutNode) {
641 auto frameNode = node.Upgrade();
642 if (frameNode && pipeline) {
643 pipeline->FlushUITaskWithSingleDirtyNode(frameNode);
644 }
645 }
646 if (pipeline) {
647 pipeline->FlushSyncGeometryNodeTasks();
648 }
649
650 auto paintProperty = node->GetPaintProperty<PaintProperty>();
651 auto wrapper = node->CreatePaintWrapper();
652 if (wrapper != nullptr) {
653 wrapper->FlushRender();
654 }
655 paintProperty->CleanDirty();
656 CHECK_NULL_VOID(pipeline);
657 pipeline->FlushModifier();
658 pipeline->FlushMessages();
659 if (needRemainActive) {
660 node->SetActive(isActive);
661 } else {
662 node->SetActive(false);
663 }
664 };
665 auto pipeline = node->GetContext();
666 if (pipeline && pipeline->IsLayouting()) {
667 pipeline->AddAfterLayoutTask(task);
668 return;
669 }
670 task();
671 }
672
InitializePatternAndContext()673 void FrameNode::InitializePatternAndContext()
674 {
675 pattern_->AttachToFrameNode(WeakClaim(this));
676 accessibilityProperty_->SetHost(WeakClaim(this));
677 renderContext_->SetRequestFrame([weak = WeakClaim(this)] {
678 auto frameNode = weak.Upgrade();
679 CHECK_NULL_VOID(frameNode);
680 if (frameNode->IsOnMainTree()) {
681 auto context = frameNode->GetContext();
682 CHECK_NULL_VOID(context);
683 context->RequestFrame();
684 return;
685 }
686 frameNode->hasPendingRequest_ = true;
687 });
688 renderContext_->SetHostNode(WeakClaim(this));
689 // Initialize FocusHub
690 if (pattern_->GetFocusPattern().GetFocusType() != FocusType::DISABLE) {
691 GetOrCreateFocusHub();
692 }
693 }
694
DumpSafeAreaInfo()695 void FrameNode::DumpSafeAreaInfo()
696 {
697 auto&& opts = layoutProperty_->GetSafeAreaExpandOpts();
698 if (opts) {
699 DumpLog::GetInstance().AddDesc(layoutProperty_->GetSafeAreaExpandOpts()
700 ->ToString()
701 .append(",hostPageId: ")
702 .append(std::to_string(GetPageId()).c_str()));
703 }
704 if (layoutProperty_->GetSafeAreaInsets()) {
705 DumpLog::GetInstance().AddDesc(layoutProperty_->GetSafeAreaInsets()->ToString());
706 }
707 if (SelfOrParentExpansive()) {
708 DumpLog::GetInstance().AddDesc(std::string("selfAdjust: ")
709 .append(geometryNode_->GetSelfAdjust().ToString().c_str())
710 .append(",parentAdjust: ")
711 .append(geometryNode_->GetParentAdjust().ToString().c_str()));
712 }
713 CHECK_NULL_VOID(GetTag() == V2::PAGE_ETS_TAG);
714 auto pipeline = GetContext();
715 CHECK_NULL_VOID(pipeline);
716 auto manager = pipeline->GetSafeAreaManager();
717 CHECK_NULL_VOID(manager);
718 DumpLog::GetInstance().AddDesc(std::string("ignoreSafeArea: ")
719 .append(std::to_string(manager->IsIgnoreSafeArea()))
720 .append(std::string(", isNeedAvoidWindow: ").c_str())
721 .append(std::to_string(manager->IsNeedAvoidWindow()))
722 .append(std::string(", isFullScreen: ").c_str())
723 .append(std::to_string(manager->IsFullScreen()))
724 .append(std::string(", isKeyboardAvoidMode").c_str())
725 .append(std::to_string(static_cast<int32_t>(manager->GetKeyBoardAvoidMode())))
726 .append(std::string(", isUseCutout").c_str())
727 .append(std::to_string(manager->GetUseCutout())));
728 }
729
DumpAlignRulesInfo()730 void FrameNode::DumpAlignRulesInfo()
731 {
732 auto& flexItemProperties = layoutProperty_->GetFlexItemProperty();
733 CHECK_NULL_VOID(flexItemProperties);
734 auto rulesToString = flexItemProperties->AlignRulesToString();
735 CHECK_NULL_VOID(!rulesToString.empty());
736 DumpLog::GetInstance().AddDesc(std::string("AlignRules: ").append(rulesToString));
737 }
738
DumpExtensionHandlerInfo()739 void FrameNode::DumpExtensionHandlerInfo()
740 {
741 if (!extensionHandler_) {
742 return;
743 }
744 DumpLog::GetInstance().AddDesc(std::string("ExtensionHandler: HasCustomerMeasure: ")
745 .append(extensionHandler_->HasCustomerMeasure() ? "true" : "false")
746 .append(", HasCustomerLayout: ")
747 .append(extensionHandler_->HasCustomerLayout() ? "true" : "false"));
748 }
749
DumpCommonInfo()750 void FrameNode::DumpCommonInfo()
751 {
752 DumpLog::GetInstance().AddDesc(std::string("FrameRect: ").append(geometryNode_->GetFrameRect().ToString()));
753 DumpLog::GetInstance().AddDesc(
754 std::string("PaintRect without transform: ").append(renderContext_->GetPaintRectWithoutTransform().ToString()));
755 if (renderContext_->GetBackgroundColor()->ColorToString().compare("#00000000") != 0) {
756 DumpLog::GetInstance().AddDesc(
757 std::string("BackgroundColor: ").append(renderContext_->GetBackgroundColor()->ColorToString()));
758 }
759 if (geometryNode_->GetParentLayoutConstraint().has_value())
760 DumpLog::GetInstance().AddDesc(std::string("ParentLayoutConstraint: ")
761 .append(geometryNode_->GetParentLayoutConstraint().value().ToString()));
762 if (!(NearZero(GetOffsetRelativeToWindow().GetY()) && NearZero(GetOffsetRelativeToWindow().GetX()))) {
763 DumpLog::GetInstance().AddDesc(std::string("top: ")
764 .append(std::to_string(GetOffsetRelativeToWindow().GetY()))
765 .append(" left: ")
766 .append(std::to_string(GetOffsetRelativeToWindow().GetX())));
767 }
768 if (static_cast<int32_t>(IsActive()) != 1) {
769 DumpLog::GetInstance().AddDesc(
770 std::string("Active: ").append(std::to_string(static_cast<int32_t>(IsActive()))));
771 }
772 if (IsFreeze()) {
773 DumpLog::GetInstance().AddDesc(std::string("Freeze: 1"));
774 if (IsUserFreeze()) {
775 DumpLog::GetInstance().AddDesc(std::string("UserFreeze: 1"));
776 }
777 }
778 if (static_cast<int32_t>(layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE)) != 0) {
779 DumpLog::GetInstance().AddDesc(std::string("Visible: ")
780 .append(PrintVisibilityDumpInfo().c_str()));
781 }
782 if (layoutProperty_->GetPaddingProperty()) {
783 DumpLog::GetInstance().AddDesc(
784 std::string("Padding: ").append(layoutProperty_->GetPaddingProperty()->ToString().c_str()));
785 }
786 if (layoutProperty_->GetSafeAreaPaddingProperty()) {
787 DumpLog::GetInstance().AddDesc(std::string("SafeArea Padding: ")
788 .append(layoutProperty_->GetSafeAreaPaddingProperty()->ToString().c_str()));
789 }
790 if (layoutProperty_->GetBorderWidthProperty()) {
791 DumpLog::GetInstance().AddDesc(
792 std::string("Border: ").append(layoutProperty_->GetBorderWidthProperty()->ToString().c_str()));
793 }
794 if (layoutProperty_->GetMarginProperty()) {
795 DumpLog::GetInstance().AddDesc(
796 std::string("Margin: ").append(layoutProperty_->GetMarginProperty()->ToString().c_str()));
797 }
798 if (layoutProperty_->GetLayoutRect()) {
799 DumpLog::GetInstance().AddDesc(
800 std::string("LayoutRect: ").append(layoutProperty_->GetLayoutRect().value().ToString().c_str()));
801 }
802 DumpExtensionHandlerInfo();
803 DumpSafeAreaInfo();
804 if (layoutProperty_->GetCalcLayoutConstraint()) {
805 DumpLog::GetInstance().AddDesc(std::string("User defined constraint: ")
806 .append(layoutProperty_->GetCalcLayoutConstraint()->ToString().c_str()));
807 }
808 if (!propInspectorId_->empty()) {
809 DumpLog::GetInstance().AddDesc(std::string("compid: ").append(propInspectorId_.value_or("")));
810 }
811 if (layoutProperty_->GetPaddingProperty() || layoutProperty_->GetBorderWidthProperty() ||
812 layoutProperty_->GetMarginProperty() || layoutProperty_->GetCalcLayoutConstraint()) {
813 DumpLog::GetInstance().AddDesc(
814 std::string("ContentConstraint: ")
815 .append(layoutProperty_->GetContentLayoutConstraint().has_value()
816 ? layoutProperty_->GetContentLayoutConstraint().value().ToString()
817 : "NA"));
818 }
819 if (NearZero(renderContext_->GetZIndexValue(ZINDEX_DEFAULT_VALUE))) {
820 DumpLog::GetInstance().AddDesc(
821 std::string("zIndex: ").append(std::to_string(renderContext_->GetZIndexValue(ZINDEX_DEFAULT_VALUE))));
822 }
823 if (GetTag() == V2::ROOT_ETS_TAG) {
824 auto pipeline = GetContext();
825 CHECK_NULL_VOID(pipeline);
826 DumpLog::GetInstance().AddDesc(std::string("dpi: ").append(std::to_string(pipeline->GetDensity())));
827 }
828 DumpAlignRulesInfo();
829 DumpDragInfo();
830 DumpOverlayInfo();
831 if (frameProxy_->Dump().compare("totalCount is 0") != 0) {
832 DumpLog::GetInstance().AddDesc(std::string("FrameProxy: ").append(frameProxy_->Dump().c_str()));
833 }
834 if (isRemoving_) {
835 DumpLog::GetInstance().AddDesc(std::string("IsRemoving: True"));
836 }
837 }
838
DumpDragInfo()839 void FrameNode::DumpDragInfo()
840 {
841 DumpLog::GetInstance().AddDesc("------------start print dragInfo");
842 DumpLog::GetInstance().AddDesc(std::string("Draggable: ")
843 .append(draggable_ ? "true" : "false")
844 .append(" UserSet: ")
845 .append(userSet_ ? "true" : "false")
846 .append(" CustomerSet: ")
847 .append(customerSet_ ? "true" : "false"));
848 auto dragPreviewStr =
849 std::string("DragPreview: Has customNode: ").append(dragPreviewInfo_.customNode ? "YES" : "NO");
850 dragPreviewStr.append(" Has pixelMap: ").append(dragPreviewInfo_.pixelMap ? "YES" : "NO");
851 dragPreviewStr.append(" extraInfo: ").append(dragPreviewInfo_.extraInfo.c_str());
852 dragPreviewStr.append(" inspectorId: ").append(dragPreviewInfo_.inspectorId.c_str());
853 DumpLog::GetInstance().AddDesc(dragPreviewStr);
854 auto eventHub = GetEventHubOnly<EventHub>();
855 DumpLog::GetInstance().AddDesc(std::string("Event: ")
856 .append("OnDragStart: ")
857 .append(eventHub && eventHub->HasOnDragStart() ? "YES" : "NO")
858 .append(" OnDragEnter: ")
859 .append(eventHub && eventHub->HasOnDragEnter() ? "YES" : "NO")
860 .append(" OnDragLeave: ")
861 .append(eventHub && eventHub->HasOnDragLeave() ? "YES" : "NO")
862 .append(" OnDragMove: ")
863 .append(eventHub && eventHub->HasOnDragMove() ? "YES" : "NO")
864 .append(" OnDrop: ")
865 .append(eventHub && eventHub->HasOnDrop() ? "YES" : "NO")
866 .append(" OnDragEnd: ")
867 .append(eventHub && eventHub->HasOnDragEnd() ? "YES" : "NO"));
868 DumpLog::GetInstance().AddDesc(std::string("DefaultOnDragStart: ")
869 .append(eventHub && eventHub->HasDefaultOnDragStart() ? "YES" : "NO")
870 .append(" CustomerOnDragEnter: ")
871 .append(eventHub && eventHub->HasCustomerOnDragEnter() ? "YES" : "NO")
872 .append(" CustomerOnDragLeave: ")
873 .append(eventHub && eventHub->HasCustomerOnDragLeave() ? "YES" : "NO")
874 .append(" CustomerOnDragMove: ")
875 .append(eventHub && eventHub->HasCustomerOnDragMove() ? "YES" : "NO")
876 .append(" CustomerOnDrop: ")
877 .append(eventHub && eventHub->HasCustomerOnDrop() ? "YES" : "NO")
878 .append(" CustomerOnDragEnd: ")
879 .append(eventHub && eventHub->HasCustomerOnDragEnd() ? "YES" : "NO"));
880 DumpLog::GetInstance().AddDesc("------------end print dragInfo");
881 }
882
DumpOnSizeChangeInfo()883 void FrameNode::DumpOnSizeChangeInfo()
884 {
885 for (auto it = onSizeChangeDumpInfos.rbegin(); it != onSizeChangeDumpInfos.rend(); ++it) {
886 DumpLog::GetInstance().AddDesc(std::string("onSizeChange Time: ")
887 .append(ConvertTimestampToStr(it->onSizeChangeTimeStamp))
888 .append(" lastFrameRect: ")
889 .append(it->lastFrameRect.ToString())
890 .append(" currFrameRect: ")
891 .append(it->currFrameRect.ToString()));
892 }
893 }
894
DumpKeyboardShortcutInfo()895 void FrameNode::DumpKeyboardShortcutInfo()
896 {
897 auto eventHub = GetEventHubOnly<EventHub>();
898 if (!eventHub) {
899 return;
900 }
901 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
902 std::string result;
903 for (auto& keyboardShortcut : keyboardShortcuts) {
904 result.append("KeyboardShortcut: ")
905 .append("keys: ")
906 .append(std::to_string(keyboardShortcut.keys))
907 .append(" value: ")
908 .append(keyboardShortcut.value);
909 }
910 DumpLog::GetInstance().AddDesc(result);
911 }
912
DumpOverlayInfo()913 void FrameNode::DumpOverlayInfo()
914 {
915 if (!layoutProperty_->IsOverlayNode()) {
916 return;
917 }
918 DumpLog::GetInstance().AddDesc(std::string("IsOverlayNode: ").append(std::string("true")));
919 Dimension offsetX, offsetY;
920 layoutProperty_->GetOverlayOffset(offsetX, offsetY);
921 DumpLog::GetInstance().AddDesc(
922 std::string("OverlayOffset: ").append(offsetX.ToString()).append(std::string(", ")).append(offsetY.ToString()));
923 }
924
DumpSimplifyCommonInfo(std::unique_ptr<JsonValue> & json)925 void FrameNode::DumpSimplifyCommonInfo(std::unique_ptr<JsonValue>& json)
926 {
927 json->Put("$rect", GetTransformRectRelativeToWindow().ToBounds().c_str());
928 json->Put("$debugLine", "");
929 }
930
DumpPadding(const std::unique_ptr<NG::PaddingProperty> & padding,std::string label,std::unique_ptr<JsonValue> & json)931 void FrameNode::DumpPadding(const std::unique_ptr<NG::PaddingProperty>& padding, std::string label,
932 std::unique_ptr<JsonValue>& json)
933 {
934 CHECK_NULL_VOID(padding);
935 NG::CalcLength defaultValue = NG::CalcLength(
936 Dimension(0, padding->left.value_or(CalcLength()).GetDimension().Unit()));
937 if (padding->left.value_or(defaultValue) != defaultValue || padding->right.value_or(defaultValue) != defaultValue ||
938 padding->top.value_or(defaultValue) != defaultValue || padding->bottom.value_or(defaultValue) != defaultValue) {
939 json->Put(label.c_str(), padding->ToString().c_str());
940 }
941 }
942
DumpBorder(const std::unique_ptr<NG::BorderWidthProperty> & border,std::string label,std::unique_ptr<JsonValue> & json)943 void FrameNode::DumpBorder(const std::unique_ptr<NG::BorderWidthProperty>& border, std::string label,
944 std::unique_ptr<JsonValue>& json)
945 {
946 CHECK_NULL_VOID(border);
947 Dimension defaultValue(0, border->leftDimen.value_or(Dimension()).Unit());
948 if (border->leftDimen.value_or(defaultValue) != defaultValue ||
949 border->rightDimen.value_or(defaultValue) != defaultValue ||
950 border->topDimen.value_or(defaultValue) != defaultValue ||
951 border->bottomDimen.value_or(defaultValue) != defaultValue) {
952 json->Put(label.c_str(), border->ToString().c_str());
953 }
954 }
955
DumpSimplifySafeAreaInfo(std::unique_ptr<JsonValue> & json)956 void FrameNode::DumpSimplifySafeAreaInfo(std::unique_ptr<JsonValue>& json)
957 {
958 auto&& opts = layoutProperty_->GetSafeAreaExpandOpts();
959 if (opts && (opts->type != NG::SAFE_AREA_TYPE_NONE || opts->edges != NG::SAFE_AREA_EDGE_NONE)) {
960 json->Put("SafeAreaExpandOpts", opts->ToString().c_str());
961 }
962 if (layoutProperty_->GetSafeAreaInsets()) {
963 json->Put("SafeAreaInsets", layoutProperty_->GetSafeAreaInsets()->ToString().c_str());
964 }
965 if (SelfOrParentExpansive()) {
966 RectF defaultValue(0.0, 0.0, 0.0, 0.0);
967 auto rect = geometryNode_->GetSelfAdjust();
968 auto parentRect = geometryNode_->GetParentAdjust();
969 if (rect != defaultValue) {
970 json->Put("SelfAdjust", rect.ToString().c_str());
971 }
972 if (parentRect != defaultValue) {
973 json->Put("ParentSelfAdjust", parentRect.ToString().c_str());
974 }
975 }
976 CHECK_NULL_VOID(GetTag() == V2::PAGE_ETS_TAG);
977 auto pipeline = GetContext();
978 CHECK_NULL_VOID(pipeline);
979 auto manager = pipeline->GetSafeAreaManager();
980 CHECK_NULL_VOID(manager);
981 if (manager->KeyboardSafeAreaEnabled()) {
982 json->Put("KeyboardInset: ", manager->GetKeyboardInset().ToString().c_str());
983 }
984 json->Put("IgnoreSafeArea", manager->IsIgnoreSafeArea());
985 json->Put("IsNeedAvoidWindow", manager->IsNeedAvoidWindow());
986 json->Put("IsFullScreen", manager->IsFullScreen());
987 json->Put("IsKeyboardAvoidMode", static_cast<int32_t>(manager->GetKeyBoardAvoidMode()));
988 json->Put("IsUseCutout", manager->GetUseCutout());
989 }
990
DumpSimplifyOverlayInfo(std::unique_ptr<JsonValue> & json)991 void FrameNode::DumpSimplifyOverlayInfo(std::unique_ptr<JsonValue>& json)
992 {
993 if (!layoutProperty_->IsOverlayNode()) {
994 return;
995 }
996 json->Put("IsOverlayNode", true);
997 Dimension offsetX;
998 Dimension offsetY;
999 layoutProperty_->GetOverlayOffset(offsetX, offsetY);
1000 json->Put("OverlayOffset", (offsetX.ToString() + "," + offsetY.ToString()).c_str());
1001 }
1002
CheckVisibleOrActive()1003 bool FrameNode::CheckVisibleOrActive()
1004 {
1005 if (layoutTags_.find(GetTag()) != layoutTags_.end()) {
1006 return layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE) == VisibleType::VISIBLE && IsActive();
1007 } else {
1008 return true;
1009 }
1010 }
1011
DumpSimplifyInfo(std::unique_ptr<JsonValue> & json)1012 void FrameNode::DumpSimplifyInfo(std::unique_ptr<JsonValue>& json)
1013 {
1014 CHECK_NULL_VOID(json);
1015 DumpSimplifyCommonInfo(json);
1016 if (pattern_) {
1017 auto child = JsonUtil::Create();
1018 pattern_->DumpSimplifyInfo(child);
1019 json->Put("$attrs", std::move(child));
1020 }
1021 }
1022
DumpInfo()1023 void FrameNode::DumpInfo()
1024 {
1025 DumpCommonInfo();
1026 DumpOnSizeChangeInfo();
1027 DumpKeyboardShortcutInfo();
1028 if (pattern_) {
1029 pattern_->DumpInfo();
1030 }
1031 if (renderContext_) {
1032 renderContext_->DumpInfo();
1033 }
1034 }
1035
DumpAdvanceInfo()1036 void FrameNode::DumpAdvanceInfo()
1037 {
1038 DumpCommonInfo();
1039 DumpOnSizeChangeInfo();
1040 DumpKeyboardShortcutInfo();
1041 if (pattern_) {
1042 pattern_->DumpInfo();
1043 pattern_->DumpAdvanceInfo();
1044 }
1045 if (renderContext_) {
1046 renderContext_->DumpInfo();
1047 renderContext_->DumpAdvanceInfo();
1048 }
1049 }
1050
DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap,bool needsRecordData)1051 void FrameNode::DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap, bool needsRecordData)
1052 {
1053 if (pattern_) {
1054 pattern_->DumpViewDataPageNode(viewDataWrap, needsRecordData);
1055 }
1056 }
1057
CheckAutoSave()1058 bool FrameNode::CheckAutoSave()
1059 {
1060 if (pattern_) {
1061 return pattern_->CheckAutoSave();
1062 }
1063 return false;
1064 }
1065
MouseToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1066 void FrameNode::MouseToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1067 {
1068 std::string hoverEffect = "HoverEffect.Auto";
1069 /* no fixed attr below, just return */
1070 if (filter.IsFastFilter()) {
1071 return;
1072 }
1073 auto inputEventHub = eventHub_ ? eventHub_->GetOrCreateInputEventHub() : nullptr;
1074 if (inputEventHub) {
1075 hoverEffect = inputEventHub->GetHoverEffectStr();
1076 }
1077 json->PutExtAttr("hoverEffect", hoverEffect.c_str(), filter);
1078 }
1079
TouchToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1080 void FrameNode::TouchToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1081 {
1082 bool touchable = true;
1083 bool monopolizeEvents = false;
1084 std::string hitTestMode = "HitTestMode.Default";
1085 /* no fixed attr below, just return */
1086 if (filter.IsFastFilter()) {
1087 return;
1088 }
1089 auto gestureEventHub = eventHub_ ? eventHub_->GetOrCreateGestureEventHub() : nullptr;
1090 std::vector<DimensionRect> responseRegion;
1091 std::vector<DimensionRect> mouseResponseRegion;
1092 if (gestureEventHub) {
1093 touchable = gestureEventHub->GetTouchable();
1094 hitTestMode = GestureEventHub::GetHitTestModeStr(gestureEventHub);
1095 responseRegion = gestureEventHub->GetResponseRegion();
1096 mouseResponseRegion = gestureEventHub->GetMouseResponseRegion();
1097 monopolizeEvents = gestureEventHub->GetMonopolizeEvents();
1098 }
1099 json->PutExtAttr("touchable", touchable, filter);
1100 json->PutExtAttr("hitTestBehavior", hitTestMode.c_str(), filter);
1101 json->PutExtAttr("monopolizeEvents", monopolizeEvents, filter);
1102 auto jsArr = JsonUtil::CreateArray(true);
1103 for (int32_t i = 0; i < static_cast<int32_t>(responseRegion.size()); ++i) {
1104 auto iStr = std::to_string(i);
1105 jsArr->Put(iStr.c_str(), responseRegion[i].ToJsonString().c_str());
1106 }
1107 json->PutExtAttr("responseRegion", jsArr, filter);
1108 for (int32_t i = 0; i < static_cast<int32_t>(mouseResponseRegion.size()); ++i) {
1109 auto iStr = std::to_string(i);
1110 jsArr->Put(iStr.c_str(), mouseResponseRegion[i].ToJsonString().c_str());
1111 }
1112 json->PutExtAttr("mouseResponseRegion", jsArr, filter);
1113 }
1114
GeometryNodeToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1115 void FrameNode::GeometryNodeToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1116 {
1117 bool hasIdealWidth = false;
1118 bool hasIdealHeight = false;
1119 /* no fixed attr below, just return */
1120 if (filter.IsFastFilter()) {
1121 return;
1122 }
1123 if (layoutProperty_ && layoutProperty_->GetCalcLayoutConstraint()) {
1124 auto selfIdealSize = layoutProperty_->GetCalcLayoutConstraint()->selfIdealSize;
1125 hasIdealWidth = selfIdealSize.has_value() && selfIdealSize.value().Width().has_value();
1126 hasIdealHeight = selfIdealSize.has_value() && selfIdealSize.value().Height().has_value();
1127 }
1128
1129 auto jsonSize = json->GetValue("size");
1130 if (!hasIdealWidth) {
1131 auto idealWidthVpStr = std::to_string(Dimension(geometryNode_->GetFrameSize().Width()).ConvertToVp());
1132 auto widthStr = (idealWidthVpStr.substr(0, idealWidthVpStr.find(".") + SUBSTR_LENGTH) + DIMENSION_UNIT_VP);
1133 json->PutExtAttr("width", widthStr.c_str(), filter);
1134 if (jsonSize) {
1135 jsonSize->Put("width", widthStr.c_str());
1136 }
1137 }
1138
1139 if (!hasIdealHeight) {
1140 auto idealHeightVpStr = std::to_string(Dimension(geometryNode_->GetFrameSize().Height()).ConvertToVp());
1141 auto heightStr = (idealHeightVpStr.substr(0, idealHeightVpStr.find(".") + SUBSTR_LENGTH) + DIMENSION_UNIT_VP);
1142 json->PutExtAttr("height", heightStr.c_str(), filter);
1143 if (jsonSize) {
1144 jsonSize->Put("height", heightStr.c_str());
1145 }
1146 }
1147 }
1148
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1149 void FrameNode::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1150 {
1151 if (renderContext_) {
1152 renderContext_->ToJsonValue(json, filter);
1153 }
1154 // scrollable in AccessibilityProperty
1155 ACE_PROPERTY_TO_JSON_VALUE(accessibilityProperty_, AccessibilityProperty);
1156 ACE_PROPERTY_TO_JSON_VALUE(layoutProperty_, LayoutProperty);
1157 ACE_PROPERTY_TO_JSON_VALUE(paintProperty_, PaintProperty);
1158 ACE_PROPERTY_TO_JSON_VALUE(pattern_, Pattern);
1159 if (eventHub_) {
1160 eventHub_->ToJsonValue(json, filter);
1161 }
1162 FocusHub::ToJsonValue(GetFocusHub(), json, filter);
1163 MouseToJsonValue(json, filter);
1164 TouchToJsonValue(json, filter);
1165 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1166 #if defined(PREVIEW)
1167 GeometryNodeToJsonValue(json, filter);
1168 #endif
1169 } else {
1170 GeometryNodeToJsonValue(json, filter);
1171 }
1172 json->PutFixedAttr("id", propInspectorId_.value_or("").c_str(), filter, FIXED_ATTR_ID);
1173 ExtraCustomPropertyToJsonValue(json, filter);
1174 }
1175
ToTreeJson(std::unique_ptr<JsonValue> & json,const InspectorConfig & config) const1176 void FrameNode::ToTreeJson(std::unique_ptr<JsonValue>& json, const InspectorConfig& config) const
1177 {
1178 if (layoutProperty_) {
1179 layoutProperty_->ToTreeJson(json, config);
1180 } else {
1181 LayoutProperty lp;
1182 lp.ToTreeJson(json, config);
1183 }
1184 if (paintProperty_) {
1185 paintProperty_->ToTreeJson(json, config);
1186 }
1187 if (pattern_) {
1188 pattern_->ToTreeJson(json, config);
1189 }
1190 auto id = propInspectorId_.value_or("");
1191 if (!id.empty()) {
1192 json->Put(TreeKey::ID, id.c_str());
1193 }
1194 if (!config.contentOnly) {
1195 auto eventHub = eventHub_ ? eventHub_->GetOrCreateGestureEventHub() : nullptr;
1196 if (eventHub) {
1197 json->Put(TreeKey::CLICKABLE, eventHub->IsClickable());
1198 json->Put(TreeKey::LONG_CLICKABLE, eventHub->IsLongClickable());
1199 }
1200 }
1201 auto accessibilityProperty = GetAccessibilityProperty<AccessibilityProperty>();
1202 if (accessibilityProperty) {
1203 auto accessibilityText = accessibilityProperty->GetAccessibilityText();
1204 if (!accessibilityText.empty()) {
1205 json->Put("accessilityContent", accessibilityText.c_str());
1206 }
1207 }
1208 }
1209
FromJson(const std::unique_ptr<JsonValue> & json)1210 void FrameNode::FromJson(const std::unique_ptr<JsonValue>& json)
1211 {
1212 if (renderContext_) {
1213 renderContext_->FromJson(json);
1214 }
1215 accessibilityProperty_->FromJson(json);
1216 layoutProperty_->FromJson(json);
1217 paintProperty_->FromJson(json);
1218 pattern_->FromJson(json);
1219 if (eventHub_) {
1220 eventHub_->FromJson(json);
1221 }
1222 }
1223
UpdateGeometryTransition()1224 void FrameNode::UpdateGeometryTransition()
1225 {
1226 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
1227 if (geometryTransition) {
1228 layoutProperty_->UpdateGeometryTransition("");
1229 layoutProperty_->UpdateGeometryTransition(geometryTransition->GetId());
1230 MarkDirtyNode();
1231 }
1232 auto children = GetChildren();
1233 for (const auto& child : children) {
1234 child->UpdateGeometryTransition();
1235 }
1236 }
1237
TriggerRsProfilerNodeMountCallbackIfExist()1238 void FrameNode::TriggerRsProfilerNodeMountCallbackIfExist()
1239 {
1240 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
1241 CHECK_NULL_VOID(renderContext_);
1242 auto callback = LayoutInspector::GetRsProfilerNodeMountCallback();
1243 if (callback) {
1244 FrameNodeInfo info { renderContext_->GetNodeId(), GetId(), GetTag(), GetDebugLine() };
1245 callback(info);
1246 }
1247 #endif
1248 }
1249
OnAttachToMainTree(bool recursive)1250 void FrameNode::OnAttachToMainTree(bool recursive)
1251 {
1252 TriggerRsProfilerNodeMountCallbackIfExist();
1253 if (eventHub_) {
1254 eventHub_->FireOnAttach();
1255 eventHub_->FireOnAppear();
1256 eventHub_->FireEnabledTask();
1257 }
1258 renderContext_->OnNodeAppear(recursive);
1259 pattern_->OnAttachToMainTree();
1260
1261 if (isActive_ && SystemProperties::GetDeveloperModeOn()) {
1262 PaintDebugBoundary(SystemProperties::GetDebugBoundaryEnabled());
1263 }
1264 bool forceMeasure = !GetPattern()->ReusedNodeSkipMeasure();
1265 // node may have been measured before AttachToMainTree
1266 if (geometryNode_->GetParentLayoutConstraint().has_value() && !UseOffscreenProcess() && forceMeasure) {
1267 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE_SELF);
1268 }
1269 UINode::OnAttachToMainTree(recursive);
1270 auto context = GetContext();
1271 CHECK_NULL_VOID(context);
1272 auto predictLayoutNode = std::move(predictLayoutNode_);
1273 for (auto& node : predictLayoutNode) {
1274 auto frameNode = node.Upgrade();
1275 if (frameNode && frameNode->isLayoutDirtyMarked_) {
1276 context->AddDirtyLayoutNode(frameNode);
1277 }
1278 }
1279
1280 if (isPropertyDiffMarked_) {
1281 context->AddDirtyPropertyNode(Claim(this));
1282 }
1283 if (!hasPendingRequest_) {
1284 return;
1285 }
1286 context->RequestFrame();
1287 hasPendingRequest_ = false;
1288 }
1289
OnAttachToBuilderNode(NodeStatus nodeStatus)1290 void FrameNode::OnAttachToBuilderNode(NodeStatus nodeStatus)
1291 {
1292 pattern_->OnAttachToBuilderNode(nodeStatus);
1293 }
1294
RenderCustomChild(int64_t deadline)1295 bool FrameNode::RenderCustomChild(int64_t deadline)
1296 {
1297 if (!pattern_->RenderCustomChild(deadline)) {
1298 return false;
1299 }
1300 return UINode::RenderCustomChild(deadline);
1301 }
1302
OnConfigurationUpdate(const ConfigurationChange & configurationChange)1303 void FrameNode::OnConfigurationUpdate(const ConfigurationChange& configurationChange)
1304 {
1305 if (configurationChange.languageUpdate) {
1306 pattern_->OnLanguageConfigurationUpdate();
1307 MarkModifyDone();
1308 MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1309 }
1310 if (configurationChange.colorModeUpdate) {
1311 pattern_->OnColorConfigurationUpdate();
1312 if (colorModeUpdateCallback_) {
1313 // copy it first in case of changing colorModeUpdateCallback_ in the callback
1314 auto cb = colorModeUpdateCallback_;
1315 cb();
1316 }
1317 FireColorNDKCallback();
1318 MarkModifyDone();
1319 MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1320 }
1321 if (configurationChange.directionUpdate) {
1322 pattern_->OnDirectionConfigurationUpdate();
1323 MarkModifyDone();
1324 MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1325 }
1326 if (configurationChange.dpiUpdate) {
1327 pattern_->OnDpiConfigurationUpdate();
1328 MarkModifyDone();
1329 MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1330 }
1331 if (configurationChange.fontUpdate) {
1332 pattern_->OnFontConfigurationUpdate();
1333 MarkModifyDone();
1334 MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1335 }
1336 if (configurationChange.iconUpdate) {
1337 pattern_->OnIconConfigurationUpdate();
1338 MarkModifyDone();
1339 MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1340 }
1341 if (configurationChange.skinUpdate) {
1342 MarkModifyDone();
1343 MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1344 }
1345 if (configurationChange.fontScaleUpdate) {
1346 pattern_->OnFontScaleConfigurationUpdate();
1347 MarkModifyDone();
1348 MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1349 }
1350 FireFontNDKCallback(configurationChange);
1351 OnPropertyChangeMeasure();
1352 }
1353
OnPropertyChangeMeasure() const1354 void FrameNode::OnPropertyChangeMeasure() const
1355 {
1356 auto layoutProperty = GetLayoutProperty();
1357 CHECK_NULL_VOID(layoutProperty);
1358 layoutProperty->OnPropertyChangeMeasure();
1359 }
1360
MarkDirtyWithOnProChange(PropertyChangeFlag extraFlag)1361 void FrameNode::MarkDirtyWithOnProChange(PropertyChangeFlag extraFlag)
1362 {
1363 MarkDirtyNode(extraFlag);
1364 auto layoutProperty = GetLayoutProperty();
1365 CHECK_NULL_VOID(layoutProperty);
1366 layoutProperty->OnPropertyChangeMeasure();
1367 }
1368
FireColorNDKCallback()1369 void FrameNode::FireColorNDKCallback()
1370 {
1371 std::shared_lock<std::shared_mutex> lock(colorModeCallbackMutex_);
1372 if (ndkColorModeUpdateCallback_) {
1373 auto colorModeChange = ndkColorModeUpdateCallback_;
1374 auto context = GetContext();
1375 CHECK_NULL_VOID(context);
1376 colorModeChange(context->GetColorMode() == ColorMode::DARK);
1377 }
1378 }
1379
SetNDKColorModeUpdateCallback(const std::function<void (int32_t)> && callback)1380 void FrameNode::SetNDKColorModeUpdateCallback(const std::function<void(int32_t)>&& callback)
1381 {
1382 std::unique_lock<std::shared_mutex> lock(colorModeCallbackMutex_);
1383 ndkColorModeUpdateCallback_ = callback;
1384 auto context = GetContext();
1385 CHECK_NULL_VOID(context);
1386 colorMode_ = context->GetColorMode();
1387 }
1388
FireFontNDKCallback(const ConfigurationChange & configurationChange)1389 void FrameNode::FireFontNDKCallback(const ConfigurationChange& configurationChange)
1390 {
1391 std::shared_lock<std::shared_mutex> lock(fontSizeCallbackMutex_);
1392 if ((configurationChange.fontScaleUpdate || configurationChange.fontWeightScaleUpdate) && ndkFontUpdateCallback_) {
1393 auto fontChangeCallback = ndkFontUpdateCallback_;
1394 auto pipeline = GetContextWithCheck();
1395 CHECK_NULL_VOID(pipeline);
1396 fontChangeCallback(pipeline->GetFontScale(), pipeline->GetFontWeightScale());
1397 }
1398 }
1399
NotifyVisibleChange(VisibleType preVisibility,VisibleType currentVisibility)1400 void FrameNode::NotifyVisibleChange(VisibleType preVisibility, VisibleType currentVisibility)
1401 {
1402 if ((preVisibility != currentVisibility &&
1403 (preVisibility == VisibleType::GONE || currentVisibility == VisibleType::GONE)) &&
1404 SelfExpansive()) {
1405 MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1406 }
1407 pattern_->OnVisibleChange(currentVisibility == VisibleType::VISIBLE);
1408 UpdateChildrenVisible(preVisibility, currentVisibility);
1409 }
1410
TryVisibleChangeOnDescendant(VisibleType preVisibility,VisibleType currentVisibility)1411 void FrameNode::TryVisibleChangeOnDescendant(VisibleType preVisibility, VisibleType currentVisibility)
1412 {
1413 auto layoutProperty = GetLayoutProperty();
1414 if (layoutProperty && layoutProperty->GetVisibilityValue(VisibleType::VISIBLE) != VisibleType::VISIBLE) {
1415 return;
1416 }
1417 NotifyVisibleChange(preVisibility, currentVisibility);
1418 }
1419
OnDetachFromMainTree(bool recursive,PipelineContext * context)1420 void FrameNode::OnDetachFromMainTree(bool recursive, PipelineContext* context)
1421 {
1422 auto focusHub = GetFocusHub();
1423 if (focusHub) {
1424 auto focusView = focusHub->GetFirstChildFocusView();
1425 if (focusView) {
1426 focusView->FocusViewClose(true);
1427 }
1428 focusHub->RemoveSelf();
1429 }
1430 pattern_->OnDetachFromMainTree();
1431 if (eventHub_) {
1432 eventHub_->OnDetachClear();
1433 }
1434 CHECK_NULL_VOID(renderContext_);
1435 renderContext_->OnNodeDisappear(recursive);
1436 if (context) {
1437 const auto& safeAreaManager = context->GetSafeAreaManager();
1438 if (safeAreaManager) {
1439 safeAreaManager->RemoveRestoreNode(WeakClaim(this));
1440 }
1441 }
1442 auto accessibilityProperty = GetAccessibilityProperty<AccessibilityProperty>();
1443 CHECK_NULL_VOID(accessibilityProperty);
1444 accessibilityProperty->OnAccessibilityDetachFromMainTree();
1445 }
1446
SwapDirtyLayoutWrapperOnMainThread(const RefPtr<LayoutWrapper> & dirty)1447 void FrameNode::SwapDirtyLayoutWrapperOnMainThread(const RefPtr<LayoutWrapper>& dirty)
1448 {
1449 CHECK_NULL_VOID(dirty);
1450
1451 // update new layout constrain.
1452 layoutProperty_->UpdateLayoutConstraint(dirty->GetLayoutProperty());
1453
1454 // active change flag judge.
1455 SetActive(dirty->IsActive());
1456 if (!isActive_) {
1457 return;
1458 }
1459
1460 // update layout size.
1461 bool frameSizeChange = geometryNode_->GetFrameSize() != dirty->GetGeometryNode()->GetFrameSize();
1462 bool frameOffsetChange = geometryNode_->GetFrameOffset() != dirty->GetGeometryNode()->GetFrameOffset();
1463 bool contentSizeChange = geometryNode_->GetContentSize() != dirty->GetGeometryNode()->GetContentSize();
1464 bool contentOffsetChange = geometryNode_->GetContentOffset() != dirty->GetGeometryNode()->GetContentOffset();
1465
1466 SetGeometryNode(dirty->GetGeometryNode());
1467
1468 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
1469 if (geometryTransition != nullptr && geometryTransition->IsRunning(WeakClaim(this))) {
1470 geometryTransition->DidLayout(dirty);
1471 if (geometryTransition->IsNodeOutAndActive(WeakClaim(this))) {
1472 isLayoutDirtyMarked_ = true;
1473 }
1474 } else if (frameSizeChange || frameOffsetChange || HasPositionProp() ||
1475 (pattern_->GetContextParam().has_value() && contentSizeChange)) {
1476 renderContext_->SyncGeometryProperties(RawPtr(dirty->GetGeometryNode()));
1477 }
1478
1479 // clean layout flag.
1480 layoutProperty_->CleanDirty();
1481 DirtySwapConfig config { frameSizeChange, frameOffsetChange, contentSizeChange, contentOffsetChange };
1482 // check if need to paint content.
1483 auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
1484 CHECK_NULL_VOID(layoutAlgorithmWrapper);
1485 config.skipMeasure = layoutAlgorithmWrapper->SkipMeasure() || dirty->SkipMeasureContent();
1486 config.skipLayout = layoutAlgorithmWrapper->SkipLayout();
1487 if ((config.skipMeasure == false) && (config.skipLayout == false)) {
1488 auto pipeline = GetContext();
1489 CHECK_NULL_VOID(pipeline);
1490 if (eventHub_) {
1491 eventHub_->FireLayoutNDKCallback(pipeline);
1492 }
1493 if (GetInspectorId().has_value()) {
1494 pipeline->OnLayoutCompleted(GetInspectorId()->c_str());
1495 }
1496 }
1497 auto needRerender = pattern_->OnDirtyLayoutWrapperSwap(dirty, config);
1498 needRerender = needRerender || pattern_->OnDirtyLayoutWrapperSwap(dirty, config.skipMeasure, config.skipLayout);
1499 if (needRerender || CheckNeedRender(paintProperty_->GetPropertyChangeFlag())) {
1500 MarkDirtyNode(true, true, PROPERTY_UPDATE_RENDER);
1501 }
1502
1503 // update border.
1504 if (layoutProperty_->GetBorderWidthProperty()) {
1505 if (!renderContext_->HasBorderColor()) {
1506 BorderColorProperty borderColorProperty;
1507 borderColorProperty.SetColor(Color::BLACK);
1508 renderContext_->UpdateBorderColor(borderColorProperty);
1509 }
1510 if (!renderContext_->HasBorderStyle()) {
1511 BorderStyleProperty borderStyleProperty;
1512 borderStyleProperty.SetBorderStyle(BorderStyle::SOLID);
1513 renderContext_->UpdateBorderStyle(borderStyleProperty);
1514 }
1515 if (!renderContext_->HasDashGap()) {
1516 BorderWidthProperty dashGapProperty;
1517 dashGapProperty.SetBorderWidth(Dimension(-1));
1518 renderContext_->UpdateDashGap(dashGapProperty);
1519 }
1520 if (!renderContext_->HasDashWidth()) {
1521 BorderWidthProperty dashWidthProperty;
1522 dashWidthProperty.SetBorderWidth(Dimension(-1));
1523 renderContext_->UpdateDashWidth(dashWidthProperty);
1524 }
1525 if (layoutProperty_->GetLayoutConstraint().has_value()) {
1526 renderContext_->UpdateBorderWidthF(ConvertToBorderWidthPropertyF(layoutProperty_->GetBorderWidthProperty(),
1527 ScaleProperty::CreateScaleProperty(),
1528 layoutProperty_->GetLayoutConstraint()->percentReference.Width()));
1529 } else {
1530 renderContext_->UpdateBorderWidthF(ConvertToBorderWidthPropertyF(layoutProperty_->GetBorderWidthProperty(),
1531 ScaleProperty::CreateScaleProperty(), PipelineContext::GetCurrentRootWidth()));
1532 }
1533 }
1534
1535 // update background
1536 if (builderFunc_) {
1537 auto builderNode = builderFunc_();
1538 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1539 AceType::MakeRefPtr<LinearLayoutPattern>(true));
1540 if (builderNode) {
1541 builderNode->MountToParent(columnNode);
1542 }
1543 SetBackgroundLayoutConstraint(columnNode);
1544 renderContext_->CreateBackgroundPixelMap(columnNode);
1545 builderFunc_ = nullptr;
1546 backgroundNode_ = columnNode;
1547 }
1548
1549 // update focus state
1550 auto focusHub = GetFocusHub();
1551 if (focusHub && focusHub->IsCurrentFocus()) {
1552 focusHub->ClearFocusState(false);
1553 focusHub->PaintFocusState(false);
1554 }
1555
1556 // rebuild child render node.
1557 RebuildRenderContextTree();
1558 }
1559
SetBackgroundLayoutConstraint(const RefPtr<FrameNode> & customNode)1560 void FrameNode::SetBackgroundLayoutConstraint(const RefPtr<FrameNode>& customNode)
1561 {
1562 CHECK_NULL_VOID(customNode);
1563 LayoutConstraintF layoutConstraint;
1564 layoutConstraint.scaleProperty = ScaleProperty::CreateScaleProperty();
1565 layoutConstraint.percentReference.SetWidth(geometryNode_->GetFrameSize().Width());
1566 layoutConstraint.percentReference.SetHeight(geometryNode_->GetFrameSize().Height());
1567 layoutConstraint.maxSize.SetWidth(geometryNode_->GetFrameSize().Width());
1568 layoutConstraint.maxSize.SetHeight(geometryNode_->GetFrameSize().Height());
1569 customNode->GetGeometryNode()->SetParentLayoutConstraint(layoutConstraint);
1570 }
1571
AdjustGridOffset()1572 void FrameNode::AdjustGridOffset()
1573 {
1574 if (!isActive_) {
1575 return;
1576 }
1577 if (layoutProperty_->UpdateGridOffset(Claim(this))) {
1578 renderContext_->SyncGeometryProperties(RawPtr(GetGeometryNode()));
1579 }
1580 }
1581
ClearUserOnAreaChange()1582 void FrameNode::ClearUserOnAreaChange()
1583 {
1584 if (eventHub_) {
1585 eventHub_->ClearUserOnAreaChanged();
1586 }
1587 }
1588
SetOnAreaChangeCallback(OnAreaChangedFunc && callback)1589 void FrameNode::SetOnAreaChangeCallback(OnAreaChangedFunc&& callback)
1590 {
1591 InitLastArea();
1592 CreateEventHubInner();
1593 CHECK_NULL_VOID(eventHub_);
1594 eventHub_->SetOnAreaChanged(std::move(callback));
1595 }
1596
TriggerOnAreaChangeCallback(uint64_t nanoTimestamp)1597 void FrameNode::TriggerOnAreaChangeCallback(uint64_t nanoTimestamp)
1598 {
1599 if (!IsActive()) {
1600 if (IsDebugInspectorId()) {
1601 TAG_LOGD(AceLogTag::ACE_UIEVENT, "OnAreaChange Node(%{public}s/%{public}d) is inActive", GetTag().c_str(),
1602 GetId());
1603 }
1604 return;
1605 }
1606 #ifdef WINDOW_SCENE_SUPPORTED
1607 auto container = Container::Current();
1608 if (container && container->IsDynamicRender() &&
1609 container->GetUIContentType() == UIContentType::DYNAMIC_COMPONENT) {
1610 DynamicComponentManager::TriggerOnAreaChangeCallback(this, nanoTimestamp);
1611 return;
1612 }
1613 #endif
1614 if (eventHub_ && (eventHub_->HasOnAreaChanged() || eventHub_->HasInnerOnAreaChanged()) && lastFrameRect_ &&
1615 lastParentOffsetToWindow_) {
1616 auto currFrameRect = geometryNode_->GetFrameRect();
1617 if (renderContext_ && renderContext_->GetPositionProperty()) {
1618 if (renderContext_->GetPositionProperty()->HasPosition()) {
1619 auto renderPosition = ContextPositionConvertToPX(
1620 renderContext_, layoutProperty_->GetLayoutConstraint()->percentReference);
1621 currFrameRect.SetOffset(
1622 { static_cast<float>(renderPosition.first), static_cast<float>(renderPosition.second) });
1623 }
1624 }
1625 bool logFlag = IsDebugInspectorId();
1626 auto currParentOffsetToWindow =
1627 CalculateOffsetRelativeToWindow(nanoTimestamp, logFlag) - currFrameRect.GetOffset();
1628 if (logFlag) {
1629 TAG_LOGD(AceLogTag::ACE_UIEVENT,
1630 "OnAreaChange Node(%{public}s/%{public}d) rect:%{public}s lastRect:%{public}s "
1631 "parentRectToWindow:%{public}s lastParentRectToWindow:%{public}s",
1632 GetTag().c_str(), GetId(), currFrameRect.ToString().c_str(), (*lastFrameRect_).ToString().c_str(),
1633 currParentOffsetToWindow.ToString().c_str(), (*lastParentOffsetToWindow_).ToString().c_str());
1634 TAG_LOGD(AceLogTag::ACE_UIEVENT, "OnAreaChange End of calculation %{public}s",
1635 currFrameRect != *lastFrameRect_ || currParentOffsetToWindow != *lastParentOffsetToWindow_
1636 ? "non-execution"
1637 : "execution");
1638 }
1639 eventHub_->HandleOnAreaChange(
1640 lastFrameRect_, lastParentOffsetToWindow_, currFrameRect, currParentOffsetToWindow);
1641 }
1642 pattern_->OnAreaChangedInner();
1643 }
1644
SetOnSizeChangeCallback(OnSizeChangedFunc && callback)1645 void FrameNode::SetOnSizeChangeCallback(OnSizeChangedFunc&& callback)
1646 {
1647 if (!lastFrameNodeRect_) {
1648 lastFrameNodeRect_ = std::make_unique<RectF>();
1649 }
1650 CreateEventHubInner();
1651 CHECK_NULL_VOID(eventHub_);
1652 eventHub_->SetOnSizeChanged(std::move(callback));
1653 }
1654
AddInnerOnSizeChangeCallback(int32_t id,OnSizeChangedFunc && callback)1655 void FrameNode::AddInnerOnSizeChangeCallback(int32_t id, OnSizeChangedFunc&& callback)
1656 {
1657 if (!lastFrameNodeRect_) {
1658 lastFrameNodeRect_ = std::make_unique<RectF>();
1659 }
1660 CreateEventHubInner();
1661 CHECK_NULL_VOID(eventHub_);
1662 eventHub_->AddInnerOnSizeChanged(id, std::move(callback));
1663 }
1664
SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc && callback)1665 void FrameNode::SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc&& callback)
1666 {
1667 if (!lastFrameNodeRect_) {
1668 lastFrameNodeRect_ = std::make_unique<RectF>();
1669 }
1670 CreateEventHubInner();
1671 CHECK_NULL_VOID(eventHub_);
1672 eventHub_->SetJSFrameNodeOnSizeChangeCallback(std::move(callback));
1673 }
1674
GetRectWithRender()1675 RectF FrameNode::GetRectWithRender()
1676 {
1677 RectF currFrameRect;
1678 if (renderContext_) {
1679 currFrameRect = renderContext_->GetPaintRectWithoutTransform();
1680 }
1681 if (renderContext_ && renderContext_->GetPositionProperty()) {
1682 if (renderContext_->GetPositionProperty()->HasPosition()) {
1683 auto renderPosition =
1684 ContextPositionConvertToPX(renderContext_, layoutProperty_->GetLayoutConstraint()->percentReference);
1685 currFrameRect.SetOffset(
1686 { static_cast<float>(renderPosition.first), static_cast<float>(renderPosition.second) });
1687 }
1688 }
1689 return currFrameRect;
1690 }
1691
CheckAncestorPageShow()1692 bool FrameNode::CheckAncestorPageShow()
1693 {
1694 auto pageNode = GetPageNode();
1695 if (!pageNode) {
1696 return true;
1697 }
1698 return pageNode->GetPattern<PagePattern>()->IsOnShow();
1699 }
1700
TriggerOnSizeChangeCallback()1701 void FrameNode::TriggerOnSizeChangeCallback()
1702 {
1703 if (!IsActive() || !CheckAncestorPageShow()) {
1704 return;
1705 }
1706 if (eventHub_ && (eventHub_->HasOnSizeChanged() || eventHub_->HasInnerOnSizeChanged()) && lastFrameNodeRect_) {
1707 auto currFrameRect = GetRectWithRender();
1708 if (currFrameRect.GetSize() != (*lastFrameNodeRect_).GetSize()) {
1709 onSizeChangeDumpInfo dumpInfo { GetCurrentTimestamp(), *lastFrameNodeRect_, currFrameRect };
1710 if (onSizeChangeDumpInfos.size() >= SIZE_CHANGE_DUMP_SIZE) {
1711 onSizeChangeDumpInfos.erase(onSizeChangeDumpInfos.begin());
1712 }
1713 onSizeChangeDumpInfos.emplace_back(dumpInfo);
1714 if (eventHub_->HasOnSizeChanged()) {
1715 eventHub_->FireOnSizeChanged(*lastFrameNodeRect_, currFrameRect);
1716 }
1717 if (eventHub_->HasInnerOnSizeChanged()) {
1718 eventHub_->FireInnerOnSizeChanged(*lastFrameNodeRect_, currFrameRect);
1719 }
1720 eventHub_->FireJSFrameNodeOnSizeChanged(*lastFrameNodeRect_, currFrameRect);
1721 *lastFrameNodeRect_ = currFrameRect;
1722 }
1723 }
1724 }
1725
IsFrameDisappear() const1726 bool FrameNode::IsFrameDisappear() const
1727 {
1728 auto context = GetContext();
1729 CHECK_NULL_RETURN(context, true);
1730 bool isFrameDisappear = !context->GetOnShow() || !IsOnMainTree() || !IsVisible();
1731 if (isFrameDisappear) {
1732 return true;
1733 }
1734 bool curFrameIsActive = isActive_;
1735 bool curIsVisible = IsVisible();
1736 auto parent = GetParent();
1737 while (parent) {
1738 auto parentFrame = AceType::DynamicCast<FrameNode>(parent);
1739 if (!parentFrame) {
1740 parent = parent->GetParent();
1741 continue;
1742 }
1743 if (!parentFrame->isActive_) {
1744 curFrameIsActive = false;
1745 break;
1746 }
1747 if (!parentFrame->IsVisible()) {
1748 curIsVisible = false;
1749 break;
1750 }
1751 parent = parent->GetParent();
1752 }
1753 return !curIsVisible || !curFrameIsActive;
1754 }
1755
IsFrameDisappear(uint64_t timestamp)1756 bool FrameNode::IsFrameDisappear(uint64_t timestamp)
1757 {
1758 auto context = GetContext();
1759 CHECK_NULL_RETURN(context, true);
1760 auto isOnShow = context->GetOnShow();
1761 auto isOnMainTree = AllowVisibleAreaCheck();
1762 auto isSelfVisible = IsVisible();
1763 if (!isSelfVisible) {
1764 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::SELF_INVISIBLE);
1765 }
1766 if (!isOnMainTree) {
1767 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::IS_NOT_ON_MAINTREE);
1768 }
1769 if (!isOnShow) {
1770 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::BACKGROUND);
1771 }
1772 bool isFrameDisappear = !isOnShow || !isOnMainTree || !isSelfVisible;
1773 if (isFrameDisappear) {
1774 cachedIsFrameDisappear_ = { timestamp, true };
1775 return true;
1776 }
1777 auto result = IsFrameAncestorDisappear(timestamp);
1778 if (result) {
1779 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::ANCESTOR_INVISIBLE);
1780 }
1781 return result;
1782 }
1783
IsFrameAncestorDisappear(uint64_t timestamp)1784 bool FrameNode::IsFrameAncestorDisappear(uint64_t timestamp)
1785 {
1786 bool curFrameIsActive = isActive_;
1787 bool curIsVisible = IsVisible();
1788 bool result = !curIsVisible || !curFrameIsActive;
1789 RefPtr<FrameNode> parentUi = GetAncestorNodeOfFrame(false);
1790 if (!parentUi) {
1791 cachedIsFrameDisappear_ = { timestamp, result };
1792 return result;
1793 }
1794
1795 auto parentIsFrameDisappear = parentUi->cachedIsFrameDisappear_;
1796 if (parentIsFrameDisappear.first == timestamp) {
1797 result = result || parentIsFrameDisappear.second;
1798 cachedIsFrameDisappear_ = { timestamp, result };
1799 return result;
1800 }
1801 result = result || (parentUi->IsFrameAncestorDisappear(timestamp));
1802 cachedIsFrameDisappear_ = { timestamp, result };
1803 return result;
1804 }
1805
TriggerVisibleAreaChangeCallback(uint64_t timestamp,bool forceDisappear)1806 void FrameNode::TriggerVisibleAreaChangeCallback(uint64_t timestamp, bool forceDisappear)
1807 {
1808 auto context = GetContext();
1809 CHECK_NULL_VOID(context);
1810 CHECK_NULL_VOID(eventHub_);
1811 ProcessThrottledVisibleCallback(forceDisappear);
1812 auto hasInnerCallback = eventHub_->HasVisibleAreaCallback(false);
1813 auto hasUserCallback = eventHub_->HasVisibleAreaCallback(true);
1814 if (!hasInnerCallback && !hasUserCallback) {
1815 return;
1816 }
1817 auto& visibleAreaUserRatios = eventHub_->GetVisibleAreaRatios(true);
1818 auto& visibleAreaUserCallback = eventHub_->GetVisibleAreaCallback(true);
1819 auto& visibleAreaInnerRatios = eventHub_->GetVisibleAreaRatios(false);
1820 auto& visibleAreaInnerCallback = eventHub_->GetVisibleAreaCallback(false);
1821 if (forceDisappear || IsFrameDisappear(timestamp)) {
1822 if (IsDebugInspectorId()) {
1823 TAG_LOGD(AceLogTag::ACE_UIEVENT,
1824 "OnVisibleAreaChange Node(%{public}s/%{public}d) lastRatio(User:%{public}s/Inner:%{public}s) "
1825 "forceDisappear:%{public}d frameDisappear:%{public}d ",
1826 GetTag().c_str(), GetId(), std::to_string(lastVisibleRatio_).c_str(),
1827 std::to_string(lastInnerVisibleRatio_).c_str(), forceDisappear, IsFrameDisappear(timestamp));
1828 }
1829 if (!NearEqual(lastInnerVisibleRatio_, VISIBLE_RATIO_MIN)) {
1830 ProcessAllVisibleCallback(visibleAreaInnerRatios, visibleAreaInnerCallback, VISIBLE_RATIO_MIN,
1831 lastInnerVisibleCallbackRatio_, false, true);
1832 lastInnerVisibleRatio_ = VISIBLE_RATIO_MIN;
1833 }
1834 if (!NearEqual(lastVisibleRatio_, VISIBLE_RATIO_MIN)) {
1835 ProcessAllVisibleCallback(
1836 visibleAreaUserRatios, visibleAreaUserCallback, VISIBLE_RATIO_MIN, lastVisibleCallbackRatio_);
1837 lastVisibleRatio_ = VISIBLE_RATIO_MIN;
1838 }
1839 return;
1840 }
1841 auto visibleResult = GetCacheVisibleRect(timestamp, IsDebugInspectorId());
1842 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::VISIBLE_AREA_CHANGE);
1843 if (hasInnerCallback) {
1844 if (isCalculateInnerVisibleRectClip_) {
1845 ProcessVisibleAreaChangeEvent(visibleResult.innerVisibleRect, visibleResult.frameRect,
1846 visibleAreaInnerRatios, visibleAreaInnerCallback, false);
1847 } else {
1848 ProcessVisibleAreaChangeEvent(visibleResult.visibleRect, visibleResult.frameRect, visibleAreaInnerRatios,
1849 visibleAreaInnerCallback, false);
1850 }
1851 }
1852 if (hasUserCallback) {
1853 ProcessVisibleAreaChangeEvent(
1854 visibleResult.visibleRect, visibleResult.frameRect, visibleAreaUserRatios, visibleAreaUserCallback, true);
1855 }
1856 }
1857
ProcessVisibleAreaChangeEvent(const RectF & visibleRect,const RectF & frameRect,const std::vector<double> & visibleAreaRatios,VisibleCallbackInfo & visibleAreaCallback,bool isUser)1858 void FrameNode::ProcessVisibleAreaChangeEvent(const RectF& visibleRect, const RectF& frameRect,
1859 const std::vector<double>& visibleAreaRatios, VisibleCallbackInfo& visibleAreaCallback, bool isUser)
1860 {
1861 double currentVisibleRatio =
1862 std::clamp(CalculateCurrentVisibleRatio(visibleRect, frameRect), VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
1863 if (IsDebugInspectorId()) {
1864 TAG_LOGD(AceLogTag::ACE_UIEVENT,
1865 "OnVisibleAreaChange Node(%{public}s/%{public}d) Ratio(cur:%{public}s/last:%{public}s)", GetTag().c_str(),
1866 GetId(), std::to_string(currentVisibleRatio).c_str(), std::to_string(lastVisibleRatio_).c_str());
1867 TAG_LOGD(AceLogTag::ACE_UIEVENT, "OnVisibleAreaChange End of calculation %{public}s",
1868 NearEqual(currentVisibleRatio, lastVisibleRatio_) ? "non-execution" : "execution");
1869 }
1870 if (isUser) {
1871 if (!NearEqual(currentVisibleRatio, lastVisibleRatio_)) {
1872 auto lastVisibleCallbackRatio = lastVisibleCallbackRatio_;
1873 ProcessAllVisibleCallback(
1874 visibleAreaRatios, visibleAreaCallback, currentVisibleRatio, lastVisibleCallbackRatio);
1875 lastVisibleRatio_ = currentVisibleRatio;
1876 }
1877 } else {
1878 if (!NearEqual(currentVisibleRatio, lastInnerVisibleRatio_)) {
1879 auto lastVisibleCallbackRatio = lastInnerVisibleCallbackRatio_;
1880 ProcessAllVisibleCallback(visibleAreaRatios, visibleAreaCallback, currentVisibleRatio,
1881 lastVisibleCallbackRatio, false, true);
1882 lastInnerVisibleRatio_ = currentVisibleRatio;
1883 }
1884 }
1885 }
1886
CalculateCurrentVisibleRatio(const RectF & visibleRect,const RectF & renderRect)1887 double FrameNode::CalculateCurrentVisibleRatio(const RectF& visibleRect, const RectF& renderRect)
1888 {
1889 if (visibleRect.IsEmpty() || renderRect.IsEmpty()) {
1890 return 0.0;
1891 }
1892 return visibleRect.Width() * visibleRect.Height() / (renderRect.Width() * renderRect.Height());
1893 }
1894
ProcessAllVisibleCallback(const std::vector<double> & visibleAreaUserRatios,VisibleCallbackInfo & visibleAreaUserCallback,double currentVisibleRatio,double lastVisibleRatio,bool isThrottled,bool isInner)1895 void FrameNode::ProcessAllVisibleCallback(const std::vector<double>& visibleAreaUserRatios,
1896 VisibleCallbackInfo& visibleAreaUserCallback, double currentVisibleRatio, double lastVisibleRatio,
1897 bool isThrottled, bool isInner)
1898 {
1899 bool isHandled = false;
1900 bool isVisible = false;
1901 double* lastVisibleCallbackRatio = isThrottled ? &lastThrottledVisibleCbRatio_ :
1902 (isInner ? &lastInnerVisibleCallbackRatio_ : &lastVisibleCallbackRatio_);
1903
1904 for (const auto& callbackRatio : visibleAreaUserRatios) {
1905 if (GreatNotEqual(currentVisibleRatio, callbackRatio) && LessOrEqual(lastVisibleRatio, callbackRatio)) {
1906 *lastVisibleCallbackRatio = currentVisibleRatio;
1907 isVisible = true;
1908 isHandled = true;
1909 } else if (LessNotEqual(currentVisibleRatio, callbackRatio) && GreatOrEqual(lastVisibleRatio, callbackRatio)) {
1910 *lastVisibleCallbackRatio = currentVisibleRatio;
1911 isVisible = false;
1912 isHandled = true;
1913 } else if (NearEqual(callbackRatio, VISIBLE_RATIO_MIN) && NearEqual(currentVisibleRatio, callbackRatio)) {
1914 *lastVisibleCallbackRatio = VISIBLE_RATIO_MIN;
1915 currentVisibleRatio = VISIBLE_RATIO_MIN;
1916 isVisible = false;
1917 isHandled = true;
1918 } else if (NearEqual(callbackRatio, VISIBLE_RATIO_MAX) && NearEqual(currentVisibleRatio, callbackRatio)) {
1919 *lastVisibleCallbackRatio = VISIBLE_RATIO_MAX;
1920 currentVisibleRatio = VISIBLE_RATIO_MAX;
1921 isVisible = true;
1922 isHandled = true;
1923 }
1924 }
1925
1926 auto callback = visibleAreaUserCallback.callback;
1927 if (isHandled && callback) {
1928 if (GetTag() == V2::WEB_ETS_TAG) {
1929 TAG_LOGI(AceLogTag::ACE_UIEVENT, "exp=%{public}d ratio=%{public}s %{public}d-%{public}s reason=%{public}d",
1930 isVisible, std::to_string(currentVisibleRatio).c_str(), GetId(),
1931 std::to_string(GetAccessibilityId()).c_str(), static_cast<int32_t>(visibleAreaChangeTriggerReason_));
1932 }
1933 callback(isVisible, currentVisibleRatio);
1934 }
1935 }
1936
ThrottledVisibleTask()1937 void FrameNode::ThrottledVisibleTask()
1938 {
1939 CHECK_NULL_VOID(eventHub_);
1940 auto& userRatios = eventHub_->GetThrottledVisibleAreaRatios();
1941 auto& userCallback = eventHub_->GetThrottledVisibleAreaCallback();
1942 if (!userCallback.callback) {
1943 throttledCallbackOnTheWay_ = false;
1944 return;
1945 }
1946 if (!throttledCallbackOnTheWay_) {
1947 return;
1948 }
1949
1950 auto pipeline = GetContext();
1951 CHECK_NULL_VOID(pipeline);
1952 auto visibleAreaRealTime = pipeline->GetVisibleAreaRealTime();
1953 auto visibleResult = GetCacheVisibleRect(pipeline->GetVsyncTime());
1954 RectF frameRect = visibleResult.frameRect;
1955 RectF visibleRect = visibleResult.visibleRect;
1956 double ratio = IsFrameDisappear() ? VISIBLE_RATIO_MIN
1957 : std::clamp(CalculateCurrentVisibleRatio(visibleRect, frameRect),
1958 VISIBLE_RATIO_MIN, VISIBLE_RATIO_MAX);
1959 if (visibleAreaRealTime) {
1960 if (NearEqual(ratio, lastThrottledVisibleRatio_)) {
1961 throttledCallbackOnTheWay_ = false;
1962 return;
1963 }
1964 ProcessAllVisibleCallback(userRatios, userCallback, ratio, lastThrottledVisibleCbRatio_, true);
1965 lastThrottledVisibleRatio_ = ratio;
1966 throttledCallbackOnTheWay_ = false;
1967 lastThrottledTriggerTime_ = GetCurrentTimestamp();
1968 } else {
1969 if (!NearEqual(ratio, lastThrottledVisibleRatio_)) {
1970 ProcessAllVisibleCallback(userRatios, userCallback, ratio, lastThrottledVisibleCbRatio_, true);
1971 lastThrottledVisibleRatio_ = ratio;
1972 }
1973 throttledCallbackOnTheWay_ = false;
1974 lastThrottledTriggerTime_ = GetCurrentTimestamp();
1975 }
1976 }
1977
ProcessThrottledVisibleCallback(bool forceDisappear)1978 void FrameNode::ProcessThrottledVisibleCallback(bool forceDisappear)
1979 {
1980 CHECK_NULL_VOID(eventHub_);
1981 auto& visibleAreaUserCallback = eventHub_->GetThrottledVisibleAreaCallback();
1982 CHECK_NULL_VOID(visibleAreaUserCallback.callback);
1983
1984 if (forceDisappear && !NearEqual(lastThrottledVisibleCbRatio_, VISIBLE_RATIO_MIN)) {
1985 auto& userRatios = eventHub_->GetThrottledVisibleAreaRatios();
1986 ProcessAllVisibleCallback(
1987 userRatios, visibleAreaUserCallback, VISIBLE_RATIO_MIN, lastThrottledVisibleCbRatio_, true);
1988 return;
1989 }
1990
1991 auto task = [weak = WeakClaim(this)]() {
1992 auto node = weak.Upgrade();
1993 CHECK_NULL_VOID(node);
1994 node->ThrottledVisibleTask();
1995 };
1996
1997 auto pipeline = GetContextRefPtr();
1998 CHECK_NULL_VOID(pipeline);
1999 auto executor = pipeline->GetTaskExecutor();
2000 CHECK_NULL_VOID(executor);
2001
2002 if (throttledCallbackOnTheWay_) {
2003 return;
2004 }
2005
2006 throttledCallbackOnTheWay_ = true;
2007 int64_t interval = GetCurrentTimestamp() - lastThrottledTriggerTime_;
2008 if (interval < visibleAreaUserCallback.period) {
2009 executor->PostDelayedTask(std::move(task), TaskExecutor::TaskType::UI, visibleAreaUserCallback.period,
2010 "ThrottledVisibleChangeCallback", PriorityType::IDLE);
2011 } else {
2012 executor->PostTask(
2013 std::move(task), TaskExecutor::TaskType::UI, "ThrottledVisibleChangeCallback", PriorityType::IDLE);
2014 }
2015 }
2016
SetActive(bool active,bool needRebuildRenderContext)2017 void FrameNode::SetActive(bool active, bool needRebuildRenderContext)
2018 {
2019 bool activeChanged = false;
2020 if (active && !isActive_) {
2021 pattern_->OnActive();
2022 isActive_ = true;
2023 activeChanged = true;
2024 }
2025 if (!active && isActive_) {
2026 pattern_->OnInActive();
2027 isActive_ = false;
2028 activeChanged = true;
2029 }
2030 CHECK_NULL_VOID(activeChanged);
2031 auto parent = GetAncestorNodeOfFrame(false);
2032 if (parent) {
2033 parent->MarkNeedSyncRenderTree();
2034 if (needRebuildRenderContext) {
2035 auto pipeline = GetContext();
2036 CHECK_NULL_VOID(pipeline);
2037 auto task = [weak = AceType::WeakClaim(AceType::RawPtr(parent))]() {
2038 auto parent = weak.Upgrade();
2039 CHECK_NULL_VOID(parent);
2040 parent->RebuildRenderContextTree();
2041 };
2042 pipeline->AddAfterLayoutTask(task);
2043 }
2044 }
2045 if (isActive_ && SystemProperties::GetDeveloperModeOn()) {
2046 PaintDebugBoundary(SystemProperties::GetDebugBoundaryEnabled());
2047 }
2048 }
2049
SetGeometryNode(const RefPtr<GeometryNode> & node)2050 void FrameNode::SetGeometryNode(const RefPtr<GeometryNode>& node)
2051 {
2052 geometryNode_ = node;
2053 }
2054
CreateLayoutTask(bool forceUseMainThread)2055 void FrameNode::CreateLayoutTask(bool forceUseMainThread)
2056 {
2057 if (!isLayoutDirtyMarked_) {
2058 return;
2059 }
2060 SetRootMeasureNode(true);
2061 UpdateLayoutPropertyFlag();
2062 SetSkipSyncGeometryNode(false);
2063 if (layoutProperty_->GetLayoutRect()) {
2064 SetActive(true, true);
2065 Measure(std::nullopt);
2066 Layout();
2067 } else {
2068 {
2069 auto layoutConstraint = GetLayoutConstraint();
2070 ACE_SCOPED_TRACE_COMMERCIAL("CreateTaskMeasure[%s][self:%d][parent:%d][layoutConstraint:%s]"
2071 "[layoutPriority:%d][pageId:%d][depth:%d]",
2072 GetTag().c_str(), GetId(), GetAncestorNodeOfFrame(false) ? GetAncestorNodeOfFrame(false)->GetId() : 0,
2073 layoutConstraint.ToString().c_str(), GetLayoutPriority(), GetPageId(), GetDepth());
2074 Measure(layoutConstraint);
2075 }
2076 {
2077 ACE_SCOPED_TRACE_COMMERCIAL("CreateTaskLayout[%s][self:%d][parent:%d][layoutPriority:%d]"
2078 "[pageId:%d][depth:%d]",
2079 GetTag().c_str(), GetId(), GetAncestorNodeOfFrame(false) ? GetAncestorNodeOfFrame(false)->GetId() : 0,
2080 GetLayoutPriority(), GetPageId(), GetDepth());
2081 Layout();
2082 }
2083 }
2084 SetRootMeasureNode(false);
2085 }
2086
CreateRenderTask(bool forceUseMainThread)2087 std::optional<UITask> FrameNode::CreateRenderTask(bool forceUseMainThread)
2088 {
2089 if (!isRenderDirtyMarked_) {
2090 return std::nullopt;
2091 }
2092 auto wrapper = CreatePaintWrapper();
2093 CHECK_NULL_RETURN(wrapper, std::nullopt);
2094 auto task = [weak = WeakClaim(this), wrapper, paintProperty = paintProperty_]() {
2095 auto self = weak.Upgrade();
2096 ACE_SCOPED_TRACE("FrameNode[%s][id:%d]::RenderTask", self->GetTag().c_str(), self->GetId());
2097 ArkUIPerfMonitor::GetInstance().RecordRenderNode();
2098 wrapper->FlushRender();
2099 paintProperty->CleanDirty();
2100 auto eventHub = self->GetEventHubOnly<NG::EventHub>();
2101 if (self->GetInspectorId() || (eventHub && eventHub->HasNDKDrawCompletedCallback())) {
2102 auto pipeline = PipelineContext::GetCurrentContext();
2103 CHECK_NULL_VOID(pipeline);
2104 pipeline->SetNeedRenderNode(weak);
2105 }
2106 };
2107 if (forceUseMainThread || wrapper->CheckShouldRunOnMain()) {
2108 return UITask(std::move(task), MAIN_TASK);
2109 }
2110 return UITask(std::move(task), wrapper->CanRunOnWhichThread());
2111 }
2112
GetLayoutConstraint() const2113 LayoutConstraintF FrameNode::GetLayoutConstraint() const
2114 {
2115 if (geometryNode_->GetParentLayoutConstraint().has_value()) {
2116 return geometryNode_->GetParentLayoutConstraint().value();
2117 }
2118 LayoutConstraintF layoutConstraint;
2119 layoutConstraint.scaleProperty = ScaleProperty::CreateScaleProperty();
2120 auto rootWidth = PipelineContext::GetCurrentRootWidth();
2121 auto rootHeight = PipelineContext::GetCurrentRootHeight();
2122 layoutConstraint.percentReference.SetWidth(rootWidth);
2123 layoutConstraint.percentReference.SetHeight(rootHeight);
2124 layoutConstraint.maxSize.SetWidth(rootWidth);
2125 layoutConstraint.maxSize.SetHeight(rootHeight);
2126 return layoutConstraint;
2127 }
2128
UpdateLayoutPropertyFlag()2129 void FrameNode::UpdateLayoutPropertyFlag()
2130 {
2131 auto selfFlag = layoutProperty_->GetPropertyChangeFlag();
2132 if (!CheckUpdateByChildRequest(selfFlag)) {
2133 return;
2134 }
2135 if (CheckForceParentMeasureFlag(selfFlag)) {
2136 return;
2137 }
2138 auto flag = PROPERTY_UPDATE_NORMAL;
2139 const auto& children = GetChildren();
2140 for (const auto& child : children) {
2141 child->UpdateLayoutPropertyFlag();
2142 child->AdjustParentLayoutFlag(flag);
2143 if (CheckForceParentMeasureFlag(selfFlag)) {
2144 break;
2145 }
2146 }
2147 if (CheckForceParentMeasureFlag(flag)) {
2148 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
2149 }
2150 }
2151
ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag)2152 void FrameNode::ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag)
2153 {
2154 layoutProperty_->UpdatePropertyChangeFlag(propertyChangeFlag);
2155 }
2156
AdjustParentLayoutFlag(PropertyChangeFlag & flag)2157 void FrameNode::AdjustParentLayoutFlag(PropertyChangeFlag& flag)
2158 {
2159 flag = flag | layoutProperty_->GetPropertyChangeFlag();
2160 }
2161
CreateLayoutWrapper(bool forceMeasure,bool forceLayout)2162 RefPtr<LayoutWrapperNode> FrameNode::CreateLayoutWrapper(bool forceMeasure, bool forceLayout)
2163 {
2164 return UpdateLayoutWrapper(nullptr, forceMeasure, forceLayout);
2165 }
2166
UpdateLayoutWrapper(RefPtr<LayoutWrapperNode> layoutWrapper,bool forceMeasure,bool forceLayout)2167 RefPtr<LayoutWrapperNode> FrameNode::UpdateLayoutWrapper(
2168 RefPtr<LayoutWrapperNode> layoutWrapper, bool forceMeasure, bool forceLayout)
2169 {
2170 CHECK_NULL_RETURN(layoutProperty_, nullptr);
2171 CHECK_NULL_RETURN(pattern_, nullptr);
2172 if (layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE) == VisibleType::GONE) {
2173 if (!layoutWrapper) {
2174 layoutWrapper =
2175 MakeRefPtr<LayoutWrapperNode>(WeakClaim(this), MakeRefPtr<GeometryNode>(), layoutProperty_->Clone());
2176 } else {
2177 layoutWrapper->Update(WeakClaim(this), MakeRefPtr<GeometryNode>(), layoutProperty_->Clone());
2178 }
2179 layoutWrapper->SetLayoutAlgorithm(MakeRefPtr<LayoutAlgorithmWrapper>(nullptr, true, true));
2180 isLayoutDirtyMarked_ = false;
2181 return layoutWrapper;
2182 }
2183
2184 pattern_->BeforeCreateLayoutWrapper();
2185 if (forceMeasure) {
2186 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
2187 }
2188 if (forceLayout) {
2189 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_LAYOUT);
2190 }
2191 auto flag = layoutProperty_->GetPropertyChangeFlag();
2192 // It is necessary to copy the layoutProperty property to prevent the layoutProperty property from being
2193 // modified during the layout process, resulting in the problem of judging whether the front-end setting value
2194 // changes the next time js is executed.
2195 if (!layoutWrapper) {
2196 layoutWrapper =
2197 MakeRefPtr<LayoutWrapperNode>(WeakClaim(this), geometryNode_->Clone(), layoutProperty_->Clone());
2198 } else {
2199 layoutWrapper->Update(WeakClaim(this), geometryNode_->Clone(), layoutProperty_->Clone());
2200 }
2201 do {
2202 if (CheckNeedMeasure(flag) || forceMeasure) {
2203 layoutWrapper->SetLayoutAlgorithm(MakeRefPtr<LayoutAlgorithmWrapper>(pattern_->CreateLayoutAlgorithm()));
2204 bool forceChildMeasure = CheckMeasureFlag(flag) || CheckMeasureSelfAndChildFlag(flag) || forceMeasure;
2205 UpdateChildrenLayoutWrapper(layoutWrapper, forceChildMeasure, false);
2206 break;
2207 }
2208 if (CheckNeedLayout(flag) || forceLayout) {
2209 layoutWrapper->SetLayoutAlgorithm(
2210 MakeRefPtr<LayoutAlgorithmWrapper>(pattern_->CreateLayoutAlgorithm(), true, false));
2211 UpdateChildrenLayoutWrapper(layoutWrapper, false, false);
2212 break;
2213 }
2214 layoutWrapper->SetLayoutAlgorithm(MakeRefPtr<LayoutAlgorithmWrapper>(nullptr, true, true));
2215 } while (false);
2216 // check position flag.
2217 layoutWrapper->SetOutOfLayout(renderContext_->HasPosition());
2218 layoutWrapper->SetActive(isActive_);
2219 layoutWrapper->SetIsOverlayNode(layoutProperty_->IsOverlayNode());
2220 isLayoutDirtyMarked_ = false;
2221 return layoutWrapper;
2222 }
2223
UpdateChildrenLayoutWrapper(const RefPtr<LayoutWrapperNode> & self,bool forceMeasure,bool forceLayout)2224 void FrameNode::UpdateChildrenLayoutWrapper(const RefPtr<LayoutWrapperNode>& self, bool forceMeasure, bool forceLayout)
2225 {
2226 const auto& children = GetChildren();
2227 for (const auto& child : children) {
2228 child->AdjustLayoutWrapperTree(self, forceMeasure, forceLayout);
2229 }
2230 }
2231
AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode> & parent,bool forceMeasure,bool forceLayout)2232 void FrameNode::AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode>& parent, bool forceMeasure, bool forceLayout)
2233 {
2234 ACE_DCHECK(parent);
2235 CHECK_NULL_VOID(layoutProperty_);
2236 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
2237 if (geometryTransition != nullptr && geometryTransition->IsNodeOutAndActive(WeakClaim(this))) {
2238 return;
2239 }
2240 auto layoutWrapper = CreateLayoutWrapper(forceMeasure, forceLayout);
2241 parent->AppendChild(layoutWrapper, layoutProperty_->IsOverlayNode());
2242 }
2243
GetContentModifier()2244 RefPtr<ContentModifier> FrameNode::GetContentModifier()
2245 {
2246 CHECK_NULL_RETURN(pattern_, nullptr);
2247 auto wrapper = CreatePaintWrapper();
2248 CHECK_NULL_RETURN(wrapper, nullptr);
2249 auto paintMethod = pattern_->CreateNodePaintMethod();
2250 if (!paintMethod || extensionHandler_ || renderContext_->GetAccessibilityFocus().value_or(false)) {
2251 paintMethod = pattern_->CreateDefaultNodePaintMethod();
2252 }
2253 CHECK_NULL_RETURN(paintMethod, nullptr);
2254 auto contentModifier = DynamicCast<ContentModifier>(paintMethod->GetContentModifier(AceType::RawPtr(wrapper)));
2255 return contentModifier;
2256 }
2257
CreatePaintWrapper()2258 RefPtr<PaintWrapper> FrameNode::CreatePaintWrapper()
2259 {
2260 pattern_->BeforeCreatePaintWrapper();
2261 isRenderDirtyMarked_ = false;
2262 if (kitNode_ && kitNode_->GetPattern()) {
2263 auto method = kitNode_->GetPattern()->CreateNodePaintMethod();
2264 auto paintWrapper = MakeRefPtr<PaintWrapper>(
2265 renderContext_, geometryNode_->Clone(), paintProperty_->Clone(), extensionHandler_);
2266 paintWrapper->SetKitNodePaintMethod(method);
2267 return paintWrapper;
2268 }
2269 auto paintMethod = pattern_->CreateNodePaintMethod();
2270 if (paintMethod || extensionHandler_ || renderContext_->GetAccessibilityFocus().value_or(false)) {
2271 // It is necessary to copy the layoutProperty property to prevent the paintProperty_ property from being
2272 // modified during the paint process, resulting in the problem of judging whether the front-end setting value
2273 // changes the next time js is executed.
2274 if (!paintMethod) {
2275 paintMethod = pattern_->CreateDefaultNodePaintMethod();
2276 }
2277
2278 auto paintWrapper = MakeRefPtr<PaintWrapper>(
2279 renderContext_, geometryNode_->Clone(), paintProperty_->Clone(), extensionHandler_);
2280 paintWrapper->SetNodePaintMethod(paintMethod);
2281 return paintWrapper;
2282 }
2283 return nullptr;
2284 }
2285
PostIdleTask(std::function<void (int64_t deadline,bool canUseLongPredictTask)> && task)2286 void FrameNode::PostIdleTask(std::function<void(int64_t deadline, bool canUseLongPredictTask)>&& task)
2287 {
2288 auto context = GetContext();
2289 CHECK_NULL_VOID(context);
2290 context->AddPredictTask(std::move(task));
2291 }
2292
UpdateLayoutConstraint(const MeasureProperty & calcLayoutConstraint)2293 void FrameNode::UpdateLayoutConstraint(const MeasureProperty& calcLayoutConstraint)
2294 {
2295 layoutProperty_->UpdateCalcLayoutProperty(calcLayoutConstraint);
2296 }
2297
RebuildRenderContextTree()2298 void FrameNode::RebuildRenderContextTree()
2299 {
2300 if (!needSyncRenderTree_) {
2301 return;
2302 }
2303 auto pipeline = GetContextRefPtr();
2304 if (pipeline && !pipeline->CheckThreadSafe()) {
2305 LOGW("RebuildRenderContextTree doesn't run on UI thread!");
2306 }
2307 frameChildren_.clear();
2308 std::list<RefPtr<FrameNode>> children;
2309 // generate full children list, including disappear children.
2310 GenerateOneDepthVisibleFrameWithTransition(children);
2311 if (overlayNode_) {
2312 auto property = overlayNode_->GetLayoutProperty();
2313 if (property && property->GetVisibilityValue(VisibleType::VISIBLE) == VisibleType::VISIBLE) {
2314 children.push_back(overlayNode_);
2315 }
2316 }
2317 if (accessibilityFocusPaintNode_) {
2318 children.push_back(accessibilityFocusPaintNode_);
2319 }
2320 for (const auto& child : children) {
2321 frameChildren_.emplace(child);
2322 }
2323 renderContext_->RebuildFrame(this, children);
2324 pattern_->OnRebuildFrame();
2325 if (isDeleteRsNode_) {
2326 auto parentFrameNode = GetParentFrameNode();
2327 if (parentFrameNode) {
2328 parentFrameNode->MarkNeedSyncRenderTree();
2329 parentFrameNode->RebuildRenderContextTree();
2330 }
2331 }
2332 needSyncRenderTree_ = false;
2333 }
2334
MarkModifyDone()2335 void FrameNode::MarkModifyDone()
2336 {
2337 pattern_->OnModifyDone();
2338 auto pipeline = PipelineContext::GetCurrentContextSafely();
2339 if (pipeline) {
2340 auto privacyManager = pipeline->GetPrivacySensitiveManager();
2341 if (privacyManager) {
2342 if (IsPrivacySensitive()) {
2343 LOGI("store sensitive node, %{public}d", GetId());
2344 privacyManager->StoreNode(AceType::WeakClaim(this));
2345 } else {
2346 privacyManager->RemoveNode(AceType::WeakClaim(this));
2347 }
2348 }
2349 }
2350 if (!isRestoreInfoUsed_) {
2351 isRestoreInfoUsed_ = true;
2352 int32_t restoreId = GetRestoreId();
2353 if (pipeline && restoreId >= 0) {
2354 // store distribute node
2355 pipeline->StoreNode(restoreId, AceType::WeakClaim(this));
2356 // restore distribute node info
2357 std::string restoreInfo;
2358 if (pipeline->GetRestoreInfo(restoreId, restoreInfo)) {
2359 pattern_->OnRestoreInfo(restoreInfo);
2360 }
2361 }
2362 }
2363 if (eventHub_) {
2364 eventHub_->MarkModifyDone();
2365 }
2366 renderContext_->OnModifyDone();
2367 #if (defined(__aarch64__) || defined(__x86_64__))
2368 if (Recorder::IsCacheAvaliable()) {
2369 auto pipeline = PipelineContext::GetCurrentContext();
2370 CHECK_NULL_VOID(pipeline);
2371 pipeline->AddAfterRenderTask([weak = WeakPtr(pattern_)]() {
2372 auto pattern = weak.Upgrade();
2373 CHECK_NULL_VOID(pattern);
2374 pattern->OnAfterModifyDone();
2375 });
2376 }
2377 #endif
2378 }
2379
OnMountToParentDone()2380 [[deprecated("using AfterMountToParent")]] void FrameNode::OnMountToParentDone()
2381 {
2382 pattern_->OnMountToParentDone();
2383 }
2384
AfterMountToParent()2385 void FrameNode::AfterMountToParent()
2386 {
2387 if (pattern_) {
2388 pattern_->AfterMountToParent();
2389 }
2390 }
2391
FlushUpdateAndMarkDirty()2392 void FrameNode::FlushUpdateAndMarkDirty()
2393 {
2394 MarkDirtyNode();
2395 }
2396
MarkDirtyNode(PropertyChangeFlag extraFlag)2397 void FrameNode::MarkDirtyNode(PropertyChangeFlag extraFlag)
2398 {
2399 if (IsFreeze()) {
2400 // store the flag.
2401 layoutProperty_->UpdatePropertyChangeFlag(extraFlag);
2402 paintProperty_->UpdatePropertyChangeFlag(extraFlag);
2403 return;
2404 }
2405 if (CheckNeedMakePropertyDiff(extraFlag)) {
2406 if (isPropertyDiffMarked_) {
2407 return;
2408 }
2409 auto context = GetContextWithCheck();
2410 CHECK_NULL_VOID(context);
2411 context->AddDirtyPropertyNode(Claim(this));
2412 isPropertyDiffMarked_ = true;
2413 return;
2414 }
2415 MarkDirtyNode(IsMeasureBoundary(), IsRenderBoundary(), extraFlag);
2416 }
2417
ProcessFreezeNode()2418 void FrameNode::ProcessFreezeNode()
2419 {
2420 MarkDirtyNode();
2421 }
2422
OnFreezeStateChange()2423 void FrameNode::OnFreezeStateChange()
2424 {
2425 if (IsFreeze()) {
2426 return;
2427 }
2428 // unlock freeze, mark dirty to process freeze node.
2429 auto layoutFlag = layoutProperty_->GetPropertyChangeFlag();
2430 auto paintFlag = paintProperty_->GetPropertyChangeFlag();
2431 if (CheckNoChanged(layoutFlag | paintFlag)) {
2432 return;
2433 }
2434 auto pipeline = GetContext();
2435 CHECK_NULL_VOID(pipeline);
2436 pipeline->AddDirtyFreezeNode(this);
2437 }
2438
GetAncestorNodeOfFrame(bool checkBoundary) const2439 RefPtr<FrameNode> FrameNode::GetAncestorNodeOfFrame(bool checkBoundary) const
2440 {
2441 if (checkBoundary && IsWindowBoundary()) {
2442 return nullptr;
2443 }
2444 auto parent = GetParent();
2445 while (parent) {
2446 auto parentFrame = DynamicCast<FrameNode>(parent);
2447 if (parentFrame) {
2448 return parentFrame;
2449 }
2450 parent = parent->GetParent();
2451 }
2452 return nullptr;
2453 }
2454
GetPageNode()2455 RefPtr<FrameNode> FrameNode::GetPageNode()
2456 {
2457 if (GetTag() == "page") {
2458 return Claim(this);
2459 }
2460 auto parent = GetParent();
2461 while (parent && parent->GetTag() != "page") {
2462 parent = parent->GetParent();
2463 }
2464 return AceType::DynamicCast<FrameNode>(parent);
2465 }
2466
GetFirstAutoFillContainerNode()2467 RefPtr<FrameNode> FrameNode::GetFirstAutoFillContainerNode()
2468 {
2469 if (IsAutoFillContainerNode()) {
2470 return Claim(this);
2471 }
2472 auto parent = GetParent();
2473 while (parent && !parent->IsAutoFillContainerNode()) {
2474 parent = parent->GetParent();
2475 }
2476 return AceType::DynamicCast<FrameNode>(parent);
2477 }
2478
NotifyFillRequestSuccess(RefPtr<ViewDataWrap> viewDataWrap,RefPtr<PageNodeInfoWrap> nodeWrap,AceAutoFillType autoFillType)2479 void FrameNode::NotifyFillRequestSuccess(
2480 RefPtr<ViewDataWrap> viewDataWrap, RefPtr<PageNodeInfoWrap> nodeWrap, AceAutoFillType autoFillType)
2481 {
2482 if (pattern_) {
2483 pattern_->NotifyFillRequestSuccess(viewDataWrap, nodeWrap, autoFillType);
2484 }
2485 }
2486
NotifyFillRequestFailed(int32_t errCode,const std::string & fillContent,bool isPopup)2487 void FrameNode::NotifyFillRequestFailed(int32_t errCode, const std::string& fillContent, bool isPopup)
2488 {
2489 if (pattern_) {
2490 pattern_->NotifyFillRequestFailed(errCode, fillContent, isPopup);
2491 }
2492 }
2493
MarkNeedRenderOnly()2494 void FrameNode::MarkNeedRenderOnly()
2495 {
2496 MarkNeedRender(IsRenderBoundary());
2497 }
2498
MarkNeedRender(bool isRenderBoundary)2499 void FrameNode::MarkNeedRender(bool isRenderBoundary)
2500 {
2501 auto context = GetContext();
2502 CHECK_NULL_VOID(context);
2503 // If it has dirtyLayoutBox, need to mark dirty after layout done.
2504 paintProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_RENDER);
2505 if (isRenderDirtyMarked_ || isLayoutDirtyMarked_) {
2506 return;
2507 }
2508 isRenderDirtyMarked_ = true;
2509 if (isRenderBoundary) {
2510 context->AddDirtyRenderNode(Claim(this));
2511 return;
2512 }
2513 auto parent = GetAncestorNodeOfFrame(false);
2514 if (parent) {
2515 parent->MarkDirtyNode(PROPERTY_UPDATE_RENDER_BY_CHILD_REQUEST);
2516 }
2517 }
2518
RequestParentDirty()2519 bool FrameNode::RequestParentDirty()
2520 {
2521 auto parent = GetAncestorNodeOfFrame(false);
2522 CHECK_NULL_RETURN(parent, false);
2523 parent->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
2524 return true;
2525 }
2526
MarkDirtyNode(bool isMeasureBoundary,bool isRenderBoundary,PropertyChangeFlag extraFlag)2527 void FrameNode::MarkDirtyNode(bool isMeasureBoundary, bool isRenderBoundary, PropertyChangeFlag extraFlag)
2528 {
2529 layoutProperty_->UpdatePropertyChangeFlag(extraFlag);
2530 paintProperty_->UpdatePropertyChangeFlag(extraFlag);
2531 auto layoutFlag = layoutProperty_->GetPropertyChangeFlag();
2532 auto paintFlag = paintProperty_->GetPropertyChangeFlag();
2533 if (CheckNoChanged(layoutFlag | paintFlag)) {
2534 return;
2535 }
2536 auto context = GetContext();
2537 CHECK_NULL_VOID(context);
2538
2539 if (CheckNeedRequestMeasureAndLayout(layoutFlag)) {
2540 if ((!isMeasureBoundary && IsNeedRequestParentMeasure())) {
2541 if (RequestParentDirty()) {
2542 return;
2543 }
2544 }
2545 if (isLayoutDirtyMarked_) {
2546 return;
2547 }
2548 isLayoutDirtyMarked_ = true;
2549 context->AddDirtyLayoutNode(Claim(this));
2550 return;
2551 }
2552 layoutProperty_->CleanDirty();
2553 MarkNeedRender(isRenderBoundary);
2554 }
2555
IsNeedRequestParentMeasure() const2556 bool FrameNode::IsNeedRequestParentMeasure() const
2557 {
2558 auto layoutFlag = layoutProperty_->GetPropertyChangeFlag();
2559 if (layoutFlag == PROPERTY_UPDATE_BY_CHILD_REQUEST) {
2560 const auto& calcLayoutConstraint = layoutProperty_->GetCalcLayoutConstraint();
2561 if (calcLayoutConstraint && calcLayoutConstraint->selfIdealSize &&
2562 calcLayoutConstraint->selfIdealSize->IsValid()) {
2563 return false;
2564 }
2565 }
2566 return CheckNeedRequestParentMeasure(layoutFlag);
2567 }
2568
OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>> & visibleList)2569 void FrameNode::OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& visibleList)
2570 {
2571 if (isLayoutNode_) {
2572 UINode::GenerateOneDepthVisibleFrame(visibleList);
2573 if (overlayNode_) {
2574 visibleList.emplace_back(overlayNode_);
2575 }
2576 return;
2577 }
2578 if (isActive_ && IsVisible()) {
2579 visibleList.emplace_back(Claim(this));
2580 }
2581 }
2582
OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>> & allList)2583 void FrameNode::OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>>& allList)
2584 {
2585 allList.emplace_back(Claim(this));
2586 }
2587
OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>> & visibleList)2588 void FrameNode::OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList)
2589 {
2590 if (isLayoutNode_) {
2591 UINode::GenerateOneDepthVisibleFrameWithTransition(visibleList);
2592 if (overlayNode_) {
2593 visibleList.emplace_back(overlayNode_);
2594 }
2595 return;
2596 }
2597
2598 auto context = GetRenderContext();
2599 CHECK_NULL_VOID(context);
2600 // skip if 1.not active or 2.not visible and has no transition out animation.
2601 if (!isActive_ || (!IsVisible() && !context->HasTransitionOutAnimation())) {
2602 return;
2603 }
2604 visibleList.emplace_back(Claim(this));
2605 }
2606
OnGenerateOneDepthVisibleFrameWithOffset(std::list<RefPtr<FrameNode>> & visibleList,OffsetF & offset)2607 void FrameNode::OnGenerateOneDepthVisibleFrameWithOffset(std::list<RefPtr<FrameNode>>& visibleList, OffsetF& offset)
2608 {
2609 if (isLayoutNode_) {
2610 isFind_ = true;
2611 offset += GetGeometryNode()->GetFrameOffset();
2612 UINode::GenerateOneDepthVisibleFrameWithOffset(visibleList, offset);
2613 if (overlayNode_) {
2614 visibleList.emplace_back(overlayNode_);
2615 }
2616 return;
2617 }
2618
2619 auto context = GetRenderContext();
2620 CHECK_NULL_VOID(context);
2621 // skip if 1.not active or 2.not visible and has no transition out animation.
2622 if (!isActive_ || (!IsVisible() && !context->HasTransitionOutAnimation())) {
2623 return;
2624 }
2625 visibleList.emplace_back(Claim(this));
2626 }
2627
IsMeasureBoundary()2628 bool FrameNode::IsMeasureBoundary()
2629 {
2630 return isMeasureBoundary_ || pattern_->IsMeasureBoundary();
2631 }
2632
IsRenderBoundary()2633 bool FrameNode::IsRenderBoundary()
2634 {
2635 return pattern_->IsRenderBoundary();
2636 }
2637
GetPattern() const2638 const RefPtr<Pattern>& FrameNode::GetPattern() const
2639 {
2640 return pattern_;
2641 }
2642
IsAtomicNode() const2643 bool FrameNode::IsAtomicNode() const
2644 {
2645 if (kitNode_ && kitNode_->GetPattern()) {
2646 return kitNode_->GetPattern()->IsAtomicNode();
2647 }
2648 return pattern_->IsAtomicNode();
2649 }
2650
GetHitTestMode() const2651 HitTestMode FrameNode::GetHitTestMode() const
2652 {
2653 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
2654 return gestureHub ? gestureHub->GetHitTestMode() : HitTestMode::HTMDEFAULT;
2655 }
2656
SetHitTestMode(HitTestMode mode)2657 void FrameNode::SetHitTestMode(HitTestMode mode)
2658 {
2659 auto gestureHub = GetOrCreateGestureEventHub();
2660 CHECK_NULL_VOID(gestureHub);
2661 gestureHub->SetHitTestMode(mode);
2662 }
2663
GetTouchable() const2664 bool FrameNode::GetTouchable() const
2665 {
2666 CHECK_NULL_RETURN(eventHub_, true);
2667 auto gestureHub = eventHub_->GetGestureEventHub();
2668 return gestureHub ? gestureHub->GetTouchable() : true;
2669 }
2670
GetMonopolizeEvents() const2671 bool FrameNode::GetMonopolizeEvents() const
2672 {
2673 CHECK_NULL_RETURN(eventHub_, false);
2674 auto gestureHub = eventHub_->GetGestureEventHub();
2675 return gestureHub ? gestureHub->GetMonopolizeEvents() : false;
2676 }
2677
2678 // get paint rect include graphic properties
GetPaintRectWithTransform() const2679 RectF FrameNode::GetPaintRectWithTransform() const
2680 {
2681 return renderContext_->GetPaintRectWithTransform();
2682 }
2683
GetTransformScale() const2684 VectorF FrameNode::GetTransformScale() const
2685 {
2686 return renderContext_->GetTransformScaleValue({ 1.0f, 1.0f });
2687 }
2688
IsPaintRectWithTransformValid()2689 bool FrameNode::IsPaintRectWithTransformValid()
2690 {
2691 auto& paintRectWithTransform = GetOrRefreshMatrixFromCache().paintRectWithTransform;
2692 if (NearZero(paintRectWithTransform.Width()) || NearZero(paintRectWithTransform.Height())) {
2693 return true;
2694 }
2695 return false;
2696 }
2697
IsOutOfTouchTestRegion(const PointF & parentRevertPoint,const TouchEvent & touchEvent,std::vector<RectF> * regionList)2698 bool FrameNode::IsOutOfTouchTestRegion(const PointF& parentRevertPoint, const TouchEvent& touchEvent,
2699 std::vector<RectF>* regionList)
2700 {
2701 bool isInChildRegion = false;
2702 auto paintRect = renderContext_->GetPaintRectWithoutTransform();
2703 if (pattern_->IsResponseRegionExpandingNeededForStylus(touchEvent)) {
2704 paintRect = pattern_->ExpandDefaultResponseRegion(paintRect);
2705 }
2706 std::vector<RectF> responseRegionList;
2707 if (regionList) {
2708 responseRegionList = *regionList;
2709 } else {
2710 responseRegionList = GetResponseRegionList(paintRect, static_cast<int32_t>(touchEvent.sourceType));
2711 }
2712
2713 auto revertPoint = parentRevertPoint;
2714 MapPointTo(revertPoint, GetOrRefreshMatrixFromCache().revertMatrix);
2715 auto subRevertPoint = revertPoint - paintRect.GetOffset();
2716 auto clip = renderContext_->GetClipEdge().value_or(false);
2717 if (!InResponseRegionList(revertPoint, responseRegionList) || !GetTouchable()) {
2718 if (clip) {
2719 return true;
2720 }
2721 for (auto iter = frameChildren_.rbegin(); iter != frameChildren_.rend(); ++iter) {
2722 const auto& child = iter->Upgrade();
2723 if (child && !child->IsOutOfTouchTestRegion(subRevertPoint, touchEvent)) {
2724 isInChildRegion = true;
2725 break;
2726 }
2727 }
2728 if (!isInChildRegion) {
2729 return true;
2730 }
2731 }
2732 return false;
2733 }
2734
AddJudgeToTargetComponent(RefPtr<TargetComponent> & targetComponent)2735 void FrameNode::AddJudgeToTargetComponent(RefPtr<TargetComponent>& targetComponent)
2736 {
2737 CHECK_NULL_VOID(eventHub_);
2738 auto gestureHub = eventHub_->GetGestureEventHub();
2739 if (gestureHub) {
2740 auto callback = gestureHub->GetOnGestureJudgeBeginCallback();
2741 targetComponent->SetOnGestureJudgeBegin(std::move(callback));
2742 auto callbackNative = gestureHub->GetOnGestureJudgeNativeBeginCallback();
2743 if (callbackNative) {
2744 targetComponent->SetOnGestureJudgeNativeBegin(std::move(callbackNative));
2745 }
2746
2747 if (!targetComponent->IsInnerNodeGestureRecognizerJudgeSet()) {
2748 auto gestureRecognizerJudgeCallback = gestureHub->GetOnGestureRecognizerJudgeBegin();
2749 targetComponent->SetOnGestureRecognizerJudgeBegin(std::move(gestureRecognizerJudgeCallback));
2750 }
2751
2752 auto pattern = GetPattern();
2753 if (pattern) {
2754 if (GetExposeInnerGestureFlag()) {
2755 auto gestureRecognizerJudgeCallback = gestureHub->GetOnGestureRecognizerJudgeBegin();
2756 pattern->AddInnerOnGestureRecognizerJudgeBegin(std::move(gestureRecognizerJudgeCallback));
2757 } else {
2758 pattern->RecoverInnerOnGestureRecognizerJudgeBegin();
2759 }
2760 }
2761 }
2762 }
2763
TouchTest(const PointF & globalPoint,const PointF & parentLocalPoint,const PointF & parentRevertPoint,TouchRestrict & touchRestrict,TouchTestResult & result,int32_t touchId,ResponseLinkResult & responseLinkResult,bool isDispatch)2764 HitTestResult FrameNode::TouchTest(const PointF& globalPoint, const PointF& parentLocalPoint,
2765 const PointF& parentRevertPoint, TouchRestrict& touchRestrict, TouchTestResult& result, int32_t touchId,
2766 ResponseLinkResult& responseLinkResult, bool isDispatch)
2767 {
2768 auto& cacheMatrixInfo = GetOrRefreshMatrixFromCache();
2769 auto paintRect = cacheMatrixInfo.paintRectWithTransform;
2770 if (!isActive_) {
2771 TAG_LOGW(AceLogTag::ACE_UIEVENT, "%{public}s is inActive, need't do touch test. Rect is %{public}s",
2772 GetTag().c_str(), paintRect.ToString().c_str());
2773 return HitTestResult::OUT_OF_REGION;
2774 }
2775 if (eventHub_ && !eventHub_->IsEnabled()) {
2776 TAG_LOGW(AceLogTag::ACE_UIEVENT, "%{public}s eventHub not enabled, need't do touch test", GetTag().c_str());
2777 return HitTestResult::OUT_OF_REGION;
2778 }
2779 auto origRect = renderContext_->GetPaintRectWithoutTransform();
2780 auto localMat = cacheMatrixInfo.localMatrix;
2781 if (!touchRestrict.touchEvent.isMouseTouchTest) {
2782 localMat_ = localMat;
2783 }
2784
2785 int32_t parentId = -1;
2786 auto parent = GetAncestorNodeOfFrame(true);
2787 if (parent) {
2788 parentId = parent->GetId();
2789 }
2790
2791 auto defaultResponseRegion = origRect;
2792 if (pattern_->IsResponseRegionExpandingNeededForStylus(touchRestrict.touchEvent)) {
2793 defaultResponseRegion = pattern_->ExpandDefaultResponseRegion(origRect);
2794 }
2795 auto responseRegionList =
2796 GetResponseRegionList(defaultResponseRegion, static_cast<int32_t>(touchRestrict.sourceType));
2797 if (SystemProperties::GetDebugEnabled()) {
2798 TAG_LOGD(AceLogTag::ACE_UIEVENT, "TouchTest: point is " SEC_PLD(%{public}s) " in %{public}s, depth: %{public}d",
2799 SEC_PARAM(parentRevertPoint.ToString().c_str()), GetTag().c_str(), GetDepth());
2800 for ([[maybe_unused]] const auto& rect : responseRegionList) {
2801 TAG_LOGD(AceLogTag::ACE_UIEVENT, "TouchTest: responseRegionList is " SEC_PLD(%{public}s)
2802 ", point is " SEC_PLD(%{public}s),
2803 SEC_PARAM(rect.ToString().c_str()), SEC_PARAM(parentRevertPoint.ToString().c_str()));
2804 }
2805 }
2806 {
2807 ACE_DEBUG_SCOPED_TRACE("FrameNode::IsOutOfTouchTestRegion");
2808 bool isOutOfRegion = IsOutOfTouchTestRegion(parentRevertPoint, touchRestrict.touchEvent, &responseRegionList);
2809 AddFrameNodeSnapshot(!isOutOfRegion, parentId, responseRegionList, touchRestrict.touchTestType);
2810 if ((!isDispatch) && isOutOfRegion) {
2811 return HitTestResult::OUT_OF_REGION;
2812 }
2813 }
2814
2815 RefPtr<TargetComponent> targetComponent;
2816 if (targetComponent_.Upgrade()) {
2817 targetComponent = targetComponent_.Upgrade();
2818 } else {
2819 targetComponent = MakeRefPtr<TargetComponent>();
2820 targetComponent_ = targetComponent;
2821 }
2822 targetComponent->SetNode(WeakClaim(this));
2823
2824 HitTestResult testResult = HitTestResult::OUT_OF_REGION;
2825 bool preventBubbling = false;
2826 // Child nodes are repackaged into gesture groups (parallel gesture groups, exclusive gesture groups, etc.)
2827 // based on the gesture attributes set by the current parent node (high and low priority, parallel gestures,
2828 // etc.), the newComingTargets is the template object to collect child nodes gesture and used by gestureHub to
2829 // pack gesture group.
2830 TouchTestResult newComingTargets;
2831 auto tmp = parentLocalPoint - paintRect.GetOffset();
2832 auto preLocation = tmp;
2833 renderContext_->GetPointWithTransform(tmp);
2834 const auto localPoint = tmp;
2835 auto localTransformOffset = preLocation - localPoint;
2836
2837 auto revertPoint = parentRevertPoint;
2838 MapPointTo(revertPoint, cacheMatrixInfo.revertMatrix);
2839 auto subRevertPoint = revertPoint - origRect.GetOffset();
2840 bool consumed = false;
2841
2842 HitTestMode onTouchInterceptresult = HitTestMode::HTMDEFAULT;
2843 if (touchRestrict.inputEventType != InputEventType::MOUSE_BUTTON) {
2844 onTouchInterceptresult = TriggerOnTouchIntercept(touchRestrict.touchEvent);
2845 }
2846 TouchResult touchRes;
2847 if (onTouchInterceptresult != HitTestMode::HTMBLOCK) {
2848 std::vector<TouchTestInfo> touchInfos;
2849 CollectTouchInfos(globalPoint, subRevertPoint, touchInfos);
2850 touchRes = GetOnChildTouchTestRet(touchInfos);
2851 if ((touchRes.strategy != TouchTestStrategy::DEFAULT) && touchRes.id.empty()) {
2852 TAG_LOGW(AceLogTag::ACE_UIEVENT, "onChildTouchTest result is: "
2853 "id = " SEC_PLD(%{public}s) ", strategy = %{public}d.",
2854 SEC_PARAM(touchRes.id.c_str()), static_cast<int32_t>(touchRes.strategy));
2855 touchRes.strategy = TouchTestStrategy::DEFAULT;
2856 }
2857
2858 auto childNode = GetDispatchFrameNode(touchRes);
2859 if (childNode != nullptr) {
2860 TAG_LOGD(AceLogTag::ACE_UIEVENT, SEC_PLD(%{public}s) " do TouchTest, parameter isDispatch is true.",
2861 SEC_PARAM(childNode->GetInspectorId()->c_str()));
2862 auto hitResult = childNode->TouchTest(globalPoint, localPoint, subRevertPoint, touchRestrict,
2863 newComingTargets, touchId, responseLinkResult, true);
2864 if (touchRes.strategy == TouchTestStrategy::FORWARD ||
2865 touchRes.strategy == TouchTestStrategy::FORWARD_COMPETITION) {
2866 touchRestrict.childTouchTestList.emplace_back(touchRes.id);
2867 }
2868 if (hitResult == HitTestResult::STOP_BUBBLING) {
2869 preventBubbling = true;
2870 consumed = true;
2871 }
2872
2873 if (hitResult == HitTestResult::BUBBLING) {
2874 consumed = true;
2875 }
2876 }
2877 }
2878
2879 for (auto iter = frameChildren_.rbegin(); iter != frameChildren_.rend(); ++iter) {
2880 if (GetHitTestMode() == HitTestMode::HTMBLOCK) {
2881 break;
2882 }
2883 if (onTouchInterceptresult != HitTestMode::HTMBLOCK) {
2884 if (touchRes.strategy == TouchTestStrategy::FORWARD) {
2885 break;
2886 }
2887 }
2888
2889 const auto& child = iter->Upgrade();
2890 if (!child) {
2891 continue;
2892 }
2893 if (onTouchInterceptresult != HitTestMode::HTMBLOCK) {
2894 std::string id;
2895 if (child->GetInspectorId().has_value()) {
2896 id = child->GetInspectorId().value();
2897 }
2898 if (touchRes.strategy == TouchTestStrategy::FORWARD_COMPETITION && touchRes.id == id) {
2899 continue;
2900 }
2901 }
2902
2903 auto childHitResult = child->TouchTest(
2904 globalPoint, localPoint, subRevertPoint, touchRestrict, newComingTargets, touchId, responseLinkResult);
2905 if (childHitResult == HitTestResult::STOP_BUBBLING) {
2906 preventBubbling = true;
2907 consumed = true;
2908 if ((child->GetHitTestMode() == HitTestMode::HTMBLOCK) ||
2909 (child->GetHitTestMode() == HitTestMode::HTMDEFAULT) ||
2910 (child->GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ||
2911 ((child->GetHitTestMode() != HitTestMode::HTMTRANSPARENT) && IsExclusiveEventForChild())) {
2912 break;
2913 }
2914 }
2915
2916 // In normal process, the node block the brother node.
2917 if (childHitResult == HitTestResult::BUBBLING &&
2918 ((child->GetHitTestMode() == HitTestMode::HTMDEFAULT) ||
2919 (child->GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ||
2920 ((child->GetHitTestMode() != HitTestMode::HTMTRANSPARENT) && IsExclusiveEventForChild()))) {
2921 consumed = true;
2922 break;
2923 }
2924 }
2925
2926 AddJudgeToTargetComponent(targetComponent);
2927
2928 // first update HitTestResult by children status.
2929 if (consumed) {
2930 testResult = preventBubbling ? HitTestResult::STOP_BUBBLING : HitTestResult::BUBBLING;
2931 consumed = false;
2932 } else if (GetHitTestMode() == HitTestMode::HTMBLOCK) {
2933 testResult = HitTestResult::STOP_BUBBLING;
2934 }
2935
2936 if (!preventBubbling && (GetHitTestMode() != HitTestMode::HTMNONE) &&
2937 (isDispatch || (InResponseRegionList(revertPoint, responseRegionList)))) {
2938 pattern_->OnTouchTestHit(touchRestrict.hitTestType);
2939 consumed = true;
2940 if (touchRestrict.hitTestType == SourceType::TOUCH) {
2941 auto gestureHub = GetOrCreateGestureEventHub();
2942 if (gestureHub) {
2943 TouchTestResult finalResult;
2944 ResponseLinkResult newComingResponseLinkTargets;
2945 const auto coordinateOffset = globalPoint - localPoint - localTransformOffset;
2946 preventBubbling = gestureHub->ProcessTouchTestHit(coordinateOffset, touchRestrict, newComingTargets,
2947 finalResult, touchId, localPoint, targetComponent, newComingResponseLinkTargets);
2948 newComingTargets.swap(finalResult);
2949 TriggerShouldParallelInnerWith(newComingResponseLinkTargets, responseLinkResult);
2950 responseLinkResult.splice(responseLinkResult.end(), std::move(newComingResponseLinkTargets));
2951 }
2952 } else if (touchRestrict.hitTestType == SourceType::MOUSE) {
2953 preventBubbling = ProcessMouseTestHit(globalPoint, localPoint, touchRestrict, newComingTargets);
2954 }
2955 }
2956
2957 result.splice(result.end(), std::move(newComingTargets));
2958 if (touchRestrict.hitTestType == SourceType::TOUCH) {
2959 // combine into exclusive recognizer group.
2960 auto gestureHub = GetOrCreateGestureEventHub();
2961 if (gestureHub) {
2962 gestureHub->CombineIntoExclusiveRecognizer(globalPoint, localPoint, result, touchId);
2963 }
2964 }
2965
2966 // consumed by children and return result.
2967 if (!consumed) {
2968 return testResult;
2969 }
2970
2971 if (testResult == HitTestResult::OUT_OF_REGION) {
2972 // consume only by self.
2973 if (preventBubbling) {
2974 return HitTestResult::STOP_BUBBLING;
2975 }
2976 return (GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ? HitTestResult::SELF_TRANSPARENT
2977 : HitTestResult::BUBBLING;
2978 }
2979 // consume by self and children.
2980 return testResult;
2981 }
2982
ProcessMouseTestHit(const PointF & globalPoint,const PointF & localPoint,TouchRestrict & touchRestrict,TouchTestResult & newComingTargets)2983 bool FrameNode::ProcessMouseTestHit(const PointF& globalPoint, const PointF& localPoint,
2984 TouchRestrict& touchRestrict, TouchTestResult& newComingTargets)
2985 {
2986 CHECK_NULL_RETURN(eventHub_, false);
2987 auto mouseHub = eventHub_->GetInputEventHub();
2988 if (!mouseHub) {
2989 return false;
2990 }
2991
2992 const auto coordinateOffset = globalPoint - localPoint;
2993 if (touchRestrict.touchEvent.IsPenHoverEvent()) {
2994 return mouseHub->ProcessPenHoverTestHit(coordinateOffset, newComingTargets);
2995 }
2996
2997 return mouseHub->ProcessMouseTestHit(coordinateOffset, newComingTargets);
2998 }
2999
GetResponseRegionList(const RectF & rect,int32_t sourceType)3000 std::vector<RectF> FrameNode::GetResponseRegionList(const RectF& rect, int32_t sourceType)
3001 {
3002 std::vector<RectF> responseRegionList;
3003 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
3004 if (!gestureHub) {
3005 responseRegionList.emplace_back(rect);
3006 return responseRegionList;
3007 }
3008 auto scaleProperty = ScaleProperty::CreateScaleProperty(GetContext());
3009 bool isMouseEvent = (static_cast<SourceType>(sourceType) == SourceType::MOUSE);
3010 if (isMouseEvent) {
3011 if (gestureHub->GetResponseRegion().empty() && (gestureHub->GetMouseResponseRegion().empty())) {
3012 responseRegionList.emplace_back(rect);
3013 return responseRegionList;
3014 }
3015 } else {
3016 if (gestureHub->GetResponseRegion().empty()) {
3017 responseRegionList.emplace_back(rect);
3018 return responseRegionList;
3019 }
3020 }
3021
3022 if (isMouseEvent && (!gestureHub->GetMouseResponseRegion().empty())) {
3023 for (const auto& region : gestureHub->GetMouseResponseRegion()) {
3024 auto x = ConvertToPx(region.GetOffset().GetX(), scaleProperty, rect.Width());
3025 auto y = ConvertToPx(region.GetOffset().GetY(), scaleProperty, rect.Height());
3026 auto width = ConvertToPx(region.GetWidth(), scaleProperty, rect.Width());
3027 auto height = ConvertToPx(region.GetHeight(), scaleProperty, rect.Height());
3028 if (!x.has_value() || !y.has_value() || !width.has_value() || !height.has_value()) {
3029 continue;
3030 }
3031 RectF mouseRegion(rect.GetOffset().GetX() + x.value(), rect.GetOffset().GetY() + y.value(), width.value(),
3032 height.value());
3033 responseRegionList.emplace_back(mouseRegion);
3034 }
3035 return responseRegionList;
3036 }
3037 for (const auto& region : gestureHub->GetResponseRegion()) {
3038 auto x = ConvertToPx(region.GetOffset().GetX(), scaleProperty, rect.Width());
3039 auto y = ConvertToPx(region.GetOffset().GetY(), scaleProperty, rect.Height());
3040 auto width = ConvertToPx(region.GetWidth(), scaleProperty, rect.Width());
3041 auto height = ConvertToPx(region.GetHeight(), scaleProperty, rect.Height());
3042 if (!x.has_value() || !y.has_value() || !width.has_value() || !height.has_value()) {
3043 continue;
3044 }
3045 RectF responseRegion(
3046 rect.GetOffset().GetX() + x.value(), rect.GetOffset().GetY() + y.value(), width.value(), height.value());
3047 responseRegionList.emplace_back(responseRegion);
3048 }
3049 return responseRegionList;
3050 }
3051
GetResponseRegionListForRecognizer(int32_t sourceType)3052 std::vector<RectF> FrameNode::GetResponseRegionListForRecognizer(int32_t sourceType)
3053 {
3054 auto paintRect = renderContext_->GetPaintRectWithoutTransform();
3055 auto responseRegionList = GetResponseRegionList(paintRect, sourceType);
3056 return responseRegionList;
3057 }
3058
GetResponseRegionListForTouch(const RectF & rect)3059 std::vector<RectF> FrameNode::GetResponseRegionListForTouch(const RectF& rect)
3060 {
3061 ACE_LAYOUT_TRACE_BEGIN("GetResponseRegionListForTouch");
3062 std::vector<RectF> responseRegionList;
3063 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
3064 if (!gestureHub) {
3065 ACE_LAYOUT_TRACE_END()
3066 return responseRegionList;
3067 }
3068
3069 bool isAccessibilityClickable = gestureHub->IsAccessibilityClickable();
3070 if (!isAccessibilityClickable) {
3071 ACE_LAYOUT_TRACE_END()
3072 return responseRegionList;
3073 }
3074 auto offset = GetPositionToScreenWithTransform();
3075 if (gestureHub->GetResponseRegion().empty()) {
3076 RectF rectToScreen{round(offset.GetX()), round(offset.GetY()), round(rect.Width()), round(rect.Height())};
3077 responseRegionList.emplace_back(rectToScreen);
3078 ACE_LAYOUT_TRACE_END()
3079 return responseRegionList;
3080 }
3081
3082 auto scaleProperty = ScaleProperty::CreateScaleProperty();
3083 for (const auto& region : gestureHub->GetResponseRegion()) {
3084 auto x = ConvertToPx(region.GetOffset().GetX(), scaleProperty, rect.Width());
3085 auto y = ConvertToPx(region.GetOffset().GetY(), scaleProperty, rect.Height());
3086 auto width = ConvertToPx(region.GetWidth(), scaleProperty, rect.Width());
3087 auto height = ConvertToPx(region.GetHeight(), scaleProperty, rect.Height());
3088 if (!x.has_value() || !y.has_value() || !width.has_value() || !height.has_value()) {
3089 continue;
3090 }
3091 RectF responseRegion(round(offset.GetX() + x.value()), round(offset.GetY() + y.value()),
3092 round(width.value()), round(height.value()));
3093 responseRegionList.emplace_back(responseRegion);
3094 }
3095 ACE_LAYOUT_TRACE_END()
3096 return responseRegionList;
3097 }
3098
GetResponseRegionListByTraversal(std::vector<RectF> & responseRegionList)3099 void FrameNode::GetResponseRegionListByTraversal(std::vector<RectF>& responseRegionList)
3100 {
3101 CHECK_NULL_VOID(renderContext_);
3102 auto origRect = renderContext_->GetPaintRectWithoutTransform();
3103 auto pipelineContext = GetContext();
3104 CHECK_NULL_VOID(pipelineContext);
3105 auto offset = GetPositionToScreenWithTransform();
3106 RectF rectToScreen{offset.GetX(), offset.GetY(), origRect.Width(), origRect.Height()};
3107 auto window = pipelineContext->GetCurrentWindowRect();
3108 RectF windowRect{window.Left(), window.Top(), window.Width(), window.Height()};
3109
3110 if (rectToScreen.Left() >= windowRect.Right() || rectToScreen.Right() <= windowRect.Left() ||
3111 rectToScreen.Top() >= windowRect.Bottom() || rectToScreen.Bottom() <= windowRect.Top()) {
3112 return;
3113 }
3114
3115 auto rootRegionList = GetResponseRegionListForTouch(origRect);
3116 if (!rootRegionList.empty()) {
3117 for (auto rect : rootRegionList) {
3118 responseRegionList.push_back(rect.IntersectRectT(windowRect));
3119 }
3120 return;
3121 }
3122 for (auto childWeak = frameChildren_.rbegin(); childWeak != frameChildren_.rend(); ++childWeak) {
3123 const auto& child = childWeak->Upgrade();
3124 if (!child) {
3125 continue;
3126 }
3127 child->GetResponseRegionListByTraversal(responseRegionList);
3128 }
3129 }
3130
InResponseRegionList(const PointF & parentLocalPoint,const std::vector<RectF> & responseRegionList)3131 bool FrameNode::InResponseRegionList(const PointF& parentLocalPoint, const std::vector<RectF>& responseRegionList)
3132 {
3133 if (IsPaintRectWithTransformValid()) {
3134 return false;
3135 }
3136 for (const auto& rect : responseRegionList) {
3137 if (rect.IsInRegion(parentLocalPoint)) {
3138 return true;
3139 }
3140 }
3141 return false;
3142 }
3143
MouseTest(const PointF & globalPoint,const PointF & parentLocalPoint,MouseTestResult & onMouseResult,MouseTestResult & onHoverResult,RefPtr<FrameNode> & hoverNode)3144 HitTestResult FrameNode::MouseTest(const PointF& globalPoint, const PointF& parentLocalPoint,
3145 MouseTestResult& onMouseResult, MouseTestResult& onHoverResult, RefPtr<FrameNode>& hoverNode)
3146 {
3147 // unuseable function. do nothing.
3148 return HitTestResult::BUBBLING;
3149 }
3150
CheckChildHitTestReslut(HitTestResult childHitResult,const RefPtr<OHOS::Ace::NG::FrameNode> & child,bool & preventBubbling,bool & consumed,bool isExclusiveEventForChild)3151 bool CheckChildHitTestReslut(HitTestResult childHitResult, const RefPtr<OHOS::Ace::NG::FrameNode>& child,
3152 bool& preventBubbling, bool& consumed, bool isExclusiveEventForChild)
3153 {
3154 consumed = false;
3155 if (childHitResult == HitTestResult::STOP_BUBBLING) {
3156 preventBubbling = true;
3157 consumed = true;
3158 return ((child->GetHitTestMode() == HitTestMode::HTMBLOCK) ||
3159 (child->GetHitTestMode() == HitTestMode::HTMDEFAULT) ||
3160 (child->GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ||
3161 ((child->GetHitTestMode() != HitTestMode::HTMTRANSPARENT) && isExclusiveEventForChild));
3162 } else if (childHitResult == HitTestResult::BUBBLING) {
3163 consumed = true;
3164 return ((child->GetHitTestMode() == HitTestMode::HTMDEFAULT) ||
3165 (child->GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ||
3166 ((child->GetHitTestMode() != HitTestMode::HTMTRANSPARENT) && isExclusiveEventForChild));
3167 }
3168 return false;
3169 }
3170
3171
AxisTest(const PointF & globalPoint,const PointF & parentLocalPoint,const PointF & parentRevertPoint,TouchRestrict & touchRestrict,AxisTestResult & axisResult)3172 HitTestResult FrameNode::AxisTest(const PointF& globalPoint, const PointF& parentLocalPoint,
3173 const PointF& parentRevertPoint, TouchRestrict& touchRestrict, AxisTestResult& axisResult)
3174 {
3175 if (!isActive_ || (eventHub_ && !eventHub_->IsEnabled())) {
3176 TAG_LOGW(AceLogTag::ACE_UIEVENT, "%{public}s is inActive, need't do touch test", GetTag().c_str());
3177 return HitTestResult::OUT_OF_REGION;
3178 }
3179 {
3180 ACE_DEBUG_SCOPED_TRACE("FrameNode::IsOutOfTouchTestRegion");
3181 if (IsOutOfTouchTestRegion(parentRevertPoint, touchRestrict.touchEvent)) {
3182 return HitTestResult::OUT_OF_REGION;
3183 }
3184 }
3185 HitTestResult testResult = HitTestResult::OUT_OF_REGION;
3186 bool preventBubbling = false;
3187 AxisTestResult newComingTargets;
3188 auto localPoint = parentLocalPoint - renderContext_->GetPaintRectWithTransform().GetOffset();
3189 renderContext_->GetPointWithTransform(localPoint);
3190 auto revertPoint = parentRevertPoint;
3191 MapPointTo(revertPoint, GetOrRefreshMatrixFromCache().revertMatrix);
3192 auto subRevertPoint = revertPoint - renderContext_->GetPaintRectWithoutTransform().GetOffset();
3193 bool consumed = false;
3194 for (auto iter = frameChildren_.rbegin(); iter != frameChildren_.rend(); ++iter) {
3195 if (GetHitTestMode() == HitTestMode::HTMBLOCK) {
3196 break;
3197 }
3198 const auto& child = iter->Upgrade();
3199 if (!child) {
3200 continue;
3201 }
3202 auto childHitResult = child->AxisTest(globalPoint, localPoint, subRevertPoint, touchRestrict, newComingTargets);
3203 if (CheckChildHitTestReslut(childHitResult, child, preventBubbling, consumed, IsExclusiveEventForChild())) {
3204 break;
3205 }
3206 }
3207 CollectSelfAxisResult(
3208 globalPoint, localPoint, consumed, revertPoint, axisResult, preventBubbling, testResult, touchRestrict);
3209
3210 axisResult.splice(axisResult.begin(), std::move(newComingTargets));
3211 if (!consumed) {
3212 return testResult;
3213 }
3214 if (testResult == HitTestResult::OUT_OF_REGION && preventBubbling) {
3215 return HitTestResult::STOP_BUBBLING;
3216 } else {
3217 return (GetHitTestMode() == HitTestMode::HTMTRANSPARENT_SELF) ? HitTestResult::SELF_TRANSPARENT
3218 : HitTestResult::BUBBLING;
3219 }
3220 return testResult;
3221 }
3222
CollectSelfAxisResult(const PointF & globalPoint,const PointF & localPoint,bool & consumed,const PointF & parentRevertPoint,AxisTestResult & axisResult,bool & preventBubbling,HitTestResult & testResult,TouchRestrict & touchRestrict)3223 void FrameNode::CollectSelfAxisResult(const PointF& globalPoint, const PointF& localPoint, bool& consumed,
3224 const PointF& parentRevertPoint, AxisTestResult& axisResult, bool& preventBubbling, HitTestResult& testResult,
3225 TouchRestrict& touchRestrict)
3226 {
3227 if (consumed) {
3228 testResult = preventBubbling ? HitTestResult::STOP_BUBBLING : HitTestResult::BUBBLING;
3229 consumed = false;
3230 } else if (GetHitTestMode() == HitTestMode::HTMBLOCK) {
3231 testResult = HitTestResult::STOP_BUBBLING;
3232 }
3233 auto origRect = renderContext_->GetPaintRectWithoutTransform();
3234 auto resRegionList = GetResponseRegionList(origRect, static_cast<int32_t>(touchRestrict.touchEvent.sourceType));
3235 if (SystemProperties::GetDebugEnabled()) {
3236 TAG_LOGD(AceLogTag::ACE_UIEVENT, "AxisTest: point is %{public}s in %{public}s, depth: %{public}d",
3237 parentRevertPoint.ToString().c_str(), GetTag().c_str(), GetDepth());
3238 for (const auto& rect : resRegionList) {
3239 TAG_LOGD(AceLogTag::ACE_UIEVENT, "AxisTest: resRegionList is %{public}s, point is %{public}s",
3240 rect.ToString().c_str(), parentRevertPoint.ToString().c_str());
3241 }
3242 }
3243 if (preventBubbling) {
3244 return;
3245 }
3246 if (GetHitTestMode() == HitTestMode::HTMNONE) {
3247 return;
3248 }
3249 if (InResponseRegionList(parentRevertPoint, resRegionList)) {
3250 consumed = true;
3251 auto inputHub = eventHub_ ? eventHub_->GetInputEventHub() : nullptr;
3252 if (inputHub) {
3253 const auto coordinateOffset = globalPoint - localPoint;
3254 inputHub->ProcessAxisTestHit(coordinateOffset, axisResult);
3255 }
3256 }
3257 }
3258
AnimateHoverEffect(bool isHovered) const3259 void FrameNode::AnimateHoverEffect(bool isHovered) const
3260 {
3261 auto renderContext = GetRenderContext();
3262 if (!renderContext) {
3263 return;
3264 }
3265 HoverEffectType animationType = HoverEffectType::UNKNOWN;
3266 auto inputEventHub = eventHub_ ? eventHub_->GetInputEventHub() : nullptr;
3267 if (inputEventHub) {
3268 animationType = inputEventHub->GetHoverEffect();
3269 if (animationType == HoverEffectType::UNKNOWN || animationType == HoverEffectType::AUTO) {
3270 animationType = inputEventHub->GetHoverEffectAuto();
3271 }
3272 }
3273 if (animationType == HoverEffectType::SCALE) {
3274 renderContext->AnimateHoverEffectScale(isHovered);
3275 } else if (animationType == HoverEffectType::BOARD) {
3276 renderContext->AnimateHoverEffectBoard(isHovered);
3277 }
3278 }
3279
GetOrCreateFocusHub()3280 RefPtr<FocusHub> FrameNode::GetOrCreateFocusHub()
3281 {
3282 if (focusHub_) {
3283 return focusHub_;
3284 }
3285 if (!pattern_) {
3286 focusHub_ = MakeRefPtr<FocusHub>(WeakClaim(this));
3287 } else {
3288 auto focusPattern = pattern_->GetFocusPattern();
3289 focusHub_ = MakeRefPtr<FocusHub>(WeakClaim(this), focusPattern);
3290 }
3291 return focusHub_;
3292 }
3293
GetOrCreateFocusHub(FocusType type,bool focusable,FocusStyleType focusStyleType,const std::unique_ptr<FocusPaintParam> & paintParamsPtr)3294 const RefPtr<FocusHub>& FrameNode::GetOrCreateFocusHub(FocusType type, bool focusable, FocusStyleType focusStyleType,
3295 const std::unique_ptr<FocusPaintParam>& paintParamsPtr)
3296 {
3297 if (focusHub_) {
3298 return focusHub_;
3299 }
3300 focusHub_ = MakeRefPtr<FocusHub>(WeakClaim(this), type, focusable);
3301 focusHub_->SetFocusStyleType(focusStyleType);
3302 if (paintParamsPtr) {
3303 focusHub_->SetFocusPaintParamsPtr(paintParamsPtr);
3304 }
3305 return focusHub_;
3306 }
3307
GetOrCreateFocusHub(const FocusPattern & focusPattern)3308 const RefPtr<FocusHub>& FrameNode::GetOrCreateFocusHub(const FocusPattern& focusPattern)
3309 {
3310 if (focusHub_) {
3311 return focusHub_;
3312 }
3313 focusHub_ = MakeRefPtr<FocusHub>(WeakClaim(this), focusPattern);
3314 return focusHub_;
3315 }
3316
OnWindowShow()3317 void FrameNode::OnWindowShow()
3318 {
3319 pattern_->OnWindowShow();
3320 }
3321
OnWindowHide()3322 void FrameNode::OnWindowHide()
3323 {
3324 pattern_->OnWindowHide();
3325 }
3326
OnWindowFocused()3327 void FrameNode::OnWindowFocused()
3328 {
3329 if (renderContext_) {
3330 renderContext_->UpdateWindowFocusState(true);
3331 }
3332 pattern_->OnWindowFocused();
3333 }
3334
OnWindowUnfocused()3335 void FrameNode::OnWindowUnfocused()
3336 {
3337 if (renderContext_) {
3338 renderContext_->UpdateWindowFocusState(false);
3339 }
3340 pattern_->OnWindowUnfocused();
3341 }
3342
OnWindowActivated()3343 void FrameNode::OnWindowActivated()
3344 {
3345 if (renderContext_) {
3346 renderContext_->UpdateWindowActiveState(true);
3347 }
3348 pattern_->OnWindowActivated();
3349 }
3350
OnWindowDeactivated()3351 void FrameNode::OnWindowDeactivated()
3352 {
3353 if (renderContext_) {
3354 renderContext_->UpdateWindowActiveState(false);
3355 }
3356 pattern_->OnWindowDeactivated();
3357 }
3358
ContextPositionConvertToPX(const RefPtr<RenderContext> & context,const SizeF & percentReference)3359 std::pair<float, float> FrameNode::ContextPositionConvertToPX(
3360 const RefPtr<RenderContext>& context, const SizeF& percentReference)
3361 {
3362 std::pair<float, float> position;
3363 CHECK_NULL_RETURN(context, position);
3364 auto scaleProperty = ScaleProperty::CreateScaleProperty();
3365 position.first =
3366 ConvertToPx(context->GetPositionProperty()->GetPosition()->GetX(), scaleProperty, percentReference.Width())
3367 .value_or(0.0);
3368 position.second =
3369 ConvertToPx(context->GetPositionProperty()->GetPosition()->GetY(), scaleProperty, percentReference.Height())
3370 .value_or(0.0);
3371 return position;
3372 }
3373
OnPixelRoundFinish(const SizeF & pixelGridRoundSize)3374 void FrameNode::OnPixelRoundFinish(const SizeF& pixelGridRoundSize)
3375 {
3376 CHECK_NULL_VOID(pattern_);
3377 pattern_->OnPixelRoundFinish(pixelGridRoundSize);
3378 }
3379
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)3380 void FrameNode::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
3381 {
3382 pattern_->OnWindowSizeChanged(width, height, type);
3383 }
3384
3385 /* @deprecated This func will be deleted, please use GetTransformRelativeOffset() instead. */
3386 // a node collect ancestor node position upto root node, if a node has "position" property
3387 // then node will use position value but not paint rect result value
GetOffsetRelativeToWindow() const3388 OffsetF FrameNode::GetOffsetRelativeToWindow() const
3389 {
3390 auto offset = geometryNode_->GetFrameOffset();
3391 auto parent = GetAncestorNodeOfFrame(true);
3392 if (renderContext_ && renderContext_->GetPositionProperty()) {
3393 if (renderContext_->GetPositionProperty()->HasPosition()) {
3394 auto renderPosition =
3395 ContextPositionConvertToPX(renderContext_, layoutProperty_->GetLayoutConstraint()->percentReference);
3396 offset.SetX(static_cast<float>(renderPosition.first));
3397 offset.SetY(static_cast<float>(renderPosition.second));
3398 }
3399 }
3400 while (parent) {
3401 auto parentRenderContext = parent->GetRenderContext();
3402 if (parentRenderContext && parentRenderContext->GetPositionProperty()) {
3403 if (parentRenderContext->GetPositionProperty()->HasPosition()) {
3404 auto parentLayoutProperty = parent->GetLayoutProperty();
3405 CHECK_NULL_RETURN(parentLayoutProperty, offset);
3406 auto parentRenderContextPosition = ContextPositionConvertToPX(
3407 parentRenderContext, parentLayoutProperty->GetLayoutConstraint()->percentReference);
3408 offset.AddX(static_cast<float>(parentRenderContextPosition.first));
3409 offset.AddY(static_cast<float>(parentRenderContextPosition.second));
3410 parent = parent->GetAncestorNodeOfFrame(true);
3411 continue;
3412 }
3413 }
3414 if (parentRenderContext) {
3415 offset += parentRenderContext->GetPaintRectWithoutTransform().GetOffset();
3416 }
3417 parent = parent->GetAncestorNodeOfFrame(true);
3418 }
3419
3420 return offset;
3421 }
3422
3423 // returns a node's collected offset(see GetOffsetRelativeToWindow)
3424 // with offset of window to screen
3425 // ex. textInput component wrap offset relative to screen into a config and send to ime framework
GetPositionToScreen()3426 OffsetF FrameNode::GetPositionToScreen()
3427 {
3428 auto offsetCurrent = GetOffsetRelativeToWindow();
3429 auto pipelineContext = GetContext();
3430 CHECK_NULL_RETURN(pipelineContext, OffsetF());
3431 auto windowOffset = pipelineContext->GetCurrentWindowRect().GetOffset();
3432 auto windowManager = pipelineContext->GetWindowManager();
3433 auto container = Container::CurrentSafely();
3434 if (container && windowManager && windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3435 auto windowScale = container->GetWindowScale();
3436 offsetCurrent = offsetCurrent * windowScale;
3437 }
3438 OffsetF offset(windowOffset.GetX() + offsetCurrent.GetX(), windowOffset.GetY() + offsetCurrent.GetY());
3439 return offset;
3440 }
3441
3442 // returns a node's offset relative to parent and consider graphic transform rotate properties
GetPositionToParentWithTransform() const3443 OffsetF FrameNode::GetPositionToParentWithTransform() const
3444 {
3445 auto context = GetRenderContext();
3446 CHECK_NULL_RETURN(context, OffsetF());
3447 auto offset = context->GetPaintRectWithoutTransform().GetOffset();
3448 PointF pointTmp(offset.GetX(), offset.GetY());
3449 context->GetPointTransformRotate(pointTmp);
3450 offset.SetX(pointTmp.GetX());
3451 offset.SetY(pointTmp.GetY());
3452 return offset;
3453 }
3454
3455 // returns a node's offset collected offset(see GetPositionToWindowWithTransform)
3456 // then plus window's offset relative to screen
GetPositionToScreenWithTransform()3457 OffsetF FrameNode::GetPositionToScreenWithTransform()
3458 {
3459 auto pipelineContext = GetContext();
3460 CHECK_NULL_RETURN(pipelineContext, OffsetF());
3461 auto windowOffset = pipelineContext->GetCurrentWindowRect().GetOffset();
3462 OffsetF nodeOffset = GetPositionToWindowWithTransform();
3463 auto windowManager = pipelineContext->GetWindowManager();
3464 auto container = Container::CurrentSafely();
3465 if (container && windowManager && windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3466 auto windowScale = container->GetWindowScale();
3467 nodeOffset = nodeOffset * windowScale;
3468 }
3469 OffsetF offset(windowOffset.GetX() + nodeOffset.GetX(), windowOffset.GetY() + nodeOffset.GetY());
3470 return offset;
3471 }
3472
3473 // returns a node's offset relative to window
3474 // and consider every ancestor node's graphic transform rotate properties
3475 // ancestor will check boundary of window scene(exclude)
GetPositionToWindowWithTransform(bool fromBottom) const3476 OffsetF FrameNode::GetPositionToWindowWithTransform(bool fromBottom) const
3477 {
3478 auto context = GetRenderContext();
3479 CHECK_NULL_RETURN(context, OffsetF());
3480 auto rect = context->GetPaintRectWithoutTransform();
3481 OffsetF offset;
3482 if (!fromBottom) {
3483 offset = rect.GetOffset();
3484 } else {
3485 OffsetF offsetBottom(rect.GetX() + rect.Width(), rect.GetY() + rect.Height());
3486 offset = offsetBottom;
3487 }
3488
3489 PointF pointNode(offset.GetX(), offset.GetY());
3490 context->GetPointTransformRotate(pointNode);
3491 auto parent = GetAncestorNodeOfFrame(true);
3492 while (parent) {
3493 auto parentRenderContext = parent->GetRenderContext();
3494 offset = parentRenderContext->GetPaintRectWithoutTransform().GetOffset();
3495 PointF pointTmp(offset.GetX() + pointNode.GetX(), offset.GetY() + pointNode.GetY());
3496 parentRenderContext->GetPointTransformRotate(pointTmp);
3497 pointNode.SetX(pointTmp.GetX());
3498 pointNode.SetY(pointTmp.GetY());
3499 parent = parent->GetAncestorNodeOfFrame(true);
3500 }
3501 offset.SetX(pointNode.GetX());
3502 offset.SetY(pointNode.GetY());
3503 return offset;
3504 }
3505
GetTransformScaleRelativeToWindow() const3506 VectorF FrameNode::GetTransformScaleRelativeToWindow() const
3507 {
3508 VectorF finalScale {1.0f, 1.0f};
3509 auto context = GetRenderContext();
3510 if (context) {
3511 auto scale = GetTransformScale();
3512 finalScale.x = scale.x;
3513 finalScale.y = scale.y;
3514 }
3515
3516 auto parent = GetAncestorNodeOfFrame(true);
3517 while (parent) {
3518 auto contextParent = parent->GetRenderContext();
3519 if (contextParent) {
3520 auto scale = parent->GetTransformScale();
3521 finalScale.x *= scale.x;
3522 finalScale.y *= scale.y;
3523 }
3524 parent = parent->GetAncestorNodeOfFrame(true);
3525 }
3526 return finalScale;
3527 }
3528
3529 // returns a node's rect relative to window
3530 // and accumulate every ancestor node's graphic properties such as rotate and transform
3531 // detail graphic properites see RosenRenderContext::GetPaintRectWithTransform
3532 // ancestor will check boundary of window scene(exclude)
GetTransformRectRelativeToWindow(bool checkBoundary) const3533 RectF FrameNode::GetTransformRectRelativeToWindow(bool checkBoundary) const
3534 {
3535 auto context = GetRenderContext();
3536 CHECK_NULL_RETURN(context, RectF());
3537 RectF rect = context->GetPaintRectWithTransform();
3538 auto parent = GetAncestorNodeOfFrame(true);
3539 while (parent) {
3540 if (checkBoundary && parent->IsWindowBoundary()) {
3541 break;
3542 }
3543 rect = ApplyFrameNodeTranformToRect(rect, parent);
3544 parent = parent->GetAncestorNodeOfFrame(true);
3545 }
3546 return rect;
3547 }
3548
3549 // returns a node's offset relative to window
3550 // and accumulate every ancestor node's graphic properties such as rotate and transform
3551 // detail graphic properites see RosenRenderContext::GetPaintRectWithTransform
3552 // ancestor will check boundary of window scene(exclude)
GetTransformRelativeOffset() const3553 OffsetF FrameNode::GetTransformRelativeOffset() const
3554 {
3555 auto context = GetRenderContext();
3556 CHECK_NULL_RETURN(context, OffsetF());
3557 auto offset = context->GetPaintRectWithTransform().GetOffset();
3558 auto parent = GetAncestorNodeOfFrame(true);
3559
3560 while (parent) {
3561 auto parentRenderContext = parent->GetRenderContext();
3562 offset += parentRenderContext->GetPaintRectWithTransform().GetOffset();
3563 parent = parent->GetAncestorNodeOfFrame(true);
3564 }
3565
3566 return offset;
3567 }
3568
GetPaintRectOffset(bool excludeSelf,bool checkBoundary) const3569 OffsetF FrameNode::GetPaintRectOffset(bool excludeSelf, bool checkBoundary) const
3570 {
3571 auto context = GetRenderContext();
3572 CHECK_NULL_RETURN(context, OffsetF());
3573 OffsetF offset = excludeSelf ? OffsetF() : context->GetPaintRectWithTransform().GetOffset();
3574 auto parent = GetAncestorNodeOfFrame(checkBoundary);
3575 while (parent) {
3576 if (!checkBoundary && parent->CheckTopWindowBoundary()) {
3577 break;
3578 }
3579 auto renderContext = parent->GetRenderContext();
3580 CHECK_NULL_RETURN(renderContext, OffsetF());
3581 offset += renderContext->GetPaintRectWithTransform().GetOffset();
3582 parent = parent->GetAncestorNodeOfFrame(checkBoundary);
3583 }
3584 return offset;
3585 }
3586
GetPaintRectOffsetNG(bool excludeSelf,bool checkBoundary) const3587 OffsetF FrameNode::GetPaintRectOffsetNG(bool excludeSelf, bool checkBoundary) const
3588 {
3589 auto context = GetRenderContext();
3590 CHECK_NULL_RETURN(context, OffsetF());
3591 OffsetF offset = excludeSelf ? OffsetF() : context->GetPaintRectWithoutTransform().GetOffset();
3592 Point point = Matrix4::Invert(context->GetRevertMatrix()) * Point(offset.GetX(), offset.GetY());
3593 auto parent = GetAncestorNodeOfFrame(checkBoundary);
3594 while (parent) {
3595 if (!checkBoundary && parent->CheckTopWindowBoundary()) {
3596 break;
3597 }
3598 auto renderContext = parent->GetRenderContext();
3599 CHECK_NULL_RETURN(renderContext, OffsetF());
3600 auto parentOffset = renderContext->GetPaintRectWithoutTransform().GetOffset();
3601 point = point + Offset(parentOffset.GetX(), parentOffset.GetY());
3602 auto parentMatrix = Matrix4::Invert(renderContext->GetRevertMatrix());
3603 point = parentMatrix * point;
3604 parent = parent->GetAncestorNodeOfFrame(checkBoundary);
3605 }
3606 return OffsetF(point.GetX(), point.GetY());
3607 }
3608
GetRectPoints(SizeF & frameSize)3609 std::vector<Point> GetRectPoints(SizeF& frameSize)
3610 {
3611 std::vector<Point> pointList;
3612 pointList.push_back(Point(0, 0));
3613 pointList.push_back(Point(frameSize.Width(), 0));
3614 pointList.push_back(Point(0, frameSize.Height()));
3615 pointList.push_back(Point(frameSize.Width(), frameSize.Height()));
3616 return pointList;
3617 }
3618
GetBoundingBox(std::vector<Point> & pointList)3619 RectF GetBoundingBox(std::vector<Point>& pointList)
3620 {
3621 Point pMax = pointList[0];
3622 Point pMin = pointList[0];
3623
3624 for (auto &point: pointList) {
3625 if (point.GetX() > pMax.GetX()) {
3626 pMax.SetX(point.GetX());
3627 }
3628 if (point.GetX() < pMin.GetX()) {
3629 pMin.SetX(point.GetX());
3630 }
3631 if (point.GetY() > pMax.GetY()) {
3632 pMax.SetY(point.GetY());
3633 }
3634 if (point.GetY() < pMin.GetY()) {
3635 pMin.SetY(point.GetY());
3636 }
3637 }
3638 return RectF(pMin.GetX(), pMin.GetY(), pMax.GetX() - pMin.GetX(), pMax.GetY() - pMin.GetY());
3639 }
3640
3641 // returns node offset relate to parent and consider transform matrix of parent
GetRectPointToParentWithTransform(std::vector<Point> & pointList,const RefPtr<FrameNode> & parent) const3642 bool FrameNode::GetRectPointToParentWithTransform(std::vector<Point>& pointList, const RefPtr<FrameNode>& parent) const
3643 {
3644 auto renderContext = parent->GetRenderContext();
3645 CHECK_NULL_RETURN(renderContext, false);
3646 auto parentOffset = renderContext->GetPaintRectWithoutTransform().GetOffset();
3647 auto parentMatrix = Matrix4::Invert(renderContext->GetRevertMatrix());
3648 for (auto& point: pointList) {
3649 point = point + Offset(parentOffset.GetX(), parentOffset.GetY());
3650 point = parentMatrix * point;
3651 }
3652 return true;
3653 }
3654
3655 // returns node accumulated offset upto an ancestor has no renderContext or window
3656 // and consider each ancestor's transform matrix
GetPaintRectToWindowWithTransform()3657 RectF FrameNode::GetPaintRectToWindowWithTransform()
3658 {
3659 auto context = GetRenderContext();
3660 CHECK_NULL_RETURN(context, RectF());
3661 auto geometryNode = GetGeometryNode();
3662 CHECK_NULL_RETURN(geometryNode, RectF());
3663 auto frameSize = geometryNode->GetFrameSize();
3664 auto pointList = GetRectPoints(frameSize);
3665 GetRectPointToParentWithTransform(pointList, Claim(this));
3666 auto parent = GetAncestorNodeOfFrame(true);
3667 while (parent) {
3668 if (GetRectPointToParentWithTransform(pointList, parent)) {
3669 parent = parent->GetAncestorNodeOfFrame(true);
3670 } else {
3671 return RectF();
3672 }
3673 }
3674 return GetBoundingBox(pointList);
3675 }
3676
3677 // returns a node's geometry offset relative to window
3678 // used when a node is in the process of layout
3679 // because offset during layout is NOT synced to renderContext yet
GetParentGlobalOffsetDuringLayout() const3680 OffsetF FrameNode::GetParentGlobalOffsetDuringLayout() const
3681 {
3682 OffsetF offset {};
3683 auto parent = GetAncestorNodeOfFrame(true);
3684 while (parent) {
3685 offset += parent->geometryNode_->GetFrameOffset();
3686 parent = parent->GetAncestorNodeOfFrame(true);
3687 }
3688 return offset;
3689 }
3690
3691 // returns a node's offset relative to window
3692 // and accumulate every ancestor node's graphic translate properties
3693 // error means any ancestor node renderContext has hasScales_ bool
GetPaintRectGlobalOffsetWithTranslate(bool excludeSelf,bool checkBoundary) const3694 std::pair<OffsetF, bool> FrameNode::GetPaintRectGlobalOffsetWithTranslate(bool excludeSelf, bool checkBoundary) const
3695 {
3696 bool error = false;
3697 auto context = GetRenderContext();
3698 CHECK_NULL_RETURN(context, std::make_pair(OffsetF(), error));
3699 OffsetF offset = excludeSelf ? OffsetF() : context->GetPaintRectWithTranslate().first.GetOffset();
3700 auto parent = GetAncestorNodeOfFrame(checkBoundary);
3701 while (parent) {
3702 auto renderContext = parent->GetRenderContext();
3703 CHECK_NULL_RETURN(renderContext, std::make_pair(OffsetF(), error));
3704 auto [rect, err] = renderContext->GetPaintRectWithTranslate();
3705 error = error || err;
3706 CHECK_NULL_RETURN(rect.IsValid(), std::make_pair(offset + parent->GetPaintRectOffset(), error));
3707 offset += rect.GetOffset();
3708 parent = parent->GetAncestorNodeOfFrame(checkBoundary);
3709 }
3710 return std::make_pair(offset, error);
3711 }
3712
3713 // returns a node's offset relative to stage node
3714 // and accumulate every ancestor node's graphic properties such as rotate and transform
3715 // most of applications has stage offset of status bar height
GetPaintRectOffsetToStage() const3716 OffsetF FrameNode::GetPaintRectOffsetToStage() const
3717 {
3718 auto context = GetRenderContext();
3719 CHECK_NULL_RETURN(context, OffsetF());
3720 OffsetF offset = context->GetPaintRectWithTransform().GetOffset();
3721 auto parent = GetAncestorNodeOfFrame(true);
3722 while (parent && parent->GetTag() != V2::STAGE_ETS_TAG) {
3723 auto renderContext = parent->GetRenderContext();
3724 CHECK_NULL_RETURN(renderContext, OffsetF());
3725 // Eliminate the impact of default page transition
3726 if (parent->GetTag() == V2::PAGE_ETS_TAG) {
3727 offset += renderContext->GetPaintRectWithoutTransform().GetOffset();
3728 } else {
3729 offset += renderContext->GetPaintRectWithTransform().GetOffset();
3730 }
3731 parent = parent->GetAncestorNodeOfFrame(true);
3732 }
3733 return (parent && parent->GetTag() == V2::STAGE_ETS_TAG) ? offset : OffsetF();
3734 }
3735
GetViewPort(bool checkBoundary) const3736 std::optional<RectF> FrameNode::GetViewPort(bool checkBoundary) const
3737 {
3738 if (viewPort_.has_value()) {
3739 return viewPort_;
3740 }
3741 auto parent = GetAncestorNodeOfFrame(checkBoundary);
3742 while (parent && parent->GetTag() != V2::PAGE_ETS_TAG) {
3743 auto parentViewPort = parent->GetSelfViewPort();
3744 if (parentViewPort.has_value()) {
3745 return parentViewPort;
3746 }
3747 parent = parent->GetAncestorNodeOfFrame(checkBoundary);
3748 }
3749 return std::nullopt;
3750 }
3751
OnNotifyMemoryLevel(int32_t level)3752 void FrameNode::OnNotifyMemoryLevel(int32_t level)
3753 {
3754 pattern_->OnNotifyMemoryLevel(level);
3755 }
3756
GetAllDepthChildrenCount()3757 int32_t FrameNode::GetAllDepthChildrenCount()
3758 {
3759 int32_t result = 0;
3760 std::list<RefPtr<FrameNode>> children;
3761 children.emplace_back(Claim(this));
3762 while (!children.empty()) {
3763 auto& node = children.front();
3764 if (!node->IsInternal()) {
3765 result++;
3766 node->GenerateOneDepthVisibleFrame(children);
3767 }
3768 children.pop_front();
3769 }
3770 return result;
3771 }
3772
OnAccessibilityEvent(AccessibilityEventType eventType,WindowsContentChangeTypes windowsContentChangeType) const3773 void FrameNode::OnAccessibilityEvent(
3774 AccessibilityEventType eventType, WindowsContentChangeTypes windowsContentChangeType) const
3775 {
3776 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3777 AccessibilityEvent event;
3778 event.type = eventType;
3779 event.windowContentChangeTypes = windowsContentChangeType;
3780 event.nodeId = GetAccessibilityId();
3781 auto pipeline = GetContext();
3782 CHECK_NULL_VOID(pipeline);
3783 pipeline->SendEventToAccessibility(event);
3784 }
3785 }
3786
OnAccessibilityEventForVirtualNode(AccessibilityEventType eventType,int64_t accessibilityId)3787 void FrameNode::OnAccessibilityEventForVirtualNode(AccessibilityEventType eventType, int64_t accessibilityId)
3788 {
3789 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3790 AccessibilityEvent event;
3791 event.type = eventType;
3792 event.windowContentChangeTypes = WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_INVALID;
3793 event.nodeId = accessibilityId;
3794 auto pipeline = GetContext();
3795 CHECK_NULL_VOID(pipeline);
3796 pipeline->SendEventToAccessibility(event);
3797 }
3798 }
3799
OnAccessibilityEvent(AccessibilityEventType eventType,int32_t startIndex,int32_t endIndex)3800 void FrameNode::OnAccessibilityEvent(
3801 AccessibilityEventType eventType, int32_t startIndex, int32_t endIndex)
3802 {
3803 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3804 AccessibilityEvent event;
3805 event.type = eventType;
3806 event.nodeId = GetAccessibilityId();
3807 event.startIndex = startIndex;
3808 event.endIndex = endIndex;
3809 auto pipeline = GetContext();
3810 CHECK_NULL_VOID(pipeline);
3811 pipeline->SendEventToAccessibilityWithNode(event, Claim(this));
3812 }
3813 }
3814
OnAccessibilityEvent(AccessibilityEventType eventType,std::string beforeText,std::string latestContent)3815 void FrameNode::OnAccessibilityEvent(
3816 AccessibilityEventType eventType, std::string beforeText, std::string latestContent)
3817 {
3818 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3819 AccessibilityEvent event;
3820 event.type = eventType;
3821 event.nodeId = GetAccessibilityId();
3822 event.beforeText = beforeText;
3823 event.latestContent = latestContent;
3824 auto pipeline = GetContext();
3825 CHECK_NULL_VOID(pipeline);
3826 pipeline->SendEventToAccessibilityWithNode(event, Claim(this));
3827 }
3828 }
3829
OnAccessibilityEvent(AccessibilityEventType eventType,int64_t stackNodeId,WindowsContentChangeTypes windowsContentChangeType)3830 void FrameNode::OnAccessibilityEvent(
3831 AccessibilityEventType eventType, int64_t stackNodeId, WindowsContentChangeTypes windowsContentChangeType)
3832 {
3833 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3834 AccessibilityEvent event;
3835 event.type = eventType;
3836 event.windowContentChangeTypes = windowsContentChangeType;
3837 event.nodeId = GetAccessibilityId();
3838 event.stackNodeId = stackNodeId;
3839 auto pipeline = GetContext();
3840 CHECK_NULL_VOID(pipeline);
3841 pipeline->SendEventToAccessibility(event);
3842 }
3843 }
3844
OnAccessibilityEvent(AccessibilityEventType eventType,std::string textAnnouncedForAccessibility)3845 void FrameNode::OnAccessibilityEvent(
3846 AccessibilityEventType eventType, std::string textAnnouncedForAccessibility)
3847 {
3848 if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
3849 if (eventType != AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY) {
3850 return;
3851 }
3852 AccessibilityEvent event;
3853 event.type = eventType;
3854 event.nodeId = GetAccessibilityId();
3855 event.textAnnouncedForAccessibility = textAnnouncedForAccessibility;
3856 auto pipeline = GetContext();
3857 CHECK_NULL_VOID(pipeline);
3858 pipeline->SendEventToAccessibilityWithNode(event, Claim(this));
3859 }
3860 }
3861
OnRecycle()3862 void FrameNode::OnRecycle()
3863 {
3864 for (const auto& destroyCallback : destroyCallbacksMap_) {
3865 if (destroyCallback.second) {
3866 destroyCallback.second();
3867 }
3868 }
3869 layoutProperty_->ResetGeometryTransition();
3870 pattern_->OnRecycle();
3871 UINode::OnRecycle();
3872 }
3873
OnReuse()3874 void FrameNode::OnReuse()
3875 {
3876 pattern_->OnReuse();
3877 UINode::OnReuse();
3878 if (SystemProperties::GetDeveloperModeOn()) {
3879 PaintDebugBoundary(SystemProperties::GetDebugBoundaryEnabled());
3880 }
3881 }
3882
MarkRemoving()3883 bool FrameNode::MarkRemoving()
3884 {
3885 bool pendingRemove = false;
3886 if (!layoutProperty_ || !geometryNode_) {
3887 return pendingRemove;
3888 }
3889
3890 isRemoving_ = true;
3891
3892 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
3893 if (geometryTransition != nullptr) {
3894 geometryTransition->Build(WeakClaim(this), false);
3895 pendingRemove = true;
3896 }
3897
3898 const auto children = GetChildren();
3899 for (const auto& child : children) {
3900 pendingRemove = child->MarkRemoving() || pendingRemove;
3901 }
3902 return pendingRemove;
3903 }
3904
AddHotZoneRect(const DimensionRect & hotZoneRect)3905 void FrameNode::AddHotZoneRect(const DimensionRect& hotZoneRect)
3906 {
3907 auto gestureHub = GetOrCreateGestureEventHub();
3908 gestureHub->AddResponseRect(hotZoneRect);
3909 }
3910
RemoveLastHotZoneRect() const3911 void FrameNode::RemoveLastHotZoneRect() const
3912 {
3913 auto gestureHub = eventHub_ ? eventHub_->GetOrCreateGestureEventHub() : nullptr;
3914 gestureHub->RemoveLastResponseRect();
3915 }
3916
OnRemoveFromParent(bool allowTransition)3917 bool FrameNode::OnRemoveFromParent(bool allowTransition)
3918 {
3919 // the node set isInDestroying state when destroying in pop animation
3920 // when in isInDestroying state node should not DetachFromMainTree preventing pop page from being white
3921 if (IsDestroyingState()) {
3922 return false;
3923 }
3924 // kick out transition animation if needed, wont re-entry if already detached.
3925 DetachFromMainTree(!allowTransition);
3926 auto context = GetRenderContext();
3927 CHECK_NULL_RETURN(context, false);
3928 if (!allowTransition || RemoveImmediately()) {
3929 // directly remove, reset parent and depth
3930 ResetParent();
3931 return true;
3932 }
3933 // delayed remove, will move self into disappearing children
3934 return false;
3935 }
3936
FindChildByPosition(float x,float y)3937 RefPtr<FrameNode> FrameNode::FindChildByPosition(float x, float y)
3938 {
3939 std::map<int32_t, RefPtr<FrameNode>> hitFrameNodes;
3940 std::list<RefPtr<FrameNode>> children;
3941 GenerateOneDepthAllFrame(children);
3942 for (const auto& child : children) {
3943 if (!child->IsActive()) {
3944 continue;
3945 }
3946 auto geometryNode = child->GetGeometryNode();
3947 if (!geometryNode) {
3948 continue;
3949 }
3950
3951 auto globalFrameRect = geometryNode->GetFrameRect();
3952 globalFrameRect.SetOffset(child->GetOffsetRelativeToWindow());
3953
3954 if (globalFrameRect.IsInRegion(PointF(x, y))) {
3955 hitFrameNodes.insert(std::make_pair(child->GetDepth(), child));
3956 }
3957 }
3958
3959 if (hitFrameNodes.empty()) {
3960 return nullptr;
3961 }
3962
3963 return hitFrameNodes.rbegin()->second;
3964 }
3965
FindChildByPositionWithoutChildTransform(float x,float y)3966 RefPtr<FrameNode> FrameNode::FindChildByPositionWithoutChildTransform(float x, float y)
3967 {
3968 std::map<int32_t, RefPtr<FrameNode>> hitFrameNodes;
3969 std::list<RefPtr<FrameNode>> children;
3970 GenerateOneDepthAllFrame(children);
3971 auto parentOffset = GetPositionToWindowWithTransform();
3972 for (const auto& child : children) {
3973 if (!child->IsActive()) {
3974 continue;
3975 }
3976 auto geometryNode = child->GetGeometryNode();
3977 if (!geometryNode) {
3978 continue;
3979 }
3980
3981 auto globalFrameRect = geometryNode->GetFrameRect();
3982 auto childOffset = geometryNode->GetFrameOffset();
3983 childOffset += parentOffset;
3984 globalFrameRect.SetOffset(childOffset);
3985
3986 if (globalFrameRect.IsInRegion(PointF(x, y))) {
3987 hitFrameNodes.insert(std::make_pair(child->GetDepth(), child));
3988 }
3989 }
3990
3991 if (hitFrameNodes.empty()) {
3992 return nullptr;
3993 }
3994
3995 return hitFrameNodes.rbegin()->second;
3996 }
3997
GetAnimatablePropertyFloat(const std::string & propertyName) const3998 RefPtr<NodeAnimatablePropertyBase> FrameNode::GetAnimatablePropertyFloat(const std::string& propertyName) const
3999 {
4000 auto iter = nodeAnimatablePropertyMap_.find(propertyName);
4001 if (iter == nodeAnimatablePropertyMap_.end()) {
4002 return nullptr;
4003 }
4004 return iter->second;
4005 }
4006
FindChildByName(const RefPtr<FrameNode> & parentNode,const std::string & nodeName)4007 RefPtr<FrameNode> FrameNode::FindChildByName(const RefPtr<FrameNode>& parentNode, const std::string& nodeName)
4008 {
4009 CHECK_NULL_RETURN(parentNode, nullptr);
4010 const auto& children = parentNode->GetChildren();
4011 for (const auto& child : children) {
4012 auto childFrameNode = AceType::DynamicCast<FrameNode>(child);
4013 if (childFrameNode && childFrameNode->GetInspectorId().value_or("") == nodeName) {
4014 return childFrameNode;
4015 }
4016 auto childFindResult = FindChildByName(childFrameNode, nodeName);
4017 if (childFindResult) {
4018 return childFindResult;
4019 }
4020 }
4021 return nullptr;
4022 }
4023
CreateAnimatablePropertyFloat(const std::string & propertyName,float value,const std::function<void (float)> & onCallbackEvent,const PropertyUnit & propertyType)4024 void FrameNode::CreateAnimatablePropertyFloat(const std::string& propertyName, float value,
4025 const std::function<void(float)>& onCallbackEvent, const PropertyUnit& propertyType)
4026 {
4027 auto context = GetRenderContext();
4028 CHECK_NULL_VOID(context);
4029 auto iter = nodeAnimatablePropertyMap_.find(propertyName);
4030 if (iter != nodeAnimatablePropertyMap_.end()) {
4031 return;
4032 }
4033 auto property = AceType::MakeRefPtr<NodeAnimatablePropertyFloat>(value, std::move(onCallbackEvent));
4034 context->AttachNodeAnimatableProperty(property);
4035 if (propertyType == PropertyUnit::PIXEL_POSITION) {
4036 property->SetPropertyUnit(propertyType);
4037 }
4038 nodeAnimatablePropertyMap_.emplace(propertyName, property);
4039 }
4040
DeleteAnimatablePropertyFloat(const std::string & propertyName)4041 void FrameNode::DeleteAnimatablePropertyFloat(const std::string& propertyName)
4042 {
4043 auto context = GetRenderContext();
4044 CHECK_NULL_VOID(context);
4045 RefPtr<NodeAnimatablePropertyBase> propertyRef = GetAnimatablePropertyFloat(propertyName);
4046 if (propertyRef) {
4047 context->DetachNodeAnimatableProperty(propertyRef);
4048 nodeAnimatablePropertyMap_.erase(propertyName);
4049 }
4050 }
4051
UpdateAnimatablePropertyFloat(const std::string & propertyName,float value)4052 void FrameNode::UpdateAnimatablePropertyFloat(const std::string& propertyName, float value)
4053 {
4054 auto iter = nodeAnimatablePropertyMap_.find(propertyName);
4055 if (iter == nodeAnimatablePropertyMap_.end()) {
4056 return;
4057 }
4058 auto property = AceType::DynamicCast<NodeAnimatablePropertyFloat>(iter->second);
4059 CHECK_NULL_VOID(property);
4060 property->Set(value);
4061 if (AnimationUtils::IsImplicitAnimationOpen()) {
4062 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_START_ANIMATION);
4063 }
4064 }
4065
CreateAnimatableArithmeticProperty(const std::string & propertyName,RefPtr<CustomAnimatableArithmetic> & value,std::function<void (const RefPtr<CustomAnimatableArithmetic> &)> & onCallbackEvent)4066 void FrameNode::CreateAnimatableArithmeticProperty(const std::string& propertyName,
4067 RefPtr<CustomAnimatableArithmetic>& value,
4068 std::function<void(const RefPtr<CustomAnimatableArithmetic>&)>& onCallbackEvent)
4069 {
4070 auto context = GetRenderContext();
4071 CHECK_NULL_VOID(context);
4072 auto iter = nodeAnimatablePropertyMap_.find(propertyName);
4073 if (iter != nodeAnimatablePropertyMap_.end()) {
4074 return;
4075 }
4076 auto property = AceType::MakeRefPtr<NodeAnimatableArithmeticProperty>(value, std::move(onCallbackEvent));
4077 context->AttachNodeAnimatableProperty(property);
4078 nodeAnimatablePropertyMap_.emplace(propertyName, property);
4079 }
4080
UpdateAnimatableArithmeticProperty(const std::string & propertyName,RefPtr<CustomAnimatableArithmetic> & value)4081 void FrameNode::UpdateAnimatableArithmeticProperty(
4082 const std::string& propertyName, RefPtr<CustomAnimatableArithmetic>& value)
4083 {
4084 auto iter = nodeAnimatablePropertyMap_.find(propertyName);
4085 if (iter == nodeAnimatablePropertyMap_.end()) {
4086 return;
4087 }
4088 auto property = AceType::DynamicCast<NodeAnimatableArithmeticProperty>(iter->second);
4089 CHECK_NULL_VOID(property);
4090 property->Set(value);
4091 }
4092
ProvideRestoreInfo()4093 std::string FrameNode::ProvideRestoreInfo()
4094 {
4095 return pattern_->ProvideRestoreInfo();
4096 }
4097
RemoveImmediately() const4098 bool FrameNode::RemoveImmediately() const
4099 {
4100 auto context = GetRenderContext();
4101 CHECK_NULL_RETURN(context, true);
4102 // has transition out animation, need to wait for animation end
4103 return !context->HasTransitionOutAnimation();
4104 }
4105
GetNodesById(const std::unordered_set<int32_t> & set)4106 std::vector<RefPtr<FrameNode>> FrameNode::GetNodesById(const std::unordered_set<int32_t>& set)
4107 {
4108 std::vector<RefPtr<FrameNode>> nodes;
4109 for (auto nodeId : set) {
4110 auto uiNode = ElementRegister::GetInstance()->GetUINodeById(nodeId);
4111 if (!uiNode) {
4112 continue;
4113 }
4114 auto frameNode = DynamicCast<FrameNode>(uiNode);
4115 if (frameNode) {
4116 nodes.emplace_back(frameNode);
4117 }
4118 }
4119 return nodes;
4120 }
4121
GetNodesPtrById(const std::unordered_set<int32_t> & set)4122 std::vector<FrameNode*> FrameNode::GetNodesPtrById(const std::unordered_set<int32_t>& set)
4123 {
4124 std::vector<FrameNode*> nodes;
4125 for (auto nodeId : set) {
4126 NG::FrameNode* frameNode = ElementRegister::GetInstance()->GetFrameNodePtrById(nodeId);
4127 if (!frameNode) {
4128 continue;
4129 }
4130 nodes.emplace_back(frameNode);
4131 }
4132 return nodes;
4133 }
4134
GetPreviewScaleVal() const4135 double FrameNode::GetPreviewScaleVal() const
4136 {
4137 double scale = 1.0;
4138 auto maxWidth = DragDropManager::GetMaxWidthBaseOnGridSystem(GetContextRefPtr());
4139 auto geometryNode = GetGeometryNode();
4140 CHECK_NULL_RETURN(geometryNode, scale);
4141 auto width = geometryNode->GetFrameRect().Width();
4142 if (GetTag() != V2::WEB_ETS_TAG && width != 0 && width > maxWidth && previewOption_.isScaleEnabled) {
4143 scale = maxWidth / width;
4144 }
4145 return scale;
4146 }
4147
IsPreviewNeedScale() const4148 bool FrameNode::IsPreviewNeedScale() const
4149 {
4150 return GetPreviewScaleVal() < 1.0f;
4151 }
4152
GetNodeExpectedRate()4153 int32_t FrameNode::GetNodeExpectedRate()
4154 {
4155 if (sceneRateMap_.empty()) {
4156 return 0;
4157 }
4158 auto iter = std::max_element(
4159 sceneRateMap_.begin(), sceneRateMap_.end(), [](auto a, auto b) { return a.second < b.second; });
4160 return iter->second;
4161 }
4162
TryPrintDebugLog(const std::string & scene,float speed,SceneStatus status)4163 void FrameNode::TryPrintDebugLog(const std::string& scene, float speed, SceneStatus status)
4164 {
4165 if (SystemProperties::GetDebugEnabled()) {
4166 const std::string sceneStatusStrs[] = { "START", "RUNNING", "END" };
4167 LOGD("%{public}s AddFRCSceneInfo scene:%{public}s speed:%{public}f status:%{public}s", GetTag().c_str(),
4168 scene.c_str(), std::abs(speed), sceneStatusStrs[static_cast<int32_t>(status)].c_str());
4169 }
4170 }
4171
AddFRCSceneInfo(const std::string & scene,float speed,SceneStatus status)4172 void FrameNode::AddFRCSceneInfo(const std::string& scene, float speed, SceneStatus status)
4173 {
4174 TryPrintDebugLog(scene, speed, status);
4175
4176 auto renderContext = GetRenderContext();
4177 CHECK_NULL_VOID(renderContext);
4178 auto pipelineContext = GetContext();
4179 CHECK_NULL_VOID(pipelineContext);
4180 auto frameRateManager = pipelineContext->GetFrameRateManager();
4181 CHECK_NULL_VOID(frameRateManager);
4182
4183 auto expectedRate = renderContext->CalcExpectedFrameRate(scene, std::abs(speed));
4184 auto nodeId = GetId();
4185 auto iter = sceneRateMap_.find(scene);
4186 EventReport::FrameRateDurationsStatistics(expectedRate, scene, status);
4187
4188 switch (status) {
4189 case SceneStatus::START: {
4190 if (iter == sceneRateMap_.end()) {
4191 if (sceneRateMap_.empty()) {
4192 frameRateManager->AddNodeRate(nodeId);
4193 }
4194 sceneRateMap_.emplace(scene, expectedRate);
4195 frameRateManager->UpdateNodeRate(nodeId, GetNodeExpectedRate());
4196 }
4197 return;
4198 }
4199 case SceneStatus::RUNNING: {
4200 if (iter != sceneRateMap_.end() && iter->second != expectedRate) {
4201 iter->second = expectedRate;
4202 auto nodeExpectedRate = GetNodeExpectedRate();
4203 frameRateManager->UpdateNodeRate(nodeId, nodeExpectedRate);
4204 }
4205 return;
4206 }
4207 case SceneStatus::END: {
4208 if (iter != sceneRateMap_.end()) {
4209 sceneRateMap_.erase(iter);
4210 if (sceneRateMap_.empty()) {
4211 frameRateManager->RemoveNodeRate(nodeId);
4212 } else {
4213 auto nodeExpectedRate = GetNodeExpectedRate();
4214 frameRateManager->UpdateNodeRate(nodeId, nodeExpectedRate);
4215 }
4216 }
4217 return;
4218 }
4219 default:
4220 return;
4221 }
4222 }
4223
GetPercentSensitive()4224 void FrameNode::GetPercentSensitive()
4225 {
4226 auto res = layoutProperty_->GetPercentSensitive();
4227 if (res.first) {
4228 if (layoutAlgorithm_) {
4229 layoutAlgorithm_->SetPercentWidth(true);
4230 }
4231 }
4232 if (res.second) {
4233 if (layoutAlgorithm_) {
4234 layoutAlgorithm_->SetPercentHeight(true);
4235 }
4236 }
4237 }
4238
UpdatePercentSensitive()4239 void FrameNode::UpdatePercentSensitive()
4240 {
4241 bool percentHeight = layoutAlgorithm_ ? layoutAlgorithm_->GetPercentHeight() : true;
4242 bool percentWidth = layoutAlgorithm_ ? layoutAlgorithm_->GetPercentWidth() : true;
4243 auto res = layoutProperty_->UpdatePercentSensitive(percentWidth, percentHeight);
4244 if (res.first) {
4245 auto parent = GetAncestorNodeOfFrame(true);
4246 if (parent && parent->layoutAlgorithm_) {
4247 parent->layoutAlgorithm_->SetPercentWidth(true);
4248 }
4249 }
4250 if (res.second) {
4251 auto parent = GetAncestorNodeOfFrame(true);
4252 if (parent && parent->layoutAlgorithm_) {
4253 parent->layoutAlgorithm_->SetPercentHeight(true);
4254 }
4255 }
4256 }
4257
4258 // This will call child and self measure process.
Measure(const std::optional<LayoutConstraintF> & parentConstraint)4259 void FrameNode::Measure(const std::optional<LayoutConstraintF>& parentConstraint)
4260 {
4261 ACE_LAYOUT_TRACE_BEGIN("Measure[%s][self:%d][parent:%d][key:%s]", GetTag().c_str(), GetId(),
4262 GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0, GetInspectorIdValue("").c_str());
4263 if (SystemProperties::GetMeasureDebugTraceEnabled()) {
4264 ACE_MEASURE_SCOPED_TRACE(
4265 "Measure[%s][self:%d][parent:%d][key:%s][frameRect:%s][parentConstraint:%s][calcConstraint:%s]",
4266 GetTag().c_str(), GetId(), GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0,
4267 GetInspectorIdValue("").c_str(), GetGeometryNode()->GetFrameRect().ToString().c_str(),
4268 parentConstraint.has_value() ? parentConstraint.value().ToString().c_str() : "NA",
4269 layoutProperty_->GetCalcLayoutConstraint() ? layoutProperty_->GetCalcLayoutConstraint()->ToString().c_str()
4270 : "NA");
4271 }
4272 ArkUIPerfMonitor::GetInstance().RecordLayoutNode();
4273 isLayoutComplete_ = false;
4274 if (!oldGeometryNode_) {
4275 oldGeometryNode_ = geometryNode_->Clone();
4276 }
4277 pattern_->BeforeCreateLayoutWrapper();
4278 GetLayoutAlgorithm(true);
4279
4280 if (layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE) == VisibleType::GONE) {
4281 layoutAlgorithm_->SetSkipMeasure();
4282 layoutAlgorithm_->SetSkipLayout();
4283 geometryNode_->SetFrameSize(SizeF());
4284 geometryNode_->UpdateMargin(MarginPropertyF());
4285 isLayoutDirtyMarked_ = false;
4286 ACE_SCOPED_TRACE("SkipMeasure [%s][self:%d] reason: VisibleType::GONE", GetTag().c_str(), GetId());
4287 ACE_LAYOUT_TRACE_END()
4288 return;
4289 }
4290 if (!isActive_) {
4291 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
4292 }
4293
4294 if (layoutAlgorithm_->SkipMeasure()) {
4295 isLayoutDirtyMarked_ = false;
4296 ACE_LAYOUT_TRACE_END()
4297 ACE_SCOPED_TRACE("SkipMeasure [%s][self:%d] reason: SkipMeasure", GetTag().c_str(), GetId());
4298 return;
4299 }
4300
4301 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
4302 if (geometryTransition != nullptr && geometryTransition->IsRunning(WeakClaim(this))) {
4303 geometryTransition->WillLayout(Claim(this));
4304 }
4305 auto preConstraint = layoutProperty_->GetLayoutConstraint();
4306 auto contentConstraint = layoutProperty_->GetContentLayoutConstraint();
4307 layoutProperty_->BuildGridProperty(Claim(this));
4308
4309 if (layoutProperty_->GetLayoutRect()) {
4310 layoutProperty_->UpdateLayoutConstraintWithLayoutRect();
4311 } else if (parentConstraint) {
4312 ApplyConstraint(*parentConstraint);
4313 } else {
4314 CreateRootConstraint();
4315 }
4316
4317 layoutProperty_->UpdateContentConstraint();
4318 geometryNode_->UpdateMargin(layoutProperty_->CreateMargin());
4319 geometryNode_->UpdatePaddingWithBorder(layoutProperty_->CreatePaddingAndBorder());
4320
4321 isConstraintNotChanged_ = layoutProperty_->ConstraintEqual(preConstraint, contentConstraint);
4322
4323 isLayoutDirtyMarked_ = false;
4324
4325 if (isConstraintNotChanged_) {
4326 if (!CheckNeedForceMeasureAndLayout()) {
4327 ACE_SCOPED_TRACE(
4328 "SkipMeasure [%s][self:%d] reason:ConstraintNotChanged and no force-flag", GetTag().c_str(), GetId());
4329 layoutAlgorithm_->SetSkipMeasure();
4330 ACE_LAYOUT_TRACE_END()
4331 return;
4332 }
4333 } else {
4334 contentConstraintChanges_.UpdateFlags(contentConstraint, layoutProperty_->GetContentLayoutConstraint());
4335 constraintChanges_.UpdateFlags(preConstraint, layoutProperty_->GetLayoutConstraint());
4336 }
4337
4338 GetPercentSensitive();
4339
4340 if (extensionHandler_ && !extensionHandler_->HasDrawModifier()) {
4341 auto extensionLayoutConstraint =
4342 ExtensionLayoutConstraint::Create(GetLayoutProperty()->GetLayoutConstraint().value());
4343 extensionHandler_->SetInnerMeasureImpl([this](const ExtensionLayoutConstraint&) {
4344 auto size = layoutAlgorithm_->MeasureContent(layoutProperty_->CreateContentConstraint(), this);
4345 if (size.has_value()) {
4346 geometryNode_->SetContentSize(size.value());
4347 }
4348 layoutAlgorithm_->Measure(this);
4349 });
4350 extensionHandler_->Measure(extensionLayoutConstraint);
4351 } else {
4352 auto size = layoutAlgorithm_->MeasureContent(layoutProperty_->CreateContentConstraint(), this);
4353 if (size.has_value()) {
4354 geometryNode_->SetContentSize(size.value());
4355 }
4356 layoutAlgorithm_->Measure(this);
4357 }
4358
4359 if (overlayNode_) {
4360 overlayNode_->Measure(layoutProperty_->CreateChildConstraint());
4361 }
4362 UpdatePercentSensitive();
4363 // check aspect radio.
4364 if (pattern_ && pattern_->IsNeedAdjustByAspectRatio() && !layoutProperty_->GetLayoutRect()) {
4365 const auto& magicItemProperty = layoutProperty_->GetMagicItemProperty();
4366 auto aspectRatio = magicItemProperty.GetAspectRatioValue();
4367 // Adjust by aspect ratio, firstly pick height based on width. It means that when width, height and
4368 // aspectRatio are all set, the height is not used.
4369 auto width = geometryNode_->GetFrameSize().Width();
4370 auto height = width / aspectRatio;
4371 geometryNode_->SetFrameSize(SizeF({ width, height }));
4372 }
4373 auto pipeline = GetContext();
4374 if (pipeline && pipeline->GetPixelRoundMode() == PixelRoundMode::PIXEL_ROUND_AFTER_MEASURE) {
4375 auto size = geometryNode_->GetFrameSize();
4376 geometryNode_->SetFrameSize(SizeF({ round(size.Width()), round(size.Height()) }));
4377 }
4378
4379 layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_LAYOUT);
4380 if (SystemProperties::GetMeasureDebugTraceEnabled()) {
4381 ACE_MEASURE_SCOPED_TRACE("MeasureFinish[%s][self:%d][parent:%d][key:%s][frameRect:%s][contentSize:%s]",
4382 GetTag().c_str(), GetId(), GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0,
4383 GetInspectorIdValue("").c_str(), GetGeometryNode()->GetFrameRect().ToString().c_str(),
4384 GetGeometryNode()->GetContentSize().ToString().c_str());
4385 }
4386 ACE_LAYOUT_TRACE_END()
4387 }
4388
4389 // Called to perform layout children.
Layout()4390 void FrameNode::Layout()
4391 {
4392 ACE_LAYOUT_TRACE_BEGIN("Layout[%s][self:%d][parent:%d][key:%s]", GetTag().c_str(), GetId(),
4393 GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0, GetInspectorIdValue("").c_str());
4394 if (SystemProperties::GetMeasureDebugTraceEnabled()) {
4395 ACE_MEASURE_SCOPED_TRACE("Layout[%s][self:%d][parent:%d][key:%s][frameRect:%s]", GetTag().c_str(), GetId(),
4396 GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0, GetInspectorIdValue("").c_str(),
4397 GetGeometryNode()->GetFrameRect().ToString().c_str());
4398 }
4399 if (layoutProperty_->GetLayoutRect()) {
4400 GetGeometryNode()->SetFrameOffset(layoutProperty_->GetLayoutRect().value().GetOffset());
4401 }
4402 int64_t time = GetSysTimestamp();
4403 OffsetNodeToSafeArea();
4404 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
4405 if (geometryTransition != nullptr) {
4406 if (geometryTransition->IsNodeInAndActive(Claim(this))) {
4407 if (IsRootMeasureNode()) {
4408 UINode::SetGeometryTransitionInRecursive(true);
4409 } else {
4410 SetSkipSyncGeometryNode();
4411 }
4412 }
4413 }
4414 if (CheckNeedLayout(layoutProperty_->GetPropertyChangeFlag())) {
4415 if (!layoutProperty_->GetLayoutConstraint()) {
4416 const auto& parentLayoutConstraint = geometryNode_->GetParentLayoutConstraint();
4417 if (layoutProperty_->GetLayoutRect()) {
4418 layoutProperty_->UpdateLayoutConstraintWithLayoutRect();
4419 } else if (parentLayoutConstraint) {
4420 layoutProperty_->UpdateLayoutConstraint(parentLayoutConstraint.value());
4421 } else {
4422 LayoutConstraintF layoutConstraint;
4423 layoutConstraint.percentReference.SetWidth(PipelineContext::GetCurrentRootWidth());
4424 layoutConstraint.percentReference.SetHeight(PipelineContext::GetCurrentRootHeight());
4425 layoutProperty_->UpdateLayoutConstraint(layoutConstraint);
4426 }
4427 layoutProperty_->UpdateContentConstraint();
4428 }
4429
4430 if (extensionHandler_ && !extensionHandler_->HasDrawModifier()) {
4431 extensionHandler_->SetInnerLayoutImpl(
4432 [this](int32_t, int32_t, int32_t, int32_t) { GetLayoutAlgorithm()->Layout(this); });
4433 const auto& rect = geometryNode_->GetFrameRect();
4434 extensionHandler_->Layout(rect.Width(), rect.Height(), rect.GetX(), rect.GetY());
4435 } else {
4436 GetLayoutAlgorithm()->Layout(this);
4437 }
4438
4439 if (overlayNode_) {
4440 LayoutOverlay();
4441 }
4442 time = GetSysTimestamp() - time;
4443 AddNodeFlexLayouts();
4444 AddNodeLayoutTime(time);
4445 } else {
4446 ACE_SCOPED_TRACE("SkipLayout [%s][self:%d]", GetTag().c_str(), GetId());
4447 GetLayoutAlgorithm()->SetSkipLayout();
4448 }
4449 if (SystemProperties::GetMeasureDebugTraceEnabled()) {
4450 ACE_MEASURE_SCOPED_TRACE("LayoutFinish[%s][self:%d][parent:%d][key:%s][frameRect:%s]", GetTag().c_str(),
4451 GetId(), GetAncestorNodeOfFrame(true) ? GetAncestorNodeOfFrame(true)->GetId() : 0,
4452 GetInspectorIdValue("").c_str(), GetGeometryNode()->GetFrameRect().ToString().c_str());
4453 }
4454
4455 auto pipeline = GetContext();
4456 CHECK_NULL_VOID_LAYOUT_TRACE_END(pipeline);
4457 auto stageManager = pipeline->GetStageManager();
4458 CHECK_NULL_VOID(stageManager);
4459 bool isFocusOnPage = stageManager->CheckPageFocus();
4460 bool needSyncRsNode = false;
4461 DirtySwapConfig config;
4462 bool willSyncGeoProperties = OnLayoutFinish(needSyncRsNode, config);
4463 needSyncRsNode |= AvoidKeyboard(isFocusOnPage);
4464 if (GetIsGeometryTransitionIn()) {
4465 renderContext_->SetFrameWithoutAnimation(renderContext_->GetPaintRectWithoutTransform());
4466 SetIsGeometryTransitionIn(false);
4467 }
4468 // skip wrapping task if node will not sync
4469 CHECK_NULL_VOID_LAYOUT_TRACE_END(willSyncGeoProperties);
4470 auto task = [weak = WeakClaim(this), needSync = needSyncRsNode, dirtyConfig = config]() {
4471 auto frameNode = weak.Upgrade();
4472 CHECK_NULL_VOID(frameNode);
4473 frameNode->SyncGeometryNode(needSync, dirtyConfig);
4474 };
4475 pipeline->AddSyncGeometryNodeTask(task);
4476 if (SelfOrParentExpansive()) {
4477 auto pipeline = GetContext();
4478 CHECK_NULL_VOID_LAYOUT_TRACE_END(pipeline);
4479 auto safeAreaManager = pipeline->GetSafeAreaManager();
4480 CHECK_NULL_VOID_LAYOUT_TRACE_END(safeAreaManager);
4481 safeAreaManager->AddNeedExpandNode(GetHostNode());
4482 }
4483 // if a node has geo transition but not the root node, add task only but not flush
4484 // or add to expand list, self node will be added to expand list in next layout
4485 if (geometryTransition != nullptr && !IsRootMeasureNode()) {
4486 ACE_LAYOUT_TRACE_END()
4487 return;
4488 }
4489 if (geometryTransition != nullptr) {
4490 pipeline->FlushSyncGeometryNodeTasks();
4491 }
4492 ACE_LAYOUT_TRACE_END()
4493 }
4494
SelfExpansive()4495 bool FrameNode::SelfExpansive()
4496 {
4497 auto&& opts = GetLayoutProperty()->GetSafeAreaExpandOpts();
4498 return opts && (opts->Expansive() || opts->switchToNone);
4499 }
4500
SelfExpansiveToKeyboard()4501 bool FrameNode::SelfExpansiveToKeyboard()
4502 {
4503 auto && opts = GetLayoutProperty()->GetSafeAreaExpandOpts();
4504 return opts && opts->ExpansiveToKeyboard();
4505 }
4506
ParentExpansive()4507 bool FrameNode::ParentExpansive()
4508 {
4509 auto parent = GetAncestorNodeOfFrame(false);
4510 CHECK_NULL_RETURN(parent, false);
4511 auto parentLayoutProperty = parent->GetLayoutProperty();
4512 CHECK_NULL_RETURN(parentLayoutProperty, false);
4513 auto&& parentOpts = parentLayoutProperty->GetSafeAreaExpandOpts();
4514 return parentOpts && parentOpts->Expansive();
4515 }
4516
ProcessSafeAreaPadding()4517 void FrameNode::ProcessSafeAreaPadding()
4518 {
4519 pattern_->ProcessSafeAreaPadding();
4520 }
4521
UpdateFocusState()4522 void FrameNode::UpdateFocusState()
4523 {
4524 auto focusHub = GetFocusHub();
4525 if (focusHub && focusHub->IsCurrentFocus()) {
4526 focusHub->ClearFocusState(false);
4527 focusHub->PaintFocusState(false);
4528 }
4529 }
4530
SelfOrParentExpansive()4531 bool FrameNode::SelfOrParentExpansive()
4532 {
4533 return SelfExpansive() || ParentExpansive();
4534 }
4535
ProcessAccessibilityVirtualNode()4536 void FrameNode::ProcessAccessibilityVirtualNode()
4537 {
4538 if (!hasAccessibilityVirtualNode_) {
4539 return;
4540 }
4541 auto accessibilityProperty = GetAccessibilityProperty<AccessibilityProperty>();
4542 auto virtualNode = accessibilityProperty->GetAccessibilityVirtualNode();
4543 auto virtualFrameNode = AceType::DynamicCast<NG::FrameNode>(virtualNode);
4544 if (virtualFrameNode) {
4545 auto constraint = GetLayoutConstraint();
4546 virtualFrameNode->ApplyConstraint(constraint);
4547 ProcessOffscreenNode(virtualFrameNode);
4548 }
4549 }
4550
UpdateAccessibilityNodeRect()4551 void FrameNode::UpdateAccessibilityNodeRect()
4552 {
4553 if (!AceApplicationInfo::GetInstance().IsAccessibilityEnabled()) {
4554 return;
4555 }
4556 auto context = GetContextRefPtr();
4557 CHECK_NULL_VOID(context);
4558 auto accessibilityManager = context->GetAccessibilityManager();
4559 CHECK_NULL_VOID(accessibilityManager);
4560 accessibilityManager->UpdateAccessibilityNodeRect(Claim(this));
4561 }
4562
OnLayoutFinish(bool & needSyncRsNode,DirtySwapConfig & config)4563 bool FrameNode::OnLayoutFinish(bool& needSyncRsNode, DirtySwapConfig& config)
4564 {
4565 auto context = GetContext();
4566 if (isLayoutNode_ && context) {
4567 context->AddLayoutNode(Claim(this));
4568 }
4569 isLayoutComplete_ = true;
4570 const auto& geometryTransition = layoutProperty_->GetGeometryTransition();
4571 bool hasTransition = geometryTransition != nullptr && geometryTransition->IsRunning(WeakClaim(this));
4572 if (!isActive_ && !hasTransition) {
4573 layoutAlgorithm_.Reset();
4574 ACE_SCOPED_TRACE("OnLayoutFinish[%s][self:%d] !isActive && !hasTransition", GetTag().c_str(), GetId());
4575 return false;
4576 }
4577 if (needSkipSyncGeometryNode_ && (!geometryTransition || !geometryTransition->IsNodeInAndActive(Claim(this)))) {
4578 layoutAlgorithm_.Reset();
4579 ACE_SCOPED_TRACE("OnLayoutFinish[%s][self:%d] needSkipSyncGeometryNode", GetTag().c_str(), GetId());
4580 return false;
4581 }
4582 // update layout size.
4583 bool frameSizeChange = true;
4584 bool frameOffsetChange = true;
4585 bool contentSizeChange = true;
4586 bool contentOffsetChange = true;
4587 if (oldGeometryNode_) {
4588 frameSizeChange = geometryNode_->GetFrameSize() != oldGeometryNode_->GetFrameSize();
4589 frameOffsetChange = geometryNode_->GetFrameOffset() != oldGeometryNode_->GetFrameOffset();
4590 contentSizeChange = geometryNode_->GetContentSize() != oldGeometryNode_->GetContentSize();
4591 contentOffsetChange = geometryNode_->GetContentOffset() != oldGeometryNode_->GetContentOffset();
4592 oldGeometryNode_.Reset();
4593 }
4594
4595 // clean layout flag.
4596 layoutProperty_->CleanDirty();
4597 needSyncRsNode = frameSizeChange || frameOffsetChange ||
4598 (pattern_->GetContextParam().has_value() && contentSizeChange) || HasPositionProp() ||
4599 SelfOrParentExpansive();
4600 if (hasTransition) {
4601 geometryTransition->DidLayout(Claim(this));
4602 if (geometryTransition->IsNodeOutAndActive(WeakClaim(this))) {
4603 isLayoutDirtyMarked_ = true;
4604 }
4605 needSyncRsNode = false;
4606 }
4607 if (GetTag() != V2::PAGE_ETS_TAG) {
4608 renderContext_->SavePaintRect(true, layoutProperty_->GetPixelRound());
4609 if (needSyncRsNode) {
4610 renderContext_->SyncPartialRsProperties();
4611 }
4612 } else {
4613 geometryNode_->SetPixelGridRoundOffset(geometryNode_->GetFrameOffset());
4614 geometryNode_->SetPixelGridRoundSize(geometryNode_->GetFrameSize());
4615 }
4616 config = { .frameSizeChange = frameSizeChange,
4617 .frameOffsetChange = frameOffsetChange,
4618 .contentSizeChange = contentSizeChange,
4619 .contentOffsetChange = contentOffsetChange };
4620 // check if need to paint content.
4621 auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(layoutAlgorithm_);
4622 CHECK_NULL_RETURN(layoutAlgorithmWrapper, false);
4623 config.skipMeasure = layoutAlgorithmWrapper->SkipMeasure();
4624 config.skipLayout = layoutAlgorithmWrapper->SkipLayout();
4625 if (!config.skipMeasure && !config.skipLayout) {
4626 CHECK_NULL_RETURN(context, false);
4627 if (GetInspectorId()) {
4628 context->OnLayoutCompleted(GetInspectorId()->c_str());
4629 }
4630 if (eventHub_) {
4631 eventHub_->FireLayoutNDKCallback(context);
4632 }
4633 }
4634 auto needRerender = pattern_->OnDirtyLayoutWrapperSwap(Claim(this), config);
4635 needRerender =
4636 needRerender || pattern_->OnDirtyLayoutWrapperSwap(Claim(this), config.skipMeasure, config.skipLayout);
4637 if (needRerender || (extensionHandler_ && extensionHandler_->NeedRender()) ||
4638 CheckNeedRender(paintProperty_->GetPropertyChangeFlag())) {
4639 MarkDirtyNode(true, true, PROPERTY_UPDATE_RENDER);
4640 }
4641 layoutAlgorithm_.Reset();
4642
4643 UpdateAccessibilityNodeRect();
4644 ProcessAccessibilityVirtualNode();
4645 CHECK_NULL_RETURN(context, false);
4646 context->SendUpdateVirtualNodeFocusEvent();
4647 return true;
4648 }
4649
SyncGeometryNode(bool needSyncRsNode,const DirtySwapConfig & config)4650 void FrameNode::SyncGeometryNode(bool needSyncRsNode, const DirtySwapConfig& config)
4651 {
4652 if (SystemProperties::GetSyncDebugTraceEnabled()) {
4653 ACE_LAYOUT_TRACE_BEGIN("SyncGeometryNode[%s][self:%d][parent:%d][key:%s][paintRect:%s][needSyncRsNode:%d]",
4654 GetTag().c_str(), GetId(), GetParent() ? GetParent()->GetId() : 0, GetInspectorIdValue("").c_str(),
4655 renderContext_->GetPaintRectWithoutTransform().ToString().c_str(), needSyncRsNode);
4656 ACE_LAYOUT_TRACE_END()
4657 }
4658 if (!needSyncRsNode) {
4659 ACE_SCOPED_TRACE("SyncGeometryNode[%s][self:%d] don't needSyncRsNode", GetTag().c_str(), GetId());
4660 }
4661
4662 // update border.
4663 if (layoutProperty_->GetBorderWidthProperty()) {
4664 if (!renderContext_->HasBorderColor()) {
4665 BorderColorProperty borderColorProperty;
4666 borderColorProperty.SetColor(Color::BLACK);
4667 renderContext_->UpdateBorderColor(borderColorProperty);
4668 }
4669 if (!renderContext_->HasBorderStyle()) {
4670 BorderStyleProperty borderStyleProperty;
4671 borderStyleProperty.SetBorderStyle(BorderStyle::SOLID);
4672 renderContext_->UpdateBorderStyle(borderStyleProperty);
4673 }
4674 if (!renderContext_->HasDashGap()) {
4675 BorderWidthProperty dashGapProperty;
4676 dashGapProperty.SetBorderWidth(Dimension(-1));
4677 renderContext_->UpdateDashGap(dashGapProperty);
4678 }
4679 if (!renderContext_->HasDashWidth()) {
4680 BorderWidthProperty dashWidthProperty;
4681 dashWidthProperty.SetBorderWidth(Dimension(-1));
4682 renderContext_->UpdateDashWidth(dashWidthProperty);
4683 }
4684 if (layoutProperty_->GetLayoutConstraint().has_value()) {
4685 renderContext_->UpdateBorderWidthF(ConvertToBorderWidthPropertyF(layoutProperty_->GetBorderWidthProperty(),
4686 ScaleProperty::CreateScaleProperty(),
4687 layoutProperty_->GetLayoutConstraint()->percentReference.Width()));
4688 } else {
4689 renderContext_->UpdateBorderWidthF(ConvertToBorderWidthPropertyF(layoutProperty_->GetBorderWidthProperty(),
4690 ScaleProperty::CreateScaleProperty(), PipelineContext::GetCurrentRootWidth()));
4691 }
4692 }
4693
4694 pattern_->OnSyncGeometryNode(config);
4695 if (needSyncRsNode) {
4696 pattern_->BeforeSyncGeometryProperties(config);
4697 renderContext_->SyncGeometryProperties(RawPtr(geometryNode_), true, layoutProperty_->GetPixelRound());
4698 if (SystemProperties::GetSyncDebugTraceEnabled()) {
4699 ACE_LAYOUT_TRACE_BEGIN("TriggerOnSizeChangeNode:[%s][id:%d]", GetTag().c_str(), GetId());
4700 ACE_LAYOUT_TRACE_END()
4701 }
4702 TriggerOnSizeChangeCallback();
4703 }
4704
4705 // update background
4706 if (builderFunc_) {
4707 auto builderNode = builderFunc_();
4708 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
4709 AceType::MakeRefPtr<LinearLayoutPattern>(true));
4710 if (builderNode) {
4711 builderNode->MountToParent(columnNode);
4712 }
4713 SetBackgroundLayoutConstraint(columnNode);
4714 renderContext_->CreateBackgroundPixelMap(columnNode);
4715 builderFunc_ = nullptr;
4716 backgroundNode_ = columnNode;
4717 }
4718
4719 // update focus state
4720 UpdateFocusState();
4721
4722 // rebuild child render node.
4723 if (!isLayoutNode_) {
4724 RebuildRenderContextTree();
4725 } else if (GetParent()) {
4726 GetParent()->RebuildRenderContextTree();
4727 }
4728
4729 /* Adjust components' position which have been set grid properties */
4730 AdjustGridOffset();
4731 }
4732
GetOrCreateChildByIndex(uint32_t index,bool addToRenderTree,bool isCache)4733 RefPtr<LayoutWrapper> FrameNode::GetOrCreateChildByIndex(uint32_t index, bool addToRenderTree, bool isCache)
4734 {
4735 auto child = frameProxy_->GetFrameNodeByIndex(index, true, isCache, addToRenderTree);
4736 if (child) {
4737 child->SetSkipSyncGeometryNode(SkipSyncGeometryNode());
4738 if (addToRenderTree) {
4739 child->SetActive(true);
4740 }
4741 }
4742 return child;
4743 }
4744
GetChildByIndex(uint32_t index,bool isCache)4745 RefPtr<LayoutWrapper> FrameNode::GetChildByIndex(uint32_t index, bool isCache)
4746 {
4747 return frameProxy_->GetFrameNodeByIndex(index, false, isCache, false);
4748 }
4749
GetFrameNodeChildByIndex(uint32_t index,bool isCache,bool isExpand)4750 FrameNode* FrameNode::GetFrameNodeChildByIndex(uint32_t index, bool isCache, bool isExpand)
4751 {
4752 auto frameNode = isExpand ? DynamicCast<FrameNode>(frameProxy_->GetFrameNodeByIndex(index, true, isCache, false))
4753 : DynamicCast<FrameNode>(UINode::GetFrameChildByIndexWithoutExpanded(index));
4754 return RawPtr(frameNode);
4755 }
4756
GetFrameNodeChildByIndexWithoutBuild(uint32_t index)4757 FrameNode* FrameNode::GetFrameNodeChildByIndexWithoutBuild(uint32_t index)
4758 {
4759 auto frameNode = DynamicCast<FrameNode>(UINode::GetFrameChildByIndex(index, false, false, false));
4760 return RawPtr(frameNode);
4761 }
4762
GetChildTrueIndex(const RefPtr<LayoutWrapper> & child) const4763 int32_t FrameNode::GetChildTrueIndex(const RefPtr<LayoutWrapper>& child) const
4764 {
4765 return frameProxy_->GetChildIndex(child);
4766 }
4767
GetChildTrueTotalCount() const4768 uint32_t FrameNode::GetChildTrueTotalCount() const
4769 {
4770 return frameProxy_->GetTotalCount();
4771 }
4772
GetAllChildrenWithBuild(bool addToRenderTree)4773 ChildrenListWithGuard FrameNode::GetAllChildrenWithBuild(bool addToRenderTree)
4774 {
4775 const auto& children = frameProxy_->GetAllFrameChildren();
4776 {
4777 auto guard = frameProxy_->GetGuard();
4778 for (const auto& child : children) {
4779 if (addToRenderTree) {
4780 child->SetActive(true);
4781 }
4782 child->SetSkipSyncGeometryNode(SkipSyncGeometryNode());
4783 }
4784 }
4785
4786 return children;
4787 }
4788
RemoveAllChildInRenderTree()4789 void FrameNode::RemoveAllChildInRenderTree()
4790 {
4791 frameProxy_->RemoveAllChildInRenderTree();
4792 }
4793
SetActiveChildRange(int32_t start,int32_t end,int32_t cacheStart,int32_t cacheEnd,bool showCached)4794 void FrameNode::SetActiveChildRange(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCached)
4795 {
4796 frameProxy_->SetActiveChildRange(start, end, cacheStart, cacheEnd, showCached);
4797 }
4798
SetActiveChildRange(const std::optional<ActiveChildSets> & activeChildSets,const std::optional<ActiveChildRange> & activeChildRange)4799 void FrameNode::SetActiveChildRange(
4800 const std::optional<ActiveChildSets>& activeChildSets, const std::optional<ActiveChildRange>& activeChildRange)
4801 {
4802 frameProxy_->SetActiveChildRange(activeChildSets, activeChildRange);
4803 }
4804
RecycleItemsByIndex(int32_t start,int32_t end)4805 void FrameNode::RecycleItemsByIndex(int32_t start, int32_t end)
4806 {
4807 frameProxy_->RecycleItemsByIndex(start, end);
4808 }
4809
RemoveChildInRenderTree(uint32_t index)4810 void FrameNode::RemoveChildInRenderTree(uint32_t index)
4811 {
4812 frameProxy_->RemoveChildInRenderTree(index);
4813 }
4814
SkipMeasureContent() const4815 bool FrameNode::SkipMeasureContent() const
4816 {
4817 return layoutAlgorithm_ && layoutAlgorithm_->SkipMeasure();
4818 }
4819
CheckNeedForceMeasureAndLayout()4820 bool FrameNode::CheckNeedForceMeasureAndLayout()
4821 {
4822 PropertyChangeFlag flag = layoutProperty_->GetPropertyChangeFlag();
4823 return CheckNeedMeasure(flag) || CheckNeedLayout(flag);
4824 }
4825
GetOffsetInScreen()4826 OffsetF FrameNode::GetOffsetInScreen()
4827 {
4828 auto frameOffset = GetPaintRectOffset(false, true);
4829 auto pipelineContext = PipelineContext::GetCurrentContext();
4830 CHECK_NULL_RETURN(pipelineContext, OffsetF(0.0f, 0.0f));
4831 auto window = pipelineContext->GetWindow();
4832 CHECK_NULL_RETURN(window, OffsetF(0.0f, 0.0f));
4833 auto windowOffset = window->GetCurrentWindowRect().GetOffset();
4834 frameOffset += OffsetT<float> { windowOffset.GetX(), windowOffset.GetY() };
4835 return frameOffset;
4836 }
4837
GetOffsetInSubwindow(const OffsetF & subwindowOffset)4838 OffsetF FrameNode::GetOffsetInSubwindow(const OffsetF& subwindowOffset)
4839 {
4840 auto frameOffset = GetOffsetInScreen();
4841 frameOffset -= subwindowOffset;
4842 return frameOffset;
4843 }
4844
GetDragPixelMap()4845 RefPtr<PixelMap> FrameNode::GetDragPixelMap()
4846 {
4847 auto gestureHub = GetOrCreateGestureEventHub();
4848 CHECK_NULL_RETURN(gestureHub, nullptr);
4849 RefPtr<PixelMap> pixelMap = gestureHub->GetPixelMap();
4850 // if gesture already have pixel map return directly
4851 if (pixelMap) {
4852 return pixelMap;
4853 }
4854 CHECK_NULL_RETURN(renderContext_, nullptr);
4855 pixelMap = renderContext_->GetThumbnailPixelMap();
4856 gestureHub->SetPixelMap(pixelMap);
4857 return pixelMap;
4858 }
4859
GetBaselineDistance() const4860 float FrameNode::GetBaselineDistance() const
4861 {
4862 const auto& children = frameProxy_->GetAllFrameChildren();
4863 if (children.empty()) {
4864 return geometryNode_->GetBaselineDistance();
4865 }
4866 float distance = 0.0;
4867 {
4868 auto guard = frameProxy_->GetGuard();
4869 for (const auto& child : children) {
4870 float childBaseline = child->GetBaselineDistance();
4871 distance = NearZero(distance) ? childBaseline : std::min(distance, childBaseline);
4872 }
4873 }
4874 return distance;
4875 }
4876
MarkNeedSyncRenderTree(bool needRebuild)4877 void FrameNode::MarkNeedSyncRenderTree(bool needRebuild)
4878 {
4879 if (isLayoutNode_ && GetParent()) {
4880 GetParent()->MarkNeedSyncRenderTree(needRebuild);
4881 }
4882 if (needRebuild) {
4883 frameProxy_->ResetChildren(true);
4884 }
4885 needSyncRenderTree_ = true;
4886 }
4887
GetFrameChildByIndex(uint32_t index,bool needBuild,bool isCache,bool addToRenderTree)4888 RefPtr<UINode> FrameNode::GetFrameChildByIndex(uint32_t index, bool needBuild, bool isCache, bool addToRenderTree)
4889 {
4890 if (index != 0) {
4891 return nullptr;
4892 }
4893 return Claim(this);
4894 }
4895
GetFrameChildByIndexWithoutExpanded(uint32_t index)4896 RefPtr<UINode> FrameNode::GetFrameChildByIndexWithoutExpanded(uint32_t index)
4897 {
4898 return GetFrameChildByIndex(index, false);
4899 }
4900
GetLayoutAlgorithm(bool needReset)4901 const RefPtr<LayoutAlgorithmWrapper>& FrameNode::GetLayoutAlgorithm(bool needReset)
4902 {
4903 if ((!layoutAlgorithm_ || (needReset && layoutAlgorithm_->IsExpire())) && pattern_) {
4904 if (kitNode_ && kitNode_->GetPattern()) {
4905 layoutAlgorithm_ =
4906 LayoutAlgorithmWrapper::CreateLayoutAlgorithmWrapper(kitNode_->GetPattern()->CreateLayoutAlgorithm());
4907 } else {
4908 layoutAlgorithm_ = MakeRefPtr<LayoutAlgorithmWrapper>(pattern_->CreateLayoutAlgorithm());
4909 }
4910 }
4911 if (needReset) {
4912 layoutAlgorithm_->SetNeedMeasure();
4913 }
4914 return layoutAlgorithm_;
4915 }
4916
SetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)4917 void FrameNode::SetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint)
4918 {
4919 frameProxy_->SetCacheCount(cacheCount, itemConstraint);
4920 }
4921
LayoutOverlay()4922 void FrameNode::LayoutOverlay()
4923 {
4924 auto size = geometryNode_->GetFrameSize();
4925 auto align = Alignment::TOP_LEFT;
4926 Dimension offsetX, offsetY;
4927 auto childLayoutProperty = overlayNode_->GetLayoutProperty();
4928 childLayoutProperty->GetOverlayOffset(offsetX, offsetY);
4929 auto offset = OffsetF(offsetX.ConvertToPx(), offsetY.ConvertToPx());
4930 if (childLayoutProperty->GetPositionProperty()) {
4931 align = childLayoutProperty->GetPositionProperty()->GetAlignment().value_or(align);
4932 }
4933
4934 auto childSize = overlayNode_->GetGeometryNode()->GetMarginFrameSize();
4935 auto translate = Alignment::GetAlignPosition(size, childSize, align) + offset;
4936 overlayNode_->GetGeometryNode()->SetMarginFrameOffset(translate);
4937 overlayNode_->Layout();
4938 }
4939
DoRemoveChildInRenderTree(uint32_t index,bool isAll)4940 void FrameNode::DoRemoveChildInRenderTree(uint32_t index, bool isAll)
4941 {
4942 isActive_ = false;
4943 SetActive(false);
4944 }
4945
DoSetActiveChildRange(int32_t start,int32_t end,int32_t cacheStart,int32_t cacheEnd,bool showCache)4946 void FrameNode::DoSetActiveChildRange(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache)
4947 {
4948 if (showCache) {
4949 start -= cacheStart;
4950 end += cacheEnd;
4951 }
4952 if (start <= end) {
4953 if (start > 0 || end < 0) {
4954 SetActive(false);
4955 SetJSViewActive(false);
4956 } else {
4957 SetActive(true);
4958 SetJSViewActive(true);
4959 }
4960 } else {
4961 if (end < 0 && start > 0) {
4962 SetActive(false);
4963 SetJSViewActive(false);
4964 } else {
4965 SetActive(true);
4966 SetJSViewActive(true);
4967 }
4968 }
4969 }
4970
OnInspectorIdUpdate(const std::string & id)4971 void FrameNode::OnInspectorIdUpdate(const std::string& id)
4972 {
4973 renderContext_->UpdateNodeName(id);
4974 ElementRegister::GetInstance()->AddFrameNodeByInspectorId(id, AceType::WeakClaim(this));
4975 auto parent = GetAncestorNodeOfFrame(true);
4976 if (parent && parent->GetTag() == V2::RELATIVE_CONTAINER_ETS_TAG) {
4977 parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
4978 }
4979 if (Recorder::EventRecorder::Get().IsExposureRecordEnable()) {
4980 if (exposureProcessor_) {
4981 return;
4982 }
4983 auto* context = GetContext();
4984 CHECK_NULL_VOID(context);
4985 context->AddAfterRenderTask([weak = WeakClaim(this), inspectorId = id]() {
4986 auto host = weak.Upgrade();
4987 CHECK_NULL_VOID(host);
4988 auto pageUrl = Recorder::GetPageUrlByNode(host);
4989 host->exposureProcessor_ = MakeRefPtr<Recorder::ExposureProcessor>(pageUrl, inspectorId);
4990 if (!host->exposureProcessor_->IsNeedRecord()) {
4991 return;
4992 }
4993 host->RecordExposureInner();
4994 });
4995 }
4996 }
4997
OnAutoEventParamUpdate(const std::string & value)4998 void FrameNode::OnAutoEventParamUpdate(const std::string& value)
4999 {
5000 if (value.empty()) {
5001 return;
5002 }
5003 auto paramJson = JsonUtil::ParseJsonString(value);
5004 if (paramJson == nullptr || !paramJson->IsValid() || !paramJson->IsObject()) {
5005 return;
5006 }
5007 if (paramJson->Contains(Recorder::ORIGIN_PARAM)) {
5008 propAutoEventParam_ = paramJson->GetValue(Recorder::ORIGIN_PARAM)->ToString();
5009 }
5010 if (exposureProcessor_ && exposureProcessor_->isListening()) {
5011 return;
5012 }
5013 if (!paramJson->Contains(Recorder::EXPOSURE_CONFIG_PARAM)) {
5014 return;
5015 }
5016 auto exposureCfg = paramJson->GetValue(Recorder::EXPOSURE_CONFIG_PARAM);
5017 if (exposureCfg && exposureCfg->IsObject()) {
5018 auto ratio = exposureCfg->GetDouble(Recorder::EXPOSURE_CONFIG_RATIO);
5019 auto duration = exposureCfg->GetInt(Recorder::EXPOSURE_CONFIG_DURATION);
5020 if (duration <= 0) {
5021 return;
5022 }
5023 auto* context = GetContext();
5024 CHECK_NULL_VOID(context);
5025 context->AddAfterRenderTask([weak = WeakClaim(this), ratio, duration]() {
5026 auto host = weak.Upgrade();
5027 CHECK_NULL_VOID(host);
5028 if (host->exposureProcessor_ && host->exposureProcessor_->isListening()) {
5029 return;
5030 }
5031 auto pageUrl = Recorder::GetPageUrlByNode(host);
5032 host->exposureProcessor_ =
5033 MakeRefPtr<Recorder::ExposureProcessor>(pageUrl, host->GetInspectorIdValue(""), ratio, duration);
5034 if (!host->exposureProcessor_->IsNeedRecord()) {
5035 return;
5036 }
5037 host->RecordExposureInner();
5038 });
5039 }
5040 }
5041
SetExposureProcessor(const RefPtr<Recorder::ExposureProcessor> & processor)5042 void FrameNode::SetExposureProcessor(const RefPtr<Recorder::ExposureProcessor>& processor)
5043 {
5044 if (exposureProcessor_ && exposureProcessor_->isListening()) {
5045 return;
5046 } else {
5047 exposureProcessor_ = MakeRefPtr<Recorder::ExposureProcessor>(processor);
5048 exposureProcessor_->SetContainerId(processor->GetContainerId());
5049 }
5050 exposureProcessor_->OnVisibleChange(true, "");
5051 RecordExposureInner();
5052 }
5053
RecordExposureInner()5054 void FrameNode::RecordExposureInner()
5055 {
5056 auto pipeline = GetContext();
5057 if (!pipeline) {
5058 auto piplineRef = PipelineContext::GetContextByContainerId(exposureProcessor_->GetContainerId());
5059 if (!piplineRef) {
5060 pipeline = Referenced::RawPtr(piplineRef);
5061 }
5062 }
5063 CHECK_NULL_VOID(pipeline);
5064 auto callback = [weak = WeakClaim(RawPtr(exposureProcessor_)), weakNode = WeakClaim(this)](
5065 bool visible, double ratio) {
5066 auto processor = weak.Upgrade();
5067 CHECK_NULL_VOID(processor);
5068 if (!visible) {
5069 auto host = weakNode.Upgrade();
5070 auto param = host ? host->GetAutoEventParamValue("") : "";
5071 processor->OnVisibleChange(false, param);
5072 } else {
5073 processor->OnVisibleChange(visible);
5074 }
5075 };
5076 std::vector<double> ratios = { exposureProcessor_->GetRatio() };
5077 pipeline->AddVisibleAreaChangeNode(Claim(this), ratios, callback, false);
5078 exposureProcessor_->SetListenState(true);
5079 }
5080
AddFrameNodeSnapshot(bool isHit,int32_t parentId,std::vector<RectF> responseRegionList,EventTreeType type)5081 void FrameNode::AddFrameNodeSnapshot(
5082 bool isHit, int32_t parentId, std::vector<RectF> responseRegionList, EventTreeType type)
5083 {
5084 auto context = GetContext();
5085 CHECK_NULL_VOID(context);
5086 auto eventMgr = context->GetEventManager();
5087 CHECK_NULL_VOID(eventMgr);
5088
5089 FrameNodeSnapshot info = { .nodeId = GetId(),
5090 .parentNodeId = parentId,
5091 .tag = GetTag(),
5092 .comId = propInspectorId_.value_or(""),
5093 .monopolizeEvents = GetMonopolizeEvents(),
5094 .isHit = isHit,
5095 .hitTestMode = static_cast<int32_t>(GetHitTestMode()),
5096 .responseRegionList = responseRegionList };
5097 eventMgr->GetEventTreeRecord(type).AddFrameNodeSnapshot(std::move(info));
5098 }
5099
GetUiExtensionId()5100 int32_t FrameNode::GetUiExtensionId()
5101 {
5102 if (pattern_) {
5103 return pattern_->GetUiExtensionId();
5104 }
5105 return -1;
5106 }
5107
WrapExtensionAbilityId(int64_t extensionOffset,int64_t abilityId)5108 int64_t FrameNode::WrapExtensionAbilityId(int64_t extensionOffset, int64_t abilityId)
5109 {
5110 if (pattern_) {
5111 return pattern_->WrapExtensionAbilityId(extensionOffset, abilityId);
5112 }
5113 return -1;
5114 }
5115
SearchExtensionElementInfoByAccessibilityIdNG(int64_t elementId,int32_t mode,int64_t offset,std::list<Accessibility::AccessibilityElementInfo> & output)5116 void FrameNode::SearchExtensionElementInfoByAccessibilityIdNG(
5117 int64_t elementId, int32_t mode, int64_t offset, std::list<Accessibility::AccessibilityElementInfo>& output)
5118 {
5119 if (pattern_) {
5120 pattern_->SearchExtensionElementInfoByAccessibilityId(elementId, mode, offset, output);
5121 }
5122 }
5123
SearchElementInfosByTextNG(int64_t elementId,const std::string & text,int64_t offset,std::list<Accessibility::AccessibilityElementInfo> & output)5124 void FrameNode::SearchElementInfosByTextNG(int64_t elementId, const std::string& text, int64_t offset,
5125 std::list<Accessibility::AccessibilityElementInfo>& output)
5126 {
5127 if (pattern_) {
5128 pattern_->SearchElementInfosByText(elementId, text, offset, output);
5129 }
5130 }
5131
FindFocusedExtensionElementInfoNG(int64_t elementId,int32_t focusType,int64_t offset,Accessibility::AccessibilityElementInfo & output)5132 void FrameNode::FindFocusedExtensionElementInfoNG(
5133 int64_t elementId, int32_t focusType, int64_t offset, Accessibility::AccessibilityElementInfo& output)
5134 {
5135 if (pattern_) {
5136 pattern_->FindFocusedElementInfo(elementId, focusType, offset, output);
5137 }
5138 }
5139
FocusMoveSearchNG(int64_t elementId,int32_t direction,int64_t offset,Accessibility::AccessibilityElementInfo & output)5140 void FrameNode::FocusMoveSearchNG(
5141 int64_t elementId, int32_t direction, int64_t offset, Accessibility::AccessibilityElementInfo& output)
5142 {
5143 if (pattern_) {
5144 pattern_->FocusMoveSearch(elementId, direction, offset, output);
5145 }
5146 }
5147
TransferExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionArguments,int32_t action,int64_t offset)5148 bool FrameNode::TransferExecuteAction(
5149 int64_t elementId, const std::map<std::string, std::string>& actionArguments, int32_t action, int64_t offset)
5150 {
5151 bool isExecuted = false;
5152 if (pattern_) {
5153 isExecuted = pattern_->TransferExecuteAction(elementId, actionArguments, action, offset);
5154 }
5155 return isExecuted;
5156 }
5157
GetOnChildTouchTestRet(const std::vector<TouchTestInfo> & touchInfo)5158 TouchResult FrameNode::GetOnChildTouchTestRet(const std::vector<TouchTestInfo>& touchInfo)
5159 {
5160 TouchResult res;
5161 res.strategy = TouchTestStrategy::DEFAULT;
5162
5163 auto func = GetOnTouchTestFunc();
5164 if (func == nullptr) {
5165 return res;
5166 }
5167 return func(touchInfo);
5168 }
5169
GetOnTouchTestFunc()5170 OnChildTouchTestFunc FrameNode::GetOnTouchTestFunc()
5171 {
5172 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
5173 if (gestureHub == nullptr) {
5174 return nullptr;
5175 }
5176 auto& func = gestureHub->GetOnTouchTestFunc();
5177 return func;
5178 }
5179
CollectTouchInfos(const PointF & globalPoint,const PointF & parentRevertPoint,std::vector<TouchTestInfo> & touchInfos)5180 void FrameNode::CollectTouchInfos(
5181 const PointF& globalPoint, const PointF& parentRevertPoint, std::vector<TouchTestInfo>& touchInfos)
5182 {
5183 if (GetOnTouchTestFunc() == nullptr) {
5184 return;
5185 }
5186
5187 for (auto iter = frameChildren_.rbegin(); iter != frameChildren_.rend(); ++iter) {
5188 const auto& child = iter->Upgrade();
5189 if (!child) {
5190 continue;
5191 }
5192
5193 TouchTestInfo info;
5194 if (!child->GetInspectorId().has_value()) {
5195 continue;
5196 }
5197 info.id = child->GetInspectorId().value();
5198 info.windowPoint = globalPoint;
5199 info.currentCmpPoint = parentRevertPoint;
5200
5201 auto renderContext = child->GetRenderContext();
5202 CHECK_NULL_VOID(renderContext);
5203 auto origRect = renderContext->GetPaintRectWithoutTransform();
5204 auto revertPoint = parentRevertPoint;
5205 renderContext->GetPointWithRevert(revertPoint);
5206 auto subRevertPoint = revertPoint - origRect.GetOffset();
5207 info.subCmpPoint = subRevertPoint;
5208
5209 info.subRect = child->GetGeometryNode()->GetFrameRect();
5210
5211 touchInfos.emplace_back(info);
5212 }
5213 }
5214
GetDispatchFrameNode(const TouchResult & touchRes)5215 RefPtr<FrameNode> FrameNode::GetDispatchFrameNode(const TouchResult& touchRes)
5216 {
5217 if (touchRes.strategy != TouchTestStrategy::FORWARD_COMPETITION &&
5218 touchRes.strategy != TouchTestStrategy::FORWARD) {
5219 return nullptr;
5220 }
5221
5222 for (auto iter = frameChildren_.rbegin(); iter != frameChildren_.rend(); ++iter) {
5223 const auto& child = iter->Upgrade();
5224 if (!child) {
5225 continue;
5226 }
5227 std::string id = child->GetInspectorId().value_or("");
5228 if ((!touchRes.id.empty()) && (touchRes.id == id)) {
5229 return child;
5230 }
5231 }
5232 return nullptr;
5233 }
5234
CalculateCachedTransformRelativeOffset(uint64_t nanoTimestamp)5235 OffsetF FrameNode::CalculateCachedTransformRelativeOffset(uint64_t nanoTimestamp)
5236 {
5237 auto context = GetRenderContext();
5238 CHECK_NULL_RETURN(context, OffsetF());
5239 auto offset = context->GetPaintRectWithTransform().GetOffset();
5240
5241 auto parent = GetAncestorNodeOfFrame(true);
5242 if (parent) {
5243 auto parentTimestampOffset = parent->GetCachedTransformRelativeOffset();
5244 if (parentTimestampOffset.first == nanoTimestamp) {
5245 auto result = offset + parentTimestampOffset.second;
5246 SetCachedTransformRelativeOffset({ nanoTimestamp, result });
5247 return result;
5248 }
5249 auto result = offset + parent->CalculateCachedTransformRelativeOffset(nanoTimestamp);
5250 SetCachedTransformRelativeOffset({ nanoTimestamp, result });
5251 return result;
5252 }
5253 SetCachedTransformRelativeOffset({ nanoTimestamp, offset });
5254 return offset;
5255 }
5256
CalculateOffsetRelativeToWindow(uint64_t nanoTimestamp,bool logFlag)5257 OffsetF FrameNode::CalculateOffsetRelativeToWindow(uint64_t nanoTimestamp, bool logFlag)
5258 {
5259 auto currOffset = geometryNode_->GetFrameOffset();
5260 if (renderContext_ && renderContext_->GetPositionProperty()) {
5261 if (renderContext_->GetPositionProperty()->HasPosition()) {
5262 auto renderPosition =
5263 ContextPositionConvertToPX(renderContext_, layoutProperty_->GetLayoutConstraint()->percentReference);
5264 currOffset.SetX(static_cast<float>(renderPosition.first));
5265 currOffset.SetY(static_cast<float>(renderPosition.second));
5266 }
5267 }
5268
5269 auto parent = GetAncestorNodeOfFrame(true);
5270 if (parent) {
5271 auto parentTimestampOffset = parent->GetCachedGlobalOffset();
5272 if (parentTimestampOffset.first == nanoTimestamp) {
5273 currOffset = currOffset + parentTimestampOffset.second;
5274 SetCachedGlobalOffset({ nanoTimestamp, currOffset });
5275 } else {
5276 currOffset = currOffset + parent->CalculateOffsetRelativeToWindow(nanoTimestamp, logFlag);
5277 SetCachedGlobalOffset({ nanoTimestamp, currOffset });
5278 }
5279 } else {
5280 SetCachedGlobalOffset({ nanoTimestamp, currOffset });
5281 }
5282 if (logFlag) {
5283 TAG_LOGD(AceLogTag::ACE_UIEVENT, "OnAreaChange Node(%{public}s/%{public}d) offsetToWindow:%{public}s",
5284 GetTag().c_str(), GetId(), currOffset.ToString().c_str());
5285 }
5286 return currOffset;
5287 }
5288
GetNodeContainer()5289 RefPtr<FrameNode> FrameNode::GetNodeContainer()
5290 {
5291 if (GetTag() == V2::NODE_CONTAINER_ETS_TAG) {
5292 return Claim(this);
5293 }
5294 auto parent = GetParent();
5295 while (parent && parent->GetTag() != V2::NODE_CONTAINER_ETS_TAG) {
5296 parent = parent->GetParent();
5297 }
5298 return AceType::DynamicCast<FrameNode>(parent);
5299 }
5300
InitLastArea()5301 void FrameNode::InitLastArea()
5302 {
5303 if (!lastFrameRect_) {
5304 lastFrameRect_ = std::make_unique<RectF>();
5305 }
5306 if (!lastParentOffsetToWindow_) {
5307 lastParentOffsetToWindow_ = std::make_unique<OffsetF>();
5308 }
5309 if (!lastHostParentOffsetToWindow_) {
5310 lastHostParentOffsetToWindow_ = std::make_shared<OffsetF>();
5311 }
5312 }
5313
SetParentLayoutConstraint(const SizeF & size) const5314 bool FrameNode::SetParentLayoutConstraint(const SizeF& size) const
5315 {
5316 LayoutConstraintF layoutConstraint;
5317 layoutConstraint.UpdatePercentReference(size);
5318 layoutConstraint.UpdateMaxSizeWithCheck(size);
5319 layoutConstraint.UpdateIllegalParentIdealSizeWithCheck(OptionalSize(size));
5320 layoutProperty_->UpdateParentLayoutConstraint(layoutConstraint);
5321 return true;
5322 }
5323
ForceSyncGeometryNode()5324 void FrameNode::ForceSyncGeometryNode()
5325 {
5326 CHECK_NULL_VOID(renderContext_);
5327 oldGeometryNode_.Reset();
5328 renderContext_->SavePaintRect();
5329 renderContext_->SyncGeometryProperties(RawPtr(geometryNode_));
5330 }
5331
GetCachedGlobalOffset() const5332 const std::pair<uint64_t, OffsetF>& FrameNode::GetCachedGlobalOffset() const
5333 {
5334 return cachedGlobalOffset_;
5335 }
5336
SetCachedGlobalOffset(const std::pair<uint64_t,OffsetF> & timestampOffset)5337 void FrameNode::SetCachedGlobalOffset(const std::pair<uint64_t, OffsetF>& timestampOffset)
5338 {
5339 cachedGlobalOffset_ = timestampOffset;
5340 }
GetCachedTransformRelativeOffset() const5341 const std::pair<uint64_t, OffsetF>& FrameNode::GetCachedTransformRelativeOffset() const
5342 {
5343 return cachedTransformRelativeOffset_;
5344 }
5345
SetCachedTransformRelativeOffset(const std::pair<uint64_t,OffsetF> & timestampOffset)5346 void FrameNode::SetCachedTransformRelativeOffset(const std::pair<uint64_t, OffsetF>& timestampOffset)
5347 {
5348 cachedTransformRelativeOffset_ = timestampOffset;
5349 }
5350
PaintDebugBoundary(bool flag)5351 void FrameNode::PaintDebugBoundary(bool flag)
5352 {
5353 if (!isActive_) {
5354 return;
5355 }
5356 if (renderContext_) {
5357 renderContext_->PaintDebugBoundary(flag);
5358 }
5359 }
5360
TriggerOnTouchIntercept(const TouchEvent & touchEvent)5361 HitTestMode FrameNode::TriggerOnTouchIntercept(const TouchEvent& touchEvent)
5362 {
5363 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
5364 CHECK_NULL_RETURN(gestureHub, HitTestMode::HTMDEFAULT);
5365 auto onTouchIntercept = gestureHub->GetOnTouchIntercept();
5366 CHECK_NULL_RETURN(onTouchIntercept, HitTestMode::HTMDEFAULT);
5367 TouchEventInfo event("touchEvent");
5368 event.SetTimeStamp(touchEvent.time);
5369 event.SetDeviceId(touchEvent.deviceId);
5370 event.SetPointerEvent(touchEvent.GetTouchEventPointerEvent());
5371 TouchLocationInfo changedInfo("onTouch", touchEvent.originalId);
5372 PointF lastLocalPoint(touchEvent.x, touchEvent.y);
5373 NGGestureRecognizer::Transform(lastLocalPoint, Claim(this), false, false);
5374 auto localX = static_cast<float>(lastLocalPoint.GetX());
5375 auto localY = static_cast<float>(lastLocalPoint.GetY());
5376 changedInfo.SetLocalLocation(Offset(localX, localY));
5377 changedInfo.SetGlobalLocation(Offset(touchEvent.x, touchEvent.y));
5378 changedInfo.SetScreenLocation(Offset(touchEvent.screenX, touchEvent.screenY));
5379 changedInfo.SetTouchType(touchEvent.type);
5380 changedInfo.SetForce(touchEvent.force);
5381 changedInfo.SetPressedTime(touchEvent.pressedTime);
5382 changedInfo.SetWidth(touchEvent.width);
5383 changedInfo.SetHeight(touchEvent.height);
5384 if (touchEvent.tiltX.has_value()) {
5385 changedInfo.SetTiltX(touchEvent.tiltX.value());
5386 }
5387 if (touchEvent.tiltY.has_value()) {
5388 changedInfo.SetTiltY(touchEvent.tiltY.value());
5389 }
5390 changedInfo.SetSourceTool(touchEvent.sourceTool);
5391 event.AddChangedTouchLocationInfo(std::move(changedInfo));
5392
5393 AddTouchEventAllFingersInfo(event, touchEvent);
5394 event.SetSourceDevice(touchEvent.sourceType);
5395 event.SetForce(touchEvent.force);
5396 if (touchEvent.tiltX.has_value()) {
5397 event.SetTiltX(touchEvent.tiltX.value());
5398 }
5399 if (touchEvent.tiltY.has_value()) {
5400 event.SetTiltY(touchEvent.tiltY.value());
5401 }
5402 if (touchEvent.rollAngle.has_value()) {
5403 event.SetRollAngle(touchEvent.rollAngle.value());
5404 }
5405 event.SetSourceTool(touchEvent.sourceTool);
5406 EventTarget eventTarget;
5407 eventTarget.id = GetInspectorId().value_or("").c_str();
5408 event.SetTarget(eventTarget);
5409 auto result = onTouchIntercept(event);
5410 SetHitTestMode(result);
5411 return result;
5412 }
5413
AddTouchEventAllFingersInfo(TouchEventInfo & event,const TouchEvent & touchEvent)5414 void FrameNode::AddTouchEventAllFingersInfo(TouchEventInfo& event, const TouchEvent& touchEvent)
5415 {
5416 // all fingers collection
5417 for (const auto& item : touchEvent.pointers) {
5418 float globalX = item.x;
5419 float globalY = item.y;
5420 float screenX = item.screenX;
5421 float screenY = item.screenY;
5422 PointF localPoint(globalX, globalY);
5423 NGGestureRecognizer::Transform(localPoint, Claim(this), false, false);
5424 auto localX = static_cast<float>(localPoint.GetX());
5425 auto localY = static_cast<float>(localPoint.GetY());
5426 TouchLocationInfo info("onTouch", item.originalId);
5427 info.SetGlobalLocation(Offset(globalX, globalY));
5428 info.SetLocalLocation(Offset(localX, localY));
5429 info.SetScreenLocation(Offset(screenX, screenY));
5430 info.SetTouchType(touchEvent.type);
5431 info.SetForce(item.force);
5432 info.SetPressedTime(item.downTime);
5433 info.SetWidth(item.width);
5434 info.SetHeight(item.height);
5435 if (item.tiltX.has_value()) {
5436 info.SetTiltX(item.tiltX.value());
5437 }
5438 if (item.tiltY.has_value()) {
5439 info.SetTiltY(item.tiltY.value());
5440 }
5441 info.SetSourceTool(item.sourceTool);
5442 event.AddTouchLocationInfo(std::move(info));
5443 }
5444 }
5445
ChangeSensitiveStyle(bool isSensitive)5446 void FrameNode::ChangeSensitiveStyle(bool isSensitive)
5447 {
5448 pattern_->OnSensitiveStyleChange(isSensitive);
5449 }
5450
AttachContext(PipelineContext * context,bool recursive)5451 void FrameNode::AttachContext(PipelineContext* context, bool recursive)
5452 {
5453 UINode::AttachContext(context, recursive);
5454 if (eventHub_) {
5455 eventHub_->OnAttachContext(context);
5456 }
5457 pattern_->OnAttachContext(context);
5458 }
5459
DetachContext(bool recursive)5460 void FrameNode::DetachContext(bool recursive)
5461 {
5462 CHECK_NULL_VOID(context_);
5463 pattern_->OnDetachContext(context_);
5464 if (eventHub_) {
5465 eventHub_->OnDetachContext(context_);
5466 }
5467 UINode::DetachContext(recursive);
5468 }
5469
OnCollectRemoved()5470 void FrameNode::OnCollectRemoved()
5471 {
5472 pattern_->OnCollectRemoved();
5473 }
5474
ApplyFrameNodeTranformToRect(const RectF & rect,const RefPtr<FrameNode> & parent) const5475 RectF FrameNode::ApplyFrameNodeTranformToRect(const RectF& rect, const RefPtr<FrameNode>& parent) const
5476 {
5477 RectF newRect = rect;
5478 if (!parent) {
5479 return newRect;
5480 }
5481
5482 auto parentRenderContext = parent->GetRenderContext();
5483 if (!parentRenderContext) {
5484 return newRect;
5485 }
5486
5487 auto parentScale = parentRenderContext->GetTransformScale();
5488 auto offset = rect.GetOffset();
5489 if (parentScale) {
5490 newRect.SetWidth(rect.Width() * parentScale.value().x);
5491 newRect.SetHeight(rect.Height() * parentScale.value().y);
5492 offset = OffsetF(offset.GetX() * parentScale.value().x, offset.GetY() * parentScale.value().y);
5493 }
5494 offset += parentRenderContext->GetPaintRectWithTransform().GetOffset();
5495 newRect.SetOffset(offset);
5496 return newRect;
5497 }
5498
GetVisibleRect(RectF & visibleRect,RectF & frameRect) const5499 void FrameNode::GetVisibleRect(RectF& visibleRect, RectF& frameRect) const
5500 {
5501 visibleRect = GetPaintRectWithTransform();
5502 frameRect = visibleRect;
5503 RefPtr<FrameNode> parentUi = GetAncestorNodeOfFrame(true);
5504 if (!parentUi) {
5505 visibleRect.SetWidth(0.0f);
5506 visibleRect.SetHeight(0.0f);
5507 return;
5508 }
5509 while (parentUi) {
5510 visibleRect = ApplyFrameNodeTranformToRect(visibleRect, parentUi);
5511 auto parentRect = parentUi->GetPaintRectWithTransform();
5512 visibleRect = visibleRect.Constrain(parentRect);
5513 if (visibleRect.IsEmpty()) {
5514 return;
5515 }
5516 frameRect = ApplyFrameNodeTranformToRect(frameRect, parentUi);
5517 parentUi = parentUi->GetAncestorNodeOfFrame(true);
5518 }
5519 }
5520
AllowVisibleAreaCheck() const5521 bool FrameNode::AllowVisibleAreaCheck() const
5522 {
5523 return IsOnMainTree() || (pattern_ && pattern_->AllowVisibleAreaCheck());
5524 }
5525
GetVisibleRectWithClip(RectF & visibleRect,RectF & visibleInnerRect,RectF & frameRect) const5526 void FrameNode::GetVisibleRectWithClip(RectF& visibleRect, RectF& visibleInnerRect, RectF& frameRect) const
5527 {
5528 visibleRect = GetPaintRectWithTransform();
5529 frameRect = visibleRect;
5530 visibleInnerRect = visibleRect;
5531 RefPtr<FrameNode> parentUi = GetAncestorNodeOfFrame(true);
5532 if (!AllowVisibleAreaCheck() || !parentUi || IsFrameDisappear()) {
5533 visibleRect.SetWidth(0.0f);
5534 visibleRect.SetHeight(0.0f);
5535 visibleInnerRect.SetWidth(0.0f);
5536 visibleInnerRect.SetHeight(0.0f);
5537 return;
5538 }
5539
5540 while (parentUi) {
5541 visibleRect = ApplyFrameNodeTranformToRect(visibleRect, parentUi);
5542 auto parentRect = parentUi->GetPaintRectWithTransform();
5543 if (!visibleRect.IsEmpty()) {
5544 visibleRect = visibleRect.Constrain(parentRect);
5545 }
5546
5547 if (isCalculateInnerVisibleRectClip_) {
5548 visibleInnerRect = ApplyFrameNodeTranformToRect(visibleInnerRect, parentUi);
5549 auto parentContext = parentUi->GetRenderContext();
5550 if (!visibleInnerRect.IsEmpty() && ((parentContext && parentContext->GetClipEdge().value_or(false)) ||
5551 parentUi->IsWindowBoundary() || parentUi->GetTag() == V2::ROOT_ETS_TAG)) {
5552 visibleInnerRect = visibleInnerRect.Constrain(parentRect);
5553 }
5554 }
5555
5556 if (visibleRect.IsEmpty() && (!isCalculateInnerVisibleRectClip_ || visibleInnerRect.IsEmpty())) {
5557 visibleInnerRect = visibleRect;
5558 return;
5559 }
5560 frameRect = ApplyFrameNodeTranformToRect(frameRect, parentUi);
5561 parentUi = parentUi->GetAncestorNodeOfFrame(true);
5562 }
5563
5564 if (!isCalculateInnerVisibleRectClip_) {
5565 visibleInnerRect = visibleRect;
5566 }
5567 }
5568
GetCacheVisibleRect(uint64_t timestamp,bool logFlag)5569 CacheVisibleRectResult FrameNode::GetCacheVisibleRect(uint64_t timestamp, bool logFlag)
5570 {
5571 RefPtr<FrameNode> parentUi = GetAncestorNodeOfFrame(true);
5572 auto rectToParent = GetPaintRectWithTransform();
5573 auto scale = GetTransformScale();
5574
5575 if (!parentUi || IsWindowBoundary()) {
5576 cachedVisibleRectResult_ = {timestamp,
5577 {rectToParent.GetOffset(), rectToParent, rectToParent, scale, rectToParent, rectToParent}};
5578 return cachedVisibleRectResult_.second;
5579 }
5580
5581 CacheVisibleRectResult result;
5582 if (parentUi->cachedVisibleRectResult_.first == timestamp) {
5583 auto parentCacheVisibleRectResult = parentUi->cachedVisibleRectResult_.second;
5584 result = CalculateCacheVisibleRect(parentCacheVisibleRectResult, parentUi, rectToParent, scale, timestamp);
5585 } else {
5586 CacheVisibleRectResult parentCacheVisibleRectResult = parentUi->GetCacheVisibleRect(timestamp, logFlag);
5587 result = CalculateCacheVisibleRect(parentCacheVisibleRectResult, parentUi, rectToParent, scale, timestamp);
5588 }
5589 if (logFlag) {
5590 TAG_LOGD(AceLogTag::ACE_UIEVENT,
5591 "OnVisibleAreaChange Node(%{public}s/%{public}d) windowOffset:%{public}s visibleRect:%{public}s "
5592 "innerVisibleRect:%{public}s frameRect:%{public}s innerBoundaryRect:%{public}s",
5593 GetTag().c_str(), GetId(), result.windowOffset.ToString().c_str(), result.visibleRect.ToString().c_str(),
5594 result.innerVisibleRect.ToString().c_str(), result.frameRect.ToString().c_str(),
5595 result.innerBoundaryRect.ToString().c_str());
5596 }
5597 return result;
5598 }
5599
CalculateCacheVisibleRect(CacheVisibleRectResult & parentCacheVisibleRect,const RefPtr<FrameNode> & parentUi,RectF & rectToParent,VectorF scale,uint64_t timestamp)5600 CacheVisibleRectResult FrameNode::CalculateCacheVisibleRect(CacheVisibleRectResult& parentCacheVisibleRect,
5601 const RefPtr<FrameNode>& parentUi, RectF& rectToParent, VectorF scale, uint64_t timestamp)
5602 {
5603 auto parentRenderContext = parentUi->GetRenderContext();
5604 OffsetF windowOffset;
5605 auto offset = rectToParent.GetOffset();
5606 if (parentRenderContext && parentRenderContext->GetTransformScale()) {
5607 auto parentScale = parentRenderContext->GetTransformScale();
5608 offset = OffsetF(offset.GetX() * parentScale.value().x, offset.GetY() * parentScale.value().y);
5609 }
5610 windowOffset = parentCacheVisibleRect.windowOffset + offset;
5611
5612 RectF rect;
5613 rect.SetOffset(windowOffset);
5614 rect.SetWidth(rectToParent.Width() * parentCacheVisibleRect.cumulativeScale.x);
5615 rect.SetHeight(rectToParent.Height() * parentCacheVisibleRect.cumulativeScale.y);
5616
5617 auto visibleRect = rect.Constrain(parentCacheVisibleRect.visibleRect);
5618 auto innerVisibleRect = rect;
5619 auto innerBoundaryRect = parentCacheVisibleRect.innerBoundaryRect;
5620 if (parentRenderContext && parentRenderContext->GetClipEdge().value_or(false)) {
5621 innerBoundaryRect = parentCacheVisibleRect.innerVisibleRect.Constrain(innerBoundaryRect);
5622 }
5623 innerVisibleRect = rect.Constrain(innerBoundaryRect);
5624
5625 scale = {scale.x * parentCacheVisibleRect.cumulativeScale.x, scale.y * parentCacheVisibleRect.cumulativeScale.y};
5626 cachedVisibleRectResult_ = { timestamp,
5627 { windowOffset, visibleRect, innerVisibleRect, scale, rect, innerBoundaryRect } };
5628 return {windowOffset, visibleRect, innerVisibleRect, scale, rect, innerBoundaryRect};
5629 }
5630
IsContextTransparent()5631 bool FrameNode::IsContextTransparent()
5632 {
5633 ACE_SCOPED_TRACE("Transparent detection");
5634 const auto& rect = renderContext_->GetPaintRectWithTransform();
5635 auto width = rect.Width();
5636 auto height = rect.Height();
5637 if (renderContext_->GetOpacity().has_value() && renderContext_->GetOpacity().value() <= MIN_OPACITY) {
5638 return true;
5639 }
5640 auto layoutTags = GetLayoutTags();
5641 if (layoutTags.find(GetTag()) == layoutTags.end()) {
5642 if (width > MIN_WIDTH && height > MIN_HEIGHT &&
5643 static_cast<int32_t>(layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE)) == 0) {
5644 return false;
5645 }
5646 } else {
5647 if (width > MIN_WIDTH && height > MIN_HEIGHT &&
5648 static_cast<int32_t>(layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE)) == 0 &&
5649 renderContext_->GetBackgroundColor()->ColorToString().compare("#00000000") != 0) {
5650 return false;
5651 }
5652 }
5653 for (const auto& item : GetChildren()) {
5654 if (!item->IsContextTransparent()) {
5655 return false;
5656 }
5657 }
5658 return true;
5659 }
5660
GetOrRefreshMatrixFromCache(bool forceRefresh)5661 CacheMatrixInfo& FrameNode::GetOrRefreshMatrixFromCache(bool forceRefresh)
5662 {
5663 auto pipeline = GetContext();
5664 CHECK_NULL_RETURN(pipeline, cacheMatrixInfo_);
5665 auto nanoTimestamp = pipeline->GetVsyncTime();
5666 CHECK_NULL_RETURN(renderContext_, cacheMatrixInfo_);
5667 auto rect = renderContext_->GetPaintRectWithoutTransform();
5668 // the caller is trying to refresh cache forcedly or the cache is invalid
5669 if (!isTransformNotChanged_ || forceRefresh || prePaintRect_ != rect ||
5670 getCacheNanoTime_ + MATRIX_CACHE_TIME_THRESHOLD < nanoTimestamp) {
5671 cacheMatrixInfo_.revertMatrix = renderContext_->GetRevertMatrix();
5672 cacheMatrixInfo_.paintRectWithTransform = renderContext_->GetPaintRectWithTransform();
5673 cacheMatrixInfo_.localMatrix = Matrix4::CreateTranslate(-rect.GetOffset().GetX(),
5674 -rect.GetOffset().GetY(), 0) * cacheMatrixInfo_.revertMatrix;
5675 isTransformNotChanged_ = true;
5676 getCacheNanoTime_ = nanoTimestamp;
5677 prePaintRect_ = rect;
5678 return cacheMatrixInfo_;
5679 }
5680
5681 // cache valid
5682 return cacheMatrixInfo_;
5683 }
5684
5685 // apply the matrix to the given point specified by dst
MapPointTo(PointF & dst,Matrix4 & matrix)5686 void FrameNode::MapPointTo(PointF& dst, Matrix4& matrix)
5687 {
5688 Point tmp(dst.GetX(), dst.GetY());
5689 auto transformPoint = matrix * tmp;
5690 dst.SetX(transformPoint.GetX());
5691 dst.SetY(transformPoint.GetY());
5692 }
5693
SetSuggestOpIncMarked(bool flag)5694 void FrameNode::SetSuggestOpIncMarked(bool flag)
5695 {
5696 if (flag) {
5697 suggestOpIncByte_ |= SUGGEST_OPINC_MARKED_MASK;
5698 } else {
5699 suggestOpIncByte_ &= (~SUGGEST_OPINC_MARKED_MASK);
5700 }
5701 }
5702
GetSuggestOpIncMarked()5703 bool FrameNode::GetSuggestOpIncMarked()
5704 {
5705 return (suggestOpIncByte_ & SUGGEST_OPINC_MARKED_MASK) > 0;
5706 }
5707
SetCanSuggestOpInc(bool flag)5708 void FrameNode::SetCanSuggestOpInc(bool flag)
5709 {
5710 if (flag) {
5711 suggestOpIncByte_ |= CAN_SUGGEST_OPINC_MASK;
5712 } else {
5713 suggestOpIncByte_ &= (~CAN_SUGGEST_OPINC_MASK);
5714 }
5715 }
5716
GetCanSuggestOpInc()5717 bool FrameNode::GetCanSuggestOpInc()
5718 {
5719 return (suggestOpIncByte_ & CAN_SUGGEST_OPINC_MASK) > 0;
5720 }
5721
SetApplicationRenderGroupMarked(bool flag)5722 void FrameNode::SetApplicationRenderGroupMarked(bool flag)
5723 {
5724 if (flag) {
5725 suggestOpIncByte_ |= APP_RENDER_GROUP_MARKED_MASK;
5726 } else {
5727 suggestOpIncByte_ &= (~APP_RENDER_GROUP_MARKED_MASK);
5728 }
5729 }
5730
GetApplicationRenderGroupMarked()5731 bool FrameNode::GetApplicationRenderGroupMarked()
5732 {
5733 return (suggestOpIncByte_ & APP_RENDER_GROUP_MARKED_MASK) > 0;
5734 }
5735
SetSuggestOpIncActivatedOnce()5736 void FrameNode::SetSuggestOpIncActivatedOnce()
5737 {
5738 suggestOpIncByte_ |= SUGGEST_OPINC_ACTIVATED_ONCE;
5739 }
5740
GetSuggestOpIncActivatedOnce()5741 bool FrameNode::GetSuggestOpIncActivatedOnce()
5742 {
5743 return (suggestOpIncByte_ & SUGGEST_OPINC_ACTIVATED_ONCE) > 0;
5744 }
5745
SetOpIncGroupCheckedThrough(bool flag)5746 void FrameNode::SetOpIncGroupCheckedThrough(bool flag)
5747 {
5748 if (flag) {
5749 suggestOpIncByte_ |= SUGGEST_OPINC_CHECKED_THROUGH;
5750 } else {
5751 suggestOpIncByte_ &= (~SUGGEST_OPINC_CHECKED_THROUGH);
5752 }
5753 }
5754
GetOpIncGroupCheckedThrough()5755 bool FrameNode::GetOpIncGroupCheckedThrough()
5756 {
5757 return (suggestOpIncByte_ & SUGGEST_OPINC_CHECKED_THROUGH) > 0;
5758 }
5759
SetOpIncCheckedOnce()5760 void FrameNode::SetOpIncCheckedOnce()
5761 {
5762 suggestOpIncByte_ |= SUGGEST_OPINC_CHCKED_ONCE;
5763 }
GetOpIncCheckedOnce()5764 bool FrameNode::GetOpIncCheckedOnce()
5765 {
5766 return (suggestOpIncByte_ & SUGGEST_OPINC_CHCKED_ONCE) > 0;
5767 }
5768
MarkSuggestOpIncGroup(bool suggest,bool calc)5769 bool FrameNode::MarkSuggestOpIncGroup(bool suggest, bool calc)
5770 {
5771 CHECK_NULL_RETURN(renderContext_, false);
5772 if (!GetSuggestOpIncMarked() && GetCanSuggestOpInc()) {
5773 renderContext_->SuggestOpIncNode(suggest, calc);
5774 SetSuggestOpIncMarked(true);
5775 }
5776 return true;
5777 }
5778
IsOpIncValidNode(const SizeF & boundary,int32_t childNumber)5779 OPINC_TYPE_E FrameNode::IsOpIncValidNode(const SizeF& boundary, int32_t childNumber)
5780 {
5781 auto ret = GetPattern()->OpIncType();
5782 switch (ret) {
5783 case OPINC_NODE:
5784 SetCanSuggestOpInc(true);
5785 break;
5786 case OPINC_PARENT_POSSIBLE:
5787 break;
5788 case OPINC_NODE_POSSIBLE: {
5789 int32_t height = static_cast<int>(GetGeometryNode()->GetFrameSize().Height());
5790 int32_t width = static_cast<int>(GetGeometryNode()->GetFrameSize().Width());
5791 int32_t heightBoundary = static_cast<int>(boundary.Height() * HIGHT_RATIO_LIMIT);
5792 int32_t area = height * width;
5793 if (area >= MIN_OPINC_AREA && height <= heightBoundary) {
5794 SetCanSuggestOpInc(true);
5795 ret = OPINC_NODE;
5796 } else if (height > heightBoundary) {
5797 ret = OPINC_PARENT_POSSIBLE;
5798 } else {
5799 ret = OPINC_SUGGESTED_OR_EXCLUDED;
5800 }
5801 break;
5802 }
5803 default:
5804 break;
5805 }
5806 return ret;
5807 }
5808
FindSuggestOpIncNode(std::string & path,const SizeF & boundary,int32_t depth)5809 OPINC_TYPE_E FrameNode::FindSuggestOpIncNode(std::string& path, const SizeF& boundary, int32_t depth)
5810 {
5811 if (GetSuggestOpIncActivatedOnce()) {
5812 return OPINC_SUGGESTED_OR_EXCLUDED;
5813 }
5814 SetSuggestOpIncActivatedOnce();
5815
5816 if (GetApplicationRenderGroupMarked()) {
5817 return OPINC_INVALID;
5818 }
5819 auto status = IsOpIncValidNode(boundary);
5820 if (SystemProperties::GetDebugEnabled()) {
5821 const auto& hostTag = GetHostTag();
5822 path = path + " --> " + hostTag;
5823 LOGD("FindSuggestOpIncNode : %{public}s, with depth %{public}d, boundary: %{public}f, self: %{public}f, "
5824 "status: %{public}d",
5825 path.c_str(), depth, boundary.Height(), GetGeometryNode()->GetFrameSize().Height(), status);
5826 }
5827 if (status == OPINC_NODE) {
5828 MarkSuggestOpIncGroup(true, true);
5829 return OPINC_SUGGESTED_OR_EXCLUDED;
5830 } else if (status == OPINC_SUGGESTED_OR_EXCLUDED) {
5831 return OPINC_SUGGESTED_OR_EXCLUDED;
5832 } else if (status == OPINC_PARENT_POSSIBLE) {
5833 std::list<RefPtr<FrameNode>> childrens;
5834 GenerateOneDepthVisibleFrame(childrens);
5835 for (auto& child : childrens) {
5836 if (child) {
5837 status = child->FindSuggestOpIncNode(path, boundary, depth + 1);
5838 }
5839 if (status == OPINC_INVALID) {
5840 return OPINC_INVALID;
5841 }
5842 }
5843 return OPINC_PARENT_POSSIBLE;
5844 } else if (status == OPINC_INVALID) {
5845 return OPINC_INVALID;
5846 }
5847 return OPINC_SUGGESTED_OR_EXCLUDED;
5848 }
5849
MarkAndCheckNewOpIncNode()5850 void FrameNode::MarkAndCheckNewOpIncNode()
5851 {
5852 auto parent = GetAncestorNodeOfFrame(true);
5853 CHECK_NULL_VOID(parent);
5854 if (parent->GetSuggestOpIncActivatedOnce() && !GetSuggestOpIncActivatedOnce()) {
5855 SetSuggestOpIncActivatedOnce();
5856 if (!parent->GetOpIncCheckedOnce()) {
5857 parent->SetOpIncCheckedOnce();
5858 auto status = IsOpIncValidNode(parent->GetGeometryNode()->GetFrameSize());
5859 if (status == OPINC_NODE) {
5860 parent->SetOpIncGroupCheckedThrough(true);
5861 } else {
5862 parent->SetOpIncGroupCheckedThrough(false);
5863 }
5864 }
5865 if (parent->GetOpIncGroupCheckedThrough()) {
5866 SetCanSuggestOpInc(true);
5867 MarkSuggestOpIncGroup(true, true);
5868 }
5869 }
5870 }
5871
GetValidLeafChildNumber(const RefPtr<FrameNode> & host,int32_t thresh)5872 int FrameNode::GetValidLeafChildNumber(const RefPtr<FrameNode>& host, int32_t thresh)
5873 {
5874 CHECK_NULL_RETURN(host, 0);
5875 auto total = 0;
5876 auto childSize = host->GetTotalChildCount();
5877 if (childSize < 1) {
5878 return 1;
5879 }
5880 for (auto i = 0; i < childSize; i++) {
5881 auto child = AceType::DynamicCast<FrameNode>(host->GetChildByIndex(i));
5882 if (!child) {
5883 continue;
5884 }
5885 total += GetValidLeafChildNumber(child, thresh);
5886 if (total >= thresh) {
5887 return total;
5888 }
5889 }
5890 return total;
5891 }
5892
TriggerShouldParallelInnerWith(const ResponseLinkResult & currentRecognizers,const ResponseLinkResult & responseLinkRecognizers)5893 void FrameNode::TriggerShouldParallelInnerWith(
5894 const ResponseLinkResult& currentRecognizers, const ResponseLinkResult& responseLinkRecognizers)
5895 {
5896 auto gestureHub = eventHub_ ? eventHub_->GetGestureEventHub() : nullptr;
5897 CHECK_NULL_VOID(gestureHub);
5898 auto shouldBuiltInRecognizerParallelWithFunc = gestureHub->GetParallelInnerGestureToFunc();
5899 CHECK_NULL_VOID(shouldBuiltInRecognizerParallelWithFunc);
5900 std::map<GestureTypeName, std::vector<RefPtr<NGGestureRecognizer>>> sortedResponseLinkRecognizers;
5901
5902 for (const auto& item : responseLinkRecognizers) {
5903 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
5904 if (!recognizer) {
5905 continue;
5906 }
5907 auto type = recognizer->GetRecognizerType();
5908 sortedResponseLinkRecognizers[type].emplace_back(item);
5909 }
5910
5911 for (const auto& item : currentRecognizers) {
5912 if (!item->IsSystemGesture() || item->GetRecognizerType() != GestureTypeName::PAN_GESTURE) {
5913 continue;
5914 }
5915 auto multiRecognizer = AceType::DynamicCast<MultiFingersRecognizer>(item);
5916 if (!multiRecognizer || multiRecognizer->GetTouchPointsSize() > 1) {
5917 continue;
5918 }
5919 auto iter = sortedResponseLinkRecognizers.find(item->GetRecognizerType());
5920 if (iter == sortedResponseLinkRecognizers.end() || iter->second.empty()) {
5921 continue;
5922 }
5923 auto result = shouldBuiltInRecognizerParallelWithFunc(item, iter->second);
5924 if (result && item != result) {
5925 item->SetBridgeMode(true);
5926 result->AddBridgeObj(item);
5927 }
5928 }
5929 }
5930
GetInspectorValue()5931 void FrameNode::GetInspectorValue()
5932 {
5933 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
5934 if (GetTag() == V2::WEB_ETS_TAG) {
5935 UiSessionManager::GetInstance()->WebTaskNumsChange(1);
5936 auto pattern = GetPattern<NG::WebPattern>();
5937 CHECK_NULL_VOID(pattern);
5938 auto cb = [](std::shared_ptr<JsonValue> value, int32_t webId) {
5939 UiSessionManager::GetInstance()->AddValueForTree(webId, value->ToString());
5940 UiSessionManager::GetInstance()->WebTaskNumsChange(-1);
5941 };
5942 pattern->GetAllWebAccessibilityNodeInfos(cb, GetId());
5943 }
5944 #endif
5945 UINode::GetInspectorValue();
5946 }
5947
ClearSubtreeLayoutAlgorithm(bool includeSelf,bool clearEntireTree)5948 void FrameNode::ClearSubtreeLayoutAlgorithm(bool includeSelf, bool clearEntireTree)
5949 {
5950 // return when reaches a child that has no layoutAlgorithm and no need to clear the entire tree
5951 if (!layoutAlgorithm_ && !clearEntireTree) {
5952 return;
5953 }
5954 // include Self might be false for the first ClearSubtreeLayoutAlgorithm enter,
5955 // but children should always include themselves
5956 if (includeSelf) {
5957 layoutAlgorithm_.Reset();
5958 }
5959 for (const auto& child : GetChildren()) {
5960 child->ClearSubtreeLayoutAlgorithm(true, clearEntireTree);
5961 }
5962 }
5963
OnSyncGeometryFrameFinish(const RectF & paintRect)5964 void FrameNode::OnSyncGeometryFrameFinish(const RectF& paintRect)
5965 {
5966 if (syncedFramePaintRect_.has_value() && syncedFramePaintRect_.value() != paintRect) {
5967 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_GEOMETRY_CHANGE);
5968 if (AnimationUtils::IsImplicitAnimationOpen()) {
5969 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_START_ANIMATION);
5970 }
5971 }
5972 syncedFramePaintRect_ = paintRect;
5973 }
5974
AddFrameNodeChangeInfoFlag(FrameNodeChangeInfoFlag changeFlag)5975 void FrameNode::AddFrameNodeChangeInfoFlag(FrameNodeChangeInfoFlag changeFlag)
5976 {
5977 auto context = GetContext();
5978 CHECK_NULL_VOID(context);
5979 if (changeFlag == FRAME_NODE_CHANGE_GEOMETRY_CHANGE || changeFlag == FRAME_NODE_CHANGE_TRANSITION_START ||
5980 changeFlag == FRAME_NODE_CHANGE_TRANSFORM_CHANGE) {
5981 context->SetIsTransFlag(true);
5982 }
5983 if (changeInfoFlag_ == FRAME_NODE_CHANGE_INFO_NONE) {
5984 if (!context->AddChangedFrameNode(WeakClaim(this))) {
5985 return;
5986 }
5987 }
5988 changeInfoFlag_ = changeInfoFlag_ | changeFlag;
5989 }
5990
RegisterNodeChangeListener()5991 void FrameNode::RegisterNodeChangeListener()
5992 {
5993 auto context = GetContext();
5994 CHECK_NULL_VOID(context);
5995 context->AddFrameNodeChangeListener(WeakClaim(this));
5996 }
5997
UnregisterNodeChangeListener()5998 void FrameNode::UnregisterNodeChangeListener()
5999 {
6000 auto context = GetContext();
6001 CHECK_NULL_VOID(context);
6002 context->RemoveFrameNodeChangeListener(GetId());
6003 }
6004
ProcessFrameNodeChangeFlag()6005 void FrameNode::ProcessFrameNodeChangeFlag()
6006 {
6007 auto changeFlag = FRAME_NODE_CHANGE_INFO_NONE;
6008 auto parent = Claim(this);
6009 while (parent) {
6010 if (parent->GetChangeInfoFlag() != FRAME_NODE_CHANGE_INFO_NONE) {
6011 changeFlag = changeFlag | parent->GetChangeInfoFlag();
6012 }
6013 parent = parent->GetAncestorNodeOfFrame(true);
6014 }
6015 if (changeFlag == FRAME_NODE_CHANGE_INFO_NONE) {
6016 return;
6017 }
6018 auto pattern = GetPattern();
6019 if (pattern) {
6020 pattern->OnFrameNodeChanged(changeFlag);
6021 }
6022 }
6023
OnNodeTransformInfoUpdate(bool changed)6024 void FrameNode::OnNodeTransformInfoUpdate(bool changed)
6025 {
6026 if (!changed) {
6027 return;
6028 }
6029 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_TRANSFORM_CHANGE);
6030 if (AnimationUtils::IsImplicitAnimationOpen()) {
6031 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_START_ANIMATION);
6032 }
6033 }
6034
OnNodeTransitionInfoUpdate()6035 void FrameNode::OnNodeTransitionInfoUpdate()
6036 {
6037 AddFrameNodeChangeInfoFlag(FRAME_NODE_CHANGE_TRANSITION_START);
6038 }
6039
NotifyWebPattern(bool isRegister)6040 void FrameNode::NotifyWebPattern(bool isRegister)
6041 {
6042 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(WEB_SUPPORTED) && defined(OHOS_PLATFORM)
6043 if (GetTag() == V2::WEB_ETS_TAG) {
6044 auto pattern = GetPattern<NG::WebPattern>();
6045 CHECK_NULL_VOID(pattern);
6046 if (isRegister) {
6047 auto callback = [](int64_t accessibilityId, const std::string data) {
6048 UiSessionManager::GetInstance()->ReportWebUnfocusEvent(accessibilityId, data);
6049 };
6050 pattern->RegisterTextBlurCallback(callback);
6051 } else {
6052 pattern->UnRegisterTextBlurCallback();
6053 }
6054 }
6055 #endif
6056 UINode::NotifyWebPattern(isRegister);
6057 }
6058
GetWindowPatternType() const6059 uint32_t FrameNode::GetWindowPatternType() const
6060 {
6061 CHECK_NULL_RETURN(pattern_, 0);
6062 return pattern_->GetWindowPatternType();
6063 }
6064
NotifyChange(int32_t index,int32_t count,int64_t id,NotificationType notificationType)6065 void FrameNode::NotifyChange(int32_t index, int32_t count, int64_t id, NotificationType notificationType)
6066 {
6067 int32_t updateFrom = CalcAbsPosition(index, id);
6068 auto pattern = GetPattern();
6069 switch (notificationType) {
6070 case NotificationType::START_CHANGE_POSITION:
6071 ChildrenUpdatedFrom(updateFrom);
6072 break;
6073 case NotificationType::END_CHANGE_POSITION:
6074 pattern->NotifyDataChange(updateFrom, count);
6075 break;
6076 case NotificationType::START_AND_END_CHANGE_POSITION:
6077 ChildrenUpdatedFrom(updateFrom);
6078 pattern->NotifyDataChange(updateFrom, count);
6079 break;
6080 default:
6081 break;
6082 }
6083 }
6084
6085 // for Grid refresh GridItems
ChildrenUpdatedFrom(int32_t index)6086 void FrameNode::ChildrenUpdatedFrom(int32_t index)
6087 {
6088 childrenUpdatedFrom_ = childrenUpdatedFrom_ >= 0 ? std::min(index, childrenUpdatedFrom_) : index;
6089 }
6090
OnThemeScopeUpdate(int32_t themeScopeId)6091 void FrameNode::OnThemeScopeUpdate(int32_t themeScopeId)
6092 {
6093 TAG_LOGD(AceLogTag::ACE_DEFAULT_DOMAIN, "WithTheme Node(%{public}s/%{public}d) OnThemeScopeUpdate id:%{public}d",
6094 GetTag().c_str(), GetId(), themeScopeId);
6095 if (pattern_->OnThemeScopeUpdate(themeScopeId)) {
6096 MarkDirtyNode(PROPERTY_UPDATE_RENDER);
6097 }
6098 }
6099
DumpOnSizeChangeInfo(std::unique_ptr<JsonValue> & json)6100 void FrameNode::DumpOnSizeChangeInfo(std::unique_ptr<JsonValue>& json)
6101 {
6102 std::unique_ptr<JsonValue> children = JsonUtil::CreateArray(true);
6103 for (auto it = onSizeChangeDumpInfos.rbegin(); it != onSizeChangeDumpInfos.rend(); ++it) {
6104 std::unique_ptr<JsonValue> child = JsonUtil::Create(true);
6105 child->Put("onSizeChange Time", it->onSizeChangeTimeStamp);
6106 child->Put("lastFrameRect", it->lastFrameRect.ToString().c_str());
6107 child->Put("currFrameRect", it->currFrameRect.ToString().c_str());
6108 children->Put(child);
6109 }
6110 children->Put("SizeChangeInfo", children);
6111 }
6112
DumpOverlayInfo(std::unique_ptr<JsonValue> & json)6113 void FrameNode::DumpOverlayInfo(std::unique_ptr<JsonValue>& json)
6114 {
6115 if (!layoutProperty_->IsOverlayNode()) {
6116 return;
6117 }
6118 json->Put("IsOverlayNode", "true");
6119 Dimension offsetX, offsetY;
6120 layoutProperty_->GetOverlayOffset(offsetX, offsetY);
6121 std::unique_ptr<JsonValue> children = JsonUtil::Create(true);
6122 children->Put("x", offsetX.ToString().c_str());
6123 children->Put("y", offsetY.ToString().c_str());
6124 json->Put("OverlayOffset", children);
6125 }
6126
DumpDragInfo(std::unique_ptr<JsonValue> & json)6127 void FrameNode::DumpDragInfo(std::unique_ptr<JsonValue>& json)
6128 {
6129 json->Put("Draggable", draggable_ ? "true" : "false");
6130 json->Put("UserSet", userSet_ ? "true" : "false");
6131 json->Put("CustomerSet", customerSet_ ? "true" : "false");
6132 std::unique_ptr<JsonValue> dragPreview = JsonUtil::Create(true);
6133 dragPreview->Put("Has customNode", dragPreviewInfo_.customNode ? "YES" : "NO");
6134 dragPreview->Put("Has pixelMap", dragPreviewInfo_.pixelMap ? "YES" : "NO");
6135 dragPreview->Put("extraInfo", dragPreviewInfo_.extraInfo.c_str());
6136 dragPreview->Put("inspectorId", dragPreviewInfo_.inspectorId.c_str());
6137 json->Put("DragPreview", dragPreview);
6138
6139 auto eventHub = GetEventHubOnly<EventHub>();
6140 std::unique_ptr<JsonValue> event = JsonUtil::Create(true);
6141 event->Put("OnDragStart", eventHub && eventHub->HasOnDragStart() ? "YES" : "NO");
6142 event->Put("OnDragEnter", eventHub && eventHub->HasOnDragEnter() ? "YES" : "NO");
6143 event->Put("OnDragLeave", eventHub && eventHub->HasOnDragLeave() ? "YES" : "NO");
6144 event->Put("OnDragMove", eventHub && eventHub->HasOnDragMove() ? "YES" : "NO");
6145 event->Put("OnDrop", eventHub && eventHub->HasOnDrop() ? "YES" : "NO");
6146 event->Put("OnDragEnd", eventHub && eventHub->HasOnDragEnd() ? "YES" : "NO");
6147 event->Put("DefaultOnDragStart", eventHub && eventHub->HasDefaultOnDragStart() ? "YES" : "NO");
6148 event->Put("CustomerOnDragEnter", eventHub && eventHub->HasCustomerOnDragEnter() ? "YES" : "NO");
6149 event->Put("CustomerOnDragLeave", eventHub && eventHub->HasCustomerOnDragLeave() ? "YES" : "NO");
6150 event->Put("CustomerOnDragMove", eventHub && eventHub->HasCustomerOnDragMove() ? "YES" : "NO");
6151 event->Put("CustomerOnDrop", eventHub && eventHub->HasCustomerOnDrop() ? "YES" : "NO");
6152 event->Put("CustomerOnDragEnd", eventHub && eventHub->HasCustomerOnDragEnd() ? "YES" : "NO");
6153 json->Put("Event", event);
6154 }
6155
DumpAlignRulesInfo(std::unique_ptr<JsonValue> & json)6156 void FrameNode::DumpAlignRulesInfo(std::unique_ptr<JsonValue>& json)
6157 {
6158 auto& flexItemProperties = layoutProperty_->GetFlexItemProperty();
6159 CHECK_NULL_VOID(flexItemProperties);
6160 auto rulesToString = flexItemProperties->AlignRulesToString();
6161 CHECK_NULL_VOID(!rulesToString.empty());
6162 json->Put("AlignRules", rulesToString.c_str());
6163 }
6164
DumpSafeAreaInfo(std::unique_ptr<JsonValue> & json)6165 void FrameNode::DumpSafeAreaInfo(std::unique_ptr<JsonValue>& json)
6166 {
6167 if (layoutProperty_->GetSafeAreaExpandOpts()) {
6168 json->Put("SafeAreaExpandOpts", layoutProperty_->GetSafeAreaExpandOpts()->ToString().c_str());
6169 }
6170 if (layoutProperty_->GetSafeAreaInsets()) {
6171 json->Put("SafeAreaInsets", layoutProperty_->GetSafeAreaInsets()->ToString().c_str());
6172 }
6173 if (SelfOrParentExpansive()) {
6174 json->Put("selfAdjust", geometryNode_->GetSelfAdjust().ToString().c_str());
6175 json->Put("parentAdjust", geometryNode_->GetParentAdjust().ToString().c_str());
6176 }
6177 CHECK_NULL_VOID(GetTag() == V2::PAGE_ETS_TAG);
6178 auto pipeline = GetContext();
6179 CHECK_NULL_VOID(pipeline);
6180 auto manager = pipeline->GetSafeAreaManager();
6181 CHECK_NULL_VOID(manager);
6182 json->Put("ignoreSafeArea", std::to_string(manager->IsIgnoreSafeArea()).c_str());
6183 json->Put("isNeedAvoidWindow", std::to_string(manager->IsNeedAvoidWindow()).c_str());
6184 json->Put("isFullScreen", std::to_string(manager->IsFullScreen()).c_str());
6185 json->Put("isKeyboardAvoidMode", std::to_string(static_cast<int32_t>(manager->GetKeyBoardAvoidMode())).c_str());
6186 json->Put("isUseCutout", std::to_string(manager->GetUseCutout()).c_str());
6187 }
6188
DumpExtensionHandlerInfo(std::unique_ptr<JsonValue> & json)6189 void FrameNode::DumpExtensionHandlerInfo(std::unique_ptr<JsonValue>& json)
6190 {
6191 if (!extensionHandler_) {
6192 return;
6193 }
6194 std::unique_ptr<JsonValue> extensionHandler = JsonUtil::Create(true);
6195 extensionHandler->Put("HasCustomerMeasure", extensionHandler_->HasCustomerMeasure() ? "true" : "false");
6196 extensionHandler->Put("HasCustomerLayout", extensionHandler_->HasCustomerLayout() ? "true" : "false");
6197 json->Put("ExtensionHandler", extensionHandler);
6198 }
6199
BuildLayoutInfo(std::unique_ptr<JsonValue> & json)6200 void FrameNode::BuildLayoutInfo(std::unique_ptr<JsonValue>& json)
6201 {
6202 if (geometryNode_->GetParentLayoutConstraint().has_value()) {
6203 json->Put("ParentLayoutConstraint", geometryNode_->GetParentLayoutConstraint().value().ToString().c_str());
6204 }
6205 if (!(NearZero(GetOffsetRelativeToWindow().GetY()) && NearZero(GetOffsetRelativeToWindow().GetX()))) {
6206 json->Put("top", GetOffsetRelativeToWindow().GetY());
6207 json->Put("left", GetOffsetRelativeToWindow().GetX());
6208 }
6209 if (static_cast<int32_t>(IsActive()) != 1) {
6210 json->Put("Active", static_cast<int32_t>(IsActive()));
6211 }
6212 if (static_cast<int32_t>(layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE)) != 0) {
6213 json->Put("Visible", static_cast<int32_t>(layoutProperty_->GetVisibility().value_or(VisibleType::VISIBLE)));
6214 }
6215 if (layoutProperty_->GetPaddingProperty()) {
6216 json->Put("Padding", layoutProperty_->GetPaddingProperty()->ToString().c_str());
6217 }
6218 if (layoutProperty_->GetSafeAreaPaddingProperty()) {
6219 json->Put("SafeArea Padding", layoutProperty_->GetSafeAreaPaddingProperty()->ToString().c_str());
6220 }
6221 if (layoutProperty_->GetBorderWidthProperty()) {
6222 json->Put("Border", layoutProperty_->GetBorderWidthProperty()->ToString().c_str());
6223 }
6224 if (layoutProperty_->GetMarginProperty()) {
6225 json->Put("Margin", layoutProperty_->GetMarginProperty()->ToString().c_str());
6226 }
6227 if (layoutProperty_->GetLayoutRect()) {
6228 json->Put("LayoutRect", layoutProperty_->GetLayoutRect().value().ToString().c_str());
6229 }
6230 }
6231
DumpCommonInfo(std::unique_ptr<JsonValue> & json)6232 void FrameNode::DumpCommonInfo(std::unique_ptr<JsonValue>& json)
6233 {
6234 json->Put("FrameRect", geometryNode_->GetFrameRect().ToString().c_str());
6235 json->Put("PaintRect without transform", renderContext_->GetPaintRectWithoutTransform().ToString().c_str());
6236 if (renderContext_->GetBackgroundColor()->ColorToString().compare("#00000000") != 0) {
6237 json->Put("BackgroundColor", renderContext_->GetBackgroundColor()->ColorToString().c_str());
6238 }
6239 BuildLayoutInfo(json);
6240 DumpExtensionHandlerInfo(json);
6241 DumpSafeAreaInfo(json);
6242 if (layoutProperty_->GetCalcLayoutConstraint()) {
6243 json->Put("User defined constraint", layoutProperty_->GetCalcLayoutConstraint()->ToString().c_str());
6244 }
6245 if (!propInspectorId_->empty()) {
6246 json->Put("compid", propInspectorId_.value_or("").c_str());
6247 }
6248 if (layoutProperty_->GetPaddingProperty() || layoutProperty_->GetBorderWidthProperty() ||
6249 layoutProperty_->GetMarginProperty() || layoutProperty_->GetCalcLayoutConstraint()) {
6250 json->Put("ContentConstraint", layoutProperty_->GetContentLayoutConstraint().has_value()
6251 ? layoutProperty_->GetContentLayoutConstraint().value().ToString().c_str()
6252 : "NA");
6253 }
6254 DumpAlignRulesInfo(json);
6255 DumpDragInfo(json);
6256 DumpOverlayInfo(json);
6257 if (frameProxy_->Dump().compare("totalCount is 0") != 0) {
6258 json->Put("FrameProxy", frameProxy_->Dump().c_str());
6259 }
6260 }
6261
DumpInfo(std::unique_ptr<JsonValue> & json)6262 void FrameNode::DumpInfo(std::unique_ptr<JsonValue>& json)
6263 {
6264 DumpCommonInfo(json);
6265 DumpOnSizeChangeInfo(json);
6266 if (pattern_) {
6267 pattern_->DumpInfo(json);
6268 }
6269 if (renderContext_) {
6270 renderContext_->DumpInfo(json);
6271 }
6272 }
6273
DumpAdvanceInfo(std::unique_ptr<JsonValue> & json)6274 void FrameNode::DumpAdvanceInfo(std::unique_ptr<JsonValue>& json)
6275 {
6276 DumpCommonInfo(json);
6277 DumpOnSizeChangeInfo(json);
6278 if (pattern_) {
6279 pattern_->DumpInfo(json);
6280 pattern_->DumpAdvanceInfo(json);
6281 }
6282 if (renderContext_) {
6283 renderContext_->DumpInfo(json);
6284 renderContext_->DumpAdvanceInfo(json);
6285 }
6286 }
6287
ResetPredictNodes()6288 void FrameNode::ResetPredictNodes()
6289 {
6290 auto predictLayoutNode = std::move(predictLayoutNode_);
6291 for (auto& node : predictLayoutNode) {
6292 auto frameNode = node.Upgrade();
6293 if (frameNode && frameNode->isLayoutDirtyMarked_) {
6294 frameNode->isLayoutDirtyMarked_ = false;
6295 }
6296 }
6297 }
6298
SetJSCustomProperty(std::function<bool ()> func,std::function<std::string (const std::string &)> getFunc)6299 void FrameNode::SetJSCustomProperty(std::function<bool()> func, std::function<std::string(const std::string&)> getFunc)
6300 {
6301 func();
6302 if (IsCNode()) {
6303 return;
6304 }
6305 if (!getCustomProperty_) {
6306 getCustomProperty_ = getFunc;
6307 }
6308 }
6309
GetJSCustomProperty(const std::string & key,std::string & value)6310 bool FrameNode::GetJSCustomProperty(const std::string& key, std::string& value)
6311 {
6312 auto iter = customPropertyMap_.find(key);
6313 if (iter != customPropertyMap_.end() && !iter->second.empty()) {
6314 if (iter->second[1] == "1") {
6315 value = iter->second[0];
6316 return true;
6317 } else if (getCustomProperty_) {
6318 value = getCustomProperty_(key);
6319 iter->second[0] = value;
6320 iter->second[1] = "1";
6321 return true;
6322 }
6323 }
6324 return false;
6325 }
6326
GetCapiCustomProperty(const std::string & key,std::string & value)6327 bool FrameNode::GetCapiCustomProperty(const std::string& key, std::string& value)
6328 {
6329 auto iter = customPropertyMap_.find(key);
6330 if (iter != customPropertyMap_.end()) {
6331 value = iter->second[0];
6332 return true;
6333 }
6334 return false;
6335 }
6336
AddCustomProperty(const std::string & key,const std::string & value)6337 void FrameNode::AddCustomProperty(const std::string& key, const std::string& value)
6338 {
6339 customPropertyMap_[key] = {value, "1"};
6340 }
6341
RemoveCustomProperty(const std::string & key)6342 void FrameNode::RemoveCustomProperty(const std::string& key)
6343 {
6344 auto iter = customPropertyMap_.find(key);
6345 if (iter != customPropertyMap_.end()) {
6346 customPropertyMap_.erase(iter);
6347 }
6348 }
6349
SetCustomPropertyMapFlagByKey(const std::string & key)6350 void FrameNode::SetCustomPropertyMapFlagByKey(const std::string& key)
6351 {
6352 auto& valueVector = customPropertyMap_[key];
6353 if (valueVector.empty()) {
6354 valueVector = {"", "0"};
6355 } else {
6356 valueVector[1] = "0";
6357 }
6358 }
6359
AddExtraCustomProperty(const std::string & key,void * extraData)6360 void FrameNode::AddExtraCustomProperty(const std::string& key, void* extraData)
6361 {
6362 extraCustomPropertyMap_[key] = extraData;
6363 }
6364
GetExtraCustomProperty(const std::string & key) const6365 void* FrameNode::GetExtraCustomProperty(const std::string& key) const
6366 {
6367 auto iter = extraCustomPropertyMap_.find(key);
6368 if (iter != extraCustomPropertyMap_.end()) {
6369 return iter->second;
6370 }
6371 return nullptr;
6372 }
6373
RemoveExtraCustomProperty(const std::string & key)6374 void FrameNode::RemoveExtraCustomProperty(const std::string& key)
6375 {
6376 auto iter = extraCustomPropertyMap_.find(key);
6377 if (iter != extraCustomPropertyMap_.end()) {
6378 extraCustomPropertyMap_.erase(iter);
6379 }
6380 }
6381
ExtraCustomPropertyToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const6382 void FrameNode::ExtraCustomPropertyToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
6383 {
6384 auto mapIter = extraCustomPropertyMap_.find("ToJsonValue");
6385 if (mapIter == extraCustomPropertyMap_.end()) {
6386 return;
6387 }
6388
6389 auto callback = reinterpret_cast<std::map<std::string, std::string>(*)(std::unordered_map<std::string, void*>)>(
6390 mapIter->second);
6391 CHECK_NULL_VOID(callback);
6392 auto jsonValue = callback(extraCustomPropertyMap_);
6393 for (auto iter = jsonValue.begin(); iter != jsonValue.end(); iter++) {
6394 json->PutExtAttr(iter->first.c_str(), iter->second.c_str(), filter);
6395 }
6396 }
6397
IsDebugInspectorId()6398 bool FrameNode::IsDebugInspectorId()
6399 {
6400 if (!SystemProperties::GetDebugEnabled()) {
6401 return false;
6402 }
6403 auto debugInspectorId = SystemProperties::GetDebugInspectorId();
6404 return debugInspectorId == GetInspectorId().value_or("");
6405 }
6406
GetCurrentPageRootNode()6407 RefPtr<UINode> FrameNode::GetCurrentPageRootNode()
6408 {
6409 auto pageNode = GetPageNode();
6410 CHECK_NULL_RETURN(pageNode, nullptr);
6411 auto jsView = pageNode->GetChildAtIndex(0);
6412 CHECK_NULL_RETURN(jsView, nullptr);
6413 if (jsView->GetTag() == V2::JS_VIEW_ETS_TAG) {
6414 auto rootNode = jsView->GetChildAtIndex(0);
6415 CHECK_NULL_RETURN(rootNode, nullptr);
6416 return rootNode;
6417 }
6418 return jsView;
6419 }
6420
GetActiveChildren()6421 std::list<RefPtr<FrameNode>> FrameNode::GetActiveChildren()
6422 {
6423 std::list<RefPtr<FrameNode>> list;
6424 for (int32_t i = 0; i < TotalChildCount(); i++) {
6425 auto child = GetFrameNodeChildByIndex(i, false, false);
6426 if (child->IsActive()) {
6427 list.emplace_back(Referenced::Claim(child));
6428 }
6429 }
6430 return list;
6431 }
6432
CleanVisibleAreaUserCallback(bool isApproximate)6433 void FrameNode::CleanVisibleAreaUserCallback(bool isApproximate)
6434 {
6435 CHECK_NULL_VOID(eventHub_);
6436 auto hasInnerCallback = eventHub_->HasVisibleAreaCallback(false);
6437 auto hasUserCallback = eventHub_->HasVisibleAreaCallback(true);
6438 auto& throttledVisibleAreaCallback = eventHub_->GetThrottledVisibleAreaCallback();
6439 auto pipeline = GetContext();
6440 if (isApproximate) {
6441 eventHub_->CleanVisibleAreaCallback(true, isApproximate);
6442 if (!hasInnerCallback && !hasUserCallback && pipeline) {
6443 throttledCallbackOnTheWay_ = false;
6444 pipeline->RemoveVisibleAreaChangeNode(GetId());
6445 }
6446 } else {
6447 eventHub_->CleanVisibleAreaCallback(true, false);
6448 if (!hasInnerCallback && !throttledVisibleAreaCallback.callback && pipeline) {
6449 pipeline->RemoveVisibleAreaChangeNode(GetId());
6450 }
6451 }
6452 }
6453
SetKitNode(const RefPtr<Kit::FrameNode> & node)6454 void FrameNode::SetKitNode(const RefPtr<Kit::FrameNode>& node)
6455 {
6456 kitNode_ = node;
6457 }
6458
GetCustomPropertyByKey(const std::string & key,std::string & value)6459 bool FrameNode::GetCustomPropertyByKey(const std::string& key, std::string& value)
6460 {
6461 auto iter = customPropertyMap_.find(key);
6462 if (iter != customPropertyMap_.end() && !iter->second.empty()) {
6463 value = iter->second[0];
6464 return true;
6465 }
6466 return false;
6467 }
6468
AddNodeDestroyCallback(const std::string & callbackKey,std::function<void ()> && callback)6469 void FrameNode::AddNodeDestroyCallback(const std::string& callbackKey, std::function<void()>&& callback)
6470 {
6471 if (!callback) {
6472 return;
6473 }
6474 destroyCallbacks_[callbackKey] = std::move(callback);
6475 }
6476
RemoveNodeDestroyCallback(const std::string & callbackKey)6477 void FrameNode::RemoveNodeDestroyCallback(const std::string& callbackKey)
6478 {
6479 auto iter = destroyCallbacks_.find(callbackKey);
6480 if (iter != destroyCallbacks_.end()) {
6481 destroyCallbacks_.erase(iter);
6482 }
6483 }
6484
FireOnExtraNodeDestroyCallback()6485 void FrameNode::FireOnExtraNodeDestroyCallback()
6486 {
6487 for (const auto& callback : destroyCallbacks_) {
6488 callback.second();
6489 }
6490 }
6491
SetFrameNodeDestructorCallback(const std::function<void (int32_t)> && callback)6492 void FrameNode::SetFrameNodeDestructorCallback(const std::function<void(int32_t)>&& callback)
6493 {
6494 frameNodeDestructorCallback_ = callback;
6495 }
6496
FireFrameNodeDestructorCallback()6497 void FrameNode::FireFrameNodeDestructorCallback()
6498 {
6499 if (frameNodeDestructorCallback_) {
6500 frameNodeDestructorCallback_(GetId());
6501 }
6502 }
6503
GetKitNode() const6504 const RefPtr<Kit::FrameNode>& FrameNode::GetKitNode() const
6505 {
6506 return kitNode_;
6507 }
6508
IsDrawFocusOnTop() const6509 bool FrameNode::IsDrawFocusOnTop() const
6510 {
6511 auto accessibilityProperty = GetAccessibilityProperty<NG::AccessibilityProperty>();
6512 CHECK_NULL_RETURN(accessibilityProperty, false);
6513 return static_cast<FocusDrawLevel>(accessibilityProperty->GetFocusDrawLevel()) == FocusDrawLevel::TOP;
6514 }
6515
AddVisibilityDumpInfo(const std::pair<uint64_t,std::pair<VisibleType,bool>> & dumpInfo)6516 void FrameNode::AddVisibilityDumpInfo(const std::pair<uint64_t, std::pair<VisibleType, bool>>& dumpInfo)
6517 {
6518 if (visibilityDumpInfos_.size() == SIZE_CHANGE_DUMP_SIZE) {
6519 visibilityDumpInfos_.pop_front();
6520 }
6521 visibilityDumpInfos_.push_back(dumpInfo);
6522 }
6523
PrintVisibilityDumpInfo() const6524 std::string FrameNode::PrintVisibilityDumpInfo() const
6525 {
6526 if (visibilityDumpInfos_.empty()) {
6527 return "" ;
6528 }
6529 std::string res = "[ ";
6530 for (auto it = visibilityDumpInfos_.rbegin(); it != visibilityDumpInfos_.rend(); ++it) {
6531 res += ("{" + std::to_string(it->first) + ", " +
6532 std::to_string(static_cast<int32_t>(it->second.first)) + ", " +
6533 std::to_string(static_cast<int32_t>(it->second.second)) + "}, ");
6534 }
6535 res += "]";
6536 return res;
6537 }
6538
HandleAreaChangeDestruct()6539 void FrameNode::HandleAreaChangeDestruct()
6540 {
6541 if (eventHub_) {
6542 eventHub_->ClearOnAreaChangedInnerCallbacks();
6543 if (eventHub_->HasVisibleAreaCallback(true) || eventHub_->HasVisibleAreaCallback(false) ||
6544 eventHub_->HasThrottledVisibleAreaCallback()) {
6545 SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::FRAMENODE_DESTROY);
6546 TriggerVisibleAreaChangeCallback(0, true);
6547 CleanVisibleAreaUserCallback(true);
6548 CleanVisibleAreaUserCallback();
6549 CleanVisibleAreaInnerCallback();
6550 }
6551 }
6552 }
6553 } // namespace OHOS::Ace::NG
6554