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