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