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