1 /* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_UI_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_UI_NODE_H 18 19 #include <cstdint> 20 #include <list> 21 #include <memory> 22 #include <string> 23 #include <unordered_map> 24 25 #include "base/geometry/ng/point_t.h" 26 #include "base/geometry/ng/size_t.h" 27 #include "base/log/ace_performance_check.h" 28 #include "base/memory/ace_type.h" 29 #include "base/memory/referenced.h" 30 #include "base/utils/macros.h" 31 #include "base/view_data/view_data_wrap.h" 32 #include "core/common/resource/resource_configuration.h" 33 #include "core/components_ng/event/focus_hub.h" 34 #include "core/components_ng/event/gesture_event_hub.h" 35 #include "core/components_ng/export_texture_info/export_texture_info.h" 36 #include "core/components_ng/layout/layout_wrapper.h" 37 #include "core/components_ng/layout/layout_wrapper_node.h" 38 #include "core/event/touch_event.h" 39 40 namespace OHOS::Ace::NG { 41 42 struct ExtraInfo { 43 std::string page; 44 int32_t line = 0; 45 }; 46 47 enum class NodeStatus : char { 48 NORMAL_NODE = 0, // Indicates it is a normal node; 49 BUILDER_NODE_OFF_MAINTREE = 1, // Indicates it is a BuilderNode and is detach from the maintreee; 50 BUILDER_NODE_ON_MAINTREE = 2 // Indicates it is a BuilderNode and is attach to the maintreee; 51 }; 52 53 class PipelineContext; 54 constexpr int32_t DEFAULT_NODE_SLOT = -1; 55 56 // UINode is the base class of FrameNode and SyntaxNode. 57 class ACE_EXPORT UINode : public virtual AceType { 58 DECLARE_ACE_TYPE(UINode, AceType); 59 60 public: 61 UINode(const std::string& tag, int32_t nodeId, bool isRoot = false); 62 ~UINode() override; 63 64 // atomic node is like button, image, custom node and so on. 65 // In ets UI compiler, the atomic node does not Add Pop function, only have Create function. 66 virtual bool IsAtomicNode() const = 0; 67 68 virtual int32_t FrameCount() const; 69 70 virtual RefPtr<LayoutWrapperNode> CreateLayoutWrapper(bool forceMeasure = false, bool forceLayout = false); 71 72 // Tree operation start. 73 void AddChild(const RefPtr<UINode>& child, int32_t slot = DEFAULT_NODE_SLOT, bool silently = false, 74 bool addDefaultTransition = false); 75 void AddChildAfter(const RefPtr<UINode>& child, const RefPtr<UINode>& siblingNode); 76 77 std::list<RefPtr<UINode>>::iterator RemoveChild(const RefPtr<UINode>& child, bool allowTransition = false); 78 int32_t RemoveChildAndReturnIndex(const RefPtr<UINode>& child); 79 void ReplaceChild(const RefPtr<UINode>& oldNode, const RefPtr<UINode>& newNode); 80 void MovePosition(int32_t slot); 81 void MountToParent(const RefPtr<UINode>& parent, int32_t slot = DEFAULT_NODE_SLOT, bool silently = false, 82 bool addDefaultTransition = false); 83 RefPtr<FrameNode> GetFocusParent() const; 84 RefPtr<FocusHub> GetFirstFocusHubChild() const; 85 void GetFocusChildren(std::list<RefPtr<FrameNode>>& children) const; 86 void Clean(bool cleanDirectly = false, bool allowTransition = false); 87 void RemoveChildAtIndex(int32_t index); 88 RefPtr<UINode> GetChildAtIndex(int32_t index) const; 89 int32_t GetChildIndex(const RefPtr<UINode>& child) const; 90 void AttachToMainTree(bool recursive = false); 91 void DetachFromMainTree(bool recursive = false); 92 void UpdateConfigurationUpdate(const ConfigurationChange& configurationChange); OnConfigurationUpdate(const ConfigurationChange & configurationChange)93 virtual void OnConfigurationUpdate(const ConfigurationChange& configurationChange) {} 94 95 // process offscreen process. 96 void ProcessOffscreenTask(bool recursive = false); 97 98 int32_t TotalChildCount() const; 99 100 // Returns index in the flatten tree structure 101 // of the node with given id and type 102 // Returns std::pair with 103 // boolean first - indication of node is found 104 // int32_t second - index of the node 105 std::pair<bool, int32_t> GetChildFlatIndex(int32_t id); 106 GetChildren()107 virtual const std::list<RefPtr<UINode>>& GetChildren() const 108 { 109 return children_; 110 } 111 GetLastChild()112 RefPtr<UINode> GetLastChild() 113 { 114 if (children_.empty()) { 115 return nullptr; 116 } 117 return children_.back(); 118 } 119 GetFirstChild()120 RefPtr<UINode> GetFirstChild() 121 { 122 if (children_.empty()) { 123 return nullptr; 124 } 125 return children_.front(); 126 } 127 128 void GenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& visibleList); 129 void GenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList); 130 void GenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>>& visibleList); 131 132 int32_t GetChildIndexById(int32_t id); 133 GetParent()134 RefPtr<UINode> GetParent() const 135 { 136 return parent_.Upgrade(); 137 } 138 SetNeedCallChildrenUpdate(bool needCallChildrenUpdate)139 void SetNeedCallChildrenUpdate(bool needCallChildrenUpdate) 140 { 141 needCallChildrenUpdate_ = needCallChildrenUpdate; 142 } 143 SetParent(const WeakPtr<UINode> & parent)144 void SetParent(const WeakPtr<UINode>& parent) 145 { 146 parent_ = parent; 147 } 148 // Tree operation end. 149 150 static RefPtr<PipelineContext> GetContext(); 151 152 // When FrameNode creates a layout task, the corresponding LayoutWrapper tree is created, and UINode needs to update 153 // the corresponding LayoutWrapper tree node at this time like add self wrapper to wrapper tree. 154 virtual void AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode>& parent, bool forceMeasure, bool forceLayout); 155 156 void DumpViewDataPageNodes(RefPtr<ViewDataWrap> viewDataWrap); 157 bool NeedRequestAutoSave(); 158 // DFX info. 159 void DumpTree(int32_t depth); 160 161 bool DumpTreeById(int32_t depth, const std::string& id); 162 GetTag()163 const std::string& GetTag() const 164 { 165 return tag_; 166 } 167 GetId()168 int32_t GetId() const 169 { 170 return nodeId_; 171 } 172 GetAccessibilityId()173 int64_t GetAccessibilityId() const 174 { 175 return accessibilityId_; 176 } 177 SetDepth(int32_t depth)178 void SetDepth(int32_t depth) 179 { 180 depth_ = depth; 181 for (auto& child : children_) { 182 child->SetDepth(depth_ + 1); 183 } 184 } 185 IsRootNode()186 bool IsRootNode() const 187 { 188 return isRoot_; 189 } 190 GetDepth()191 int32_t GetDepth() const 192 { 193 return depth_; 194 } 195 GetRootId()196 int32_t GetRootId() const 197 { 198 return hostRootId_; 199 } 200 GetPageId()201 int32_t GetPageId() const 202 { 203 return hostPageId_; 204 } 205 206 // TODO: SetHostRootId step on create node. SetHostRootId(int32_t id)207 void SetHostRootId(int32_t id) 208 { 209 hostRootId_ = id; 210 } 211 212 // TODO: SetHostPageId step on mount to page. SetHostPageId(int32_t id)213 void SetHostPageId(int32_t id) 214 { 215 hostPageId_ = id; 216 for (auto& child : children_) { 217 child->SetHostPageId(id); 218 } 219 } 220 SetRemoveSilently(bool removeSilently)221 void SetRemoveSilently(bool removeSilently) 222 { 223 removeSilently_ = removeSilently; 224 } 225 SetUndefinedNodeId()226 void SetUndefinedNodeId() 227 { 228 nodeId_ = -1; 229 } 230 IsRemoving()231 bool IsRemoving() const 232 { 233 return isRemoving_; 234 } 235 GetLayoutPriority()236 int32_t GetLayoutPriority() const 237 { 238 return layoutPriority_; 239 } 240 SetLayoutPriority(int32_t priority)241 void SetLayoutPriority(int32_t priority) 242 { 243 layoutPriority_ = priority; 244 } 245 SetInDestroying()246 void SetInDestroying() 247 { 248 isInDestroying_ = true; 249 } 250 IsInDestroying()251 bool IsInDestroying() const 252 { 253 return isInDestroying_; 254 } 255 256 void SetChildrenInDestroying(); 257 258 virtual HitTestResult TouchTest(const PointF& globalPoint, const PointF& parentLocalPoint, 259 const PointF& parentRevertPoint, TouchRestrict& touchRestrict, TouchTestResult& result, int32_t touchId, 260 bool isDispatch = false); GetHitTestMode()261 virtual HitTestMode GetHitTestMode() const 262 { 263 return HitTestMode::HTMDEFAULT; 264 } 265 266 virtual HitTestResult MouseTest(const PointF& globalPoint, const PointF& parentLocalPoint, 267 MouseTestResult& onMouseResult, MouseTestResult& onHoverResult, RefPtr<FrameNode>& hoverNode); 268 269 virtual HitTestResult AxisTest( 270 const PointF& globalPoint, const PointF& parentLocalPoint, AxisTestResult& onAxisResult); 271 272 // In the request to re-layout the scene, needs to obtain the changed state of the child node for the creation 273 // of parent's layout wrapper 274 virtual void UpdateLayoutPropertyFlag(); 275 ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag)276 virtual void ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag) {} 277 278 virtual void AdjustParentLayoutFlag(PropertyChangeFlag& flag); 279 280 virtual void MarkDirtyNode( 281 PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL, bool childExpansiveAndMark = false); 282 283 virtual void MarkNeedFrameFlushDirty(PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL); 284 FlushUpdateAndMarkDirty()285 virtual void FlushUpdateAndMarkDirty() 286 { 287 for (const auto& child : children_) { 288 child->FlushUpdateAndMarkDirty(); 289 } 290 } 291 292 virtual void MarkNeedSyncRenderTree(bool needRebuild = false); 293 294 virtual void RebuildRenderContextTree(); 295 OnWindowShow()296 virtual void OnWindowShow() {} 297 OnWindowHide()298 virtual void OnWindowHide() {} 299 virtual void Build(std::shared_ptr<std::list<ExtraInfo>> extraInfos); 300 301 virtual bool RenderCustomChild(int64_t deadline); 302 OnWindowFocused()303 virtual void OnWindowFocused() {} 304 OnWindowUnfocused()305 virtual void OnWindowUnfocused() {} 306 OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)307 virtual void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) {} 308 OnNotifyMemoryLevel(int32_t level)309 virtual void OnNotifyMemoryLevel(int32_t level) {} 310 311 virtual void SetActive(bool active); 312 313 virtual void SetJSViewActive(bool active); 314 315 virtual void OnVisibleChange(bool isVisible); 316 317 virtual bool MarkRemoving(); 318 IsOnMainTree()319 bool IsOnMainTree() const 320 { 321 return onMainTree_; 322 } 323 UseOffscreenProcess()324 bool UseOffscreenProcess() const 325 { 326 return useOffscreenProcess_; 327 } 328 ToJsonValue(std::unique_ptr<JsonValue> & json)329 virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const {} 330 FromJson(const std::unique_ptr<JsonValue> & json)331 virtual void FromJson(const std::unique_ptr<JsonValue>& json) {} 332 333 ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(InspectorId, std::string); OnInspectorIdUpdate(const std::string &)334 virtual void OnInspectorIdUpdate(const std::string& /*unused*/) {} 335 336 ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(AutoEventParam, std::string); OnAutoEventParamUpdate(const std::string &)337 virtual void OnAutoEventParamUpdate(const std::string& /*unused*/) {} 338 339 template<typename T> FindChildNodeOfClass()340 RefPtr<T> FindChildNodeOfClass() 341 { 342 const auto& children = GetChildren(); 343 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { 344 auto& child = *iter; 345 346 auto target = child->FindChildNodeOfClass<T>(); 347 if (target) { 348 return target; 349 } 350 } 351 352 RefPtr<UINode> uiNode = AceType::Claim<UINode>(this); 353 if (AceType::InstanceOf<T>(uiNode)) { 354 return AceType::DynamicCast<T>(uiNode); 355 } 356 return nullptr; 357 } 358 359 void ChildrenUpdatedFrom(int32_t index); GetChildrenUpdated()360 int32_t GetChildrenUpdated() const 361 { 362 return childrenUpdatedFrom_; 363 } 364 365 // utility function for adding child to disappearingChildren_ 366 void AddDisappearingChild(const RefPtr<UINode>& child, uint32_t index = UINT32_MAX); 367 // utility function for removing child from disappearingChildren_, return true if child is removed 368 bool RemoveDisappearingChild(const RefPtr<UINode>& child); 369 // return if we are in parent's disappearing children IsDisappearing()370 bool IsDisappearing() const 371 { 372 return isDisappearing_; 373 } 374 RefPtr<UINode> GetDisappearingChildById(const std::string& id) const; 375 376 // These two interfaces are only used for fast preview. 377 // FastPreviewUpdateChild: Replace the old child at the specified slot with the new created node. 378 // FastPreviewUpdateChildDone: the new created node performs some special operations. FastPreviewUpdateChild(int32_t slot,const RefPtr<UINode> & newChild)379 virtual void FastPreviewUpdateChild(int32_t slot, const RefPtr<UINode>& newChild) 380 { 381 RemoveChildAtIndex(slot); 382 newChild->MountToParent(AceType::Claim(this), slot, false); 383 } FastPreviewUpdateChildDone()384 virtual void FastPreviewUpdateChildDone() {} 385 virtual RefPtr<UINode> GetFrameChildByIndex(uint32_t index, bool needBuild); 386 SetDebugLine(const std::string & line)387 void SetDebugLine(const std::string& line) 388 { 389 debugLine_ = line; 390 } GetDebugLine()391 std::string GetDebugLine() const 392 { 393 return debugLine_; 394 } 395 SetViewId(const std::string & viewId)396 void SetViewId(const std::string& viewId) 397 { 398 viewId_ = viewId; 399 } 400 GetViewId()401 std::string GetViewId() const 402 { 403 return viewId_; 404 } 405 SetRestoreId(int32_t restoreId)406 void SetRestoreId(int32_t restoreId) 407 { 408 restoreId_ = restoreId; 409 } 410 GetRestoreId()411 int32_t GetRestoreId() 412 { 413 return restoreId_; 414 } 415 UpdateRecycleElmtId(int32_t newElmtId)416 void UpdateRecycleElmtId(int32_t newElmtId) 417 { 418 nodeId_ = newElmtId; 419 } 420 421 // -------------------------------------------------------------------------------- 422 // performance check get child count, depth, flex layout times and layout time 423 void GetPerformanceCheckData(PerformanceCheckNodeMap& nodeMap); SetLayoutTime(int64_t time)424 void SetLayoutTime(int64_t time) 425 { 426 if (nodeInfo_) { 427 nodeInfo_->layoutTime = time; 428 } 429 } GetLayoutTime()430 int64_t GetLayoutTime() 431 { 432 if (nodeInfo_) { 433 return nodeInfo_->layoutTime; 434 } 435 return 0; 436 } GetFlexLayouts()437 int32_t GetFlexLayouts() 438 { 439 if (nodeInfo_) { 440 return nodeInfo_->flexLayouts; 441 } 442 return 0; 443 } GetRow()444 int32_t GetRow() const 445 { 446 if (nodeInfo_) { 447 return nodeInfo_->codeRow; 448 } 449 return 0; 450 } GetCol()451 int32_t GetCol() const 452 { 453 if (nodeInfo_) { 454 return nodeInfo_->codeCol; 455 } 456 return 0; 457 } SetRow(const int32_t row)458 void SetRow(const int32_t row) 459 { 460 if (nodeInfo_) { 461 nodeInfo_->codeRow = row; 462 } 463 } SetCol(const int32_t col)464 void SetCol(const int32_t col) 465 { 466 if (nodeInfo_) { 467 nodeInfo_->codeCol = col; 468 } 469 } SetForeachItem()470 void SetForeachItem() 471 { 472 if (nodeInfo_) { 473 nodeInfo_->isForEachItem = true; 474 } 475 } AddFlexLayouts()476 void AddFlexLayouts() 477 { 478 if (nodeInfo_) { 479 nodeInfo_->flexLayouts++; 480 } 481 } GetCustomTag()482 virtual std::string GetCustomTag() 483 { 484 return GetTag(); 485 } SetBuildByJs(bool isBuildByJS)486 void SetBuildByJs(bool isBuildByJS) 487 { 488 isBuildByJS_ = isBuildByJS; 489 } AddAttachToMainTreeTask(std::function<void ()> && func)490 void AddAttachToMainTreeTask(std::function<void()>&& func) 491 { 492 attachToMainTreeTasks_.emplace_back(std::move(func)); 493 } 494 495 // -------------------------------------------------------------------------------- 496 497 virtual void DoRemoveChildInRenderTree(uint32_t index, bool isAll = false); 498 virtual void DoSetActiveChildRange(int32_t start, int32_t end); 499 virtual void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint); 500 501 // return value: true if the node can be removed immediately. 502 virtual bool OnRemoveFromParent(bool allowTransition); 503 MarkForceMeasure()504 void MarkForceMeasure() 505 { 506 MarkDirtyNode(PROPERTY_UPDATE_MEASURE); 507 for (const auto& child : children_) { 508 child->MarkForceMeasure(); 509 } 510 } 511 512 std::string GetCurrentCustomNodeInfo(); 513 static int64_t GenerateAccessibilityId(); 514 515 NodeStatus GetNodeStatus() const; 516 void UpdateNodeStatus(NodeStatus nodeStatus); 517 GetExportTextureInfo()518 const RefPtr<ExportTextureInfo>& GetExportTextureInfo() const 519 { 520 return exportTextureInfo_; 521 } 522 523 void CreateExportTextureInfoIfNeeded(); 524 525 bool IsNeedExportTexture() const; 526 527 virtual bool SetParentLayoutConstraint(const SizeF& size) const; 528 529 protected: ModifyChildren()530 std::list<RefPtr<UINode>>& ModifyChildren() 531 { 532 return children_; 533 } 534 OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>> & visibleList)535 virtual void OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& visibleList) 536 { 537 for (const auto& child : GetChildren()) { 538 child->OnGenerateOneDepthVisibleFrame(visibleList); 539 } 540 } 541 542 virtual void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList); 543 OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>> & allList)544 virtual void OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>>& allList) 545 { 546 for (const auto& child : GetChildren()) { 547 child->OnGenerateOneDepthAllFrame(allList); 548 } 549 } 550 OnContextAttached()551 virtual void OnContextAttached() {} 552 // dump self info. DumpInfo()553 virtual void DumpInfo() {} DumpAdvanceInfo()554 virtual void DumpAdvanceInfo() {} DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap)555 virtual void DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap) {} CheckAutoSave()556 virtual bool CheckAutoSave() 557 { 558 return false; 559 } 560 // Mount to the main tree to display. 561 virtual void OnAttachToMainTree(bool recursive = false); 562 virtual void OnDetachFromMainTree(bool recursive = false); OnAttachToBuilderNode(NodeStatus nodeStatus)563 virtual void OnAttachToBuilderNode(NodeStatus nodeStatus) {} 564 // run offscreen process. OnOffscreenProcess(bool recursive)565 virtual void OnOffscreenProcess(bool recursive) {} 566 567 bool isRemoving_ = false; 568 569 virtual bool RemoveImmediately() const; 570 void ResetParent(); 571 572 // update visible change signal to children 573 void UpdateChildrenVisible(bool isVisible) const; 574 575 protected: 576 bool needCallChildrenUpdate_ = true; 577 578 private: 579 void DoAddChild(std::list<RefPtr<UINode>>::iterator& it, const RefPtr<UINode>& child, bool silently = false, 580 bool addDefaultTransition = false); 581 582 std::list<RefPtr<UINode>> children_; 583 std::list<std::pair<RefPtr<UINode>, uint32_t>> disappearingChildren_; 584 std::unique_ptr<PerformanceCheckNode> nodeInfo_; 585 WeakPtr<UINode> parent_; 586 std::string tag_ = "UINode"; 587 int32_t depth_ = 0; 588 int32_t hostRootId_ = 0; 589 int32_t hostPageId_ = 0; 590 int32_t nodeId_ = 0; 591 int64_t accessibilityId_ = -1; 592 int32_t layoutPriority_ = 0; 593 bool isRoot_ = false; 594 bool onMainTree_ = false; 595 bool removeSilently_ = true; 596 bool isInDestroying_ = false; 597 bool isDisappearing_ = false; 598 bool isBuildByJS_ = false; 599 NodeStatus nodeStatus_ = NodeStatus::NORMAL_NODE; 600 RefPtr<ExportTextureInfo> exportTextureInfo_; 601 602 int32_t childrenUpdatedFrom_ = -1; 603 static thread_local int64_t currentAccessibilityId_; 604 int32_t restoreId_ = -1; 605 606 bool useOffscreenProcess_ = false; 607 608 std::list<std::function<void()>> attachToMainTreeTasks_; 609 610 std::string debugLine_; 611 std::string viewId_; 612 613 friend class RosenRenderContext; 614 ACE_DISALLOW_COPY_AND_MOVE(UINode); 615 }; 616 617 } // namespace OHOS::Ace::NG 618 619 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_UI_NODE_H 620