• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "core/components_ng/pattern/node_container/node_container_pattern.h"
17 
18 #include "core/common/builder_util.h"
19 #include "core/pipeline_ng/pipeline_context.h"
20 #include "core/pipeline/base/element_register.h"
21 
22 namespace OHOS::Ace::NG {
23 namespace {
CheckBeforeAddNode(const RefPtr<UINode> & hostNode,const RefPtr<UINode> & newNode)24 bool CheckBeforeAddNode(const RefPtr<UINode>& hostNode, const RefPtr<UINode>& newNode)
25 {
26     CHECK_NULL_RETURN(hostNode, false);
27     CHECK_NULL_RETURN(newNode, true);
28     if (!(newNode->IsArkTsFrameNode()) && !newNode->GetIsRootBuilderNode()) {
29         TAG_LOGW(AceLogTag::ACE_NODE_CONTAINER, "Cannot return node created by declarative UI function");
30         return false;
31     }
32     auto parent = newNode->GetParent();
33     if (parent && parent != hostNode) {
34         TAG_LOGF(AceLogTag::ACE_NODE_CONTAINER,
35             "Add [id:%{public}d][tag:%{public}s] to [id:%{public}d][tag:%{public}s] with previous parent "
36             "[id:%{public}d][tag:%{public}s]",
37             newNode->GetId(), newNode->GetTag().c_str(), hostNode->GetId(), hostNode->GetTag().c_str(), parent->GetId(),
38             parent->GetTag().c_str());
39     }
40     return true;
41 }
42 } // namespace
43 
RemakeNode()44 void NodeContainerPattern::RemakeNode()
45 {
46     auto host = GetHost();
47     CHECK_NULL_VOID(host);
48     auto newNode = FireMakeFunction();
49     AddBaseNode(newNode);
50 }
51 
AddBaseNode(const RefPtr<UINode> & newNode)52 void NodeContainerPattern::AddBaseNode(const RefPtr<UINode>& newNode)
53 {
54     auto host = GetHost();
55     CHECK_NULL_VOID(host);
56     auto oldChild = host->GetChildAtIndex(0);
57     if ((!oldChild && !newNode) || (oldChild && oldChild == newNode)) {
58         return;
59     }
60     host->RemoveChildAtIndex(0);
61     BuilderUtils::RemoveBuilderFromParent(host, oldChild);
62     if (newNode) {
63         CHECK_NULL_VOID(CheckBeforeAddNode(host, newNode));
64         host->AddChild(newNode, 0);
65         BuilderUtils::AddBuilderToParent(host, newNode);
66         newNode->UpdateGeometryTransition();
67     }
68     OnAddBaseNode();
69     host->MarkNeedFrameFlushDirty(NG::PROPERTY_UPDATE_MEASURE);
70 }
71 
CleanChild()72 void NodeContainerPattern::CleanChild()
73 {
74     auto host = GetHost();
75     CHECK_NULL_VOID(host);
76     host->RemoveChildAtIndex(0);
77     host->MarkNeedFrameFlushDirty(NG::PROPERTY_UPDATE_MEASURE);
78 }
79 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)80 bool NodeContainerPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
81 {
82     if (config.skipMeasure && config.skipLayout) {
83         return false;
84     }
85     auto host = GetHost();
86     CHECK_NULL_RETURN(host, false);
87     auto context = host->GetContext();
88     CHECK_NULL_RETURN(context, false);
89     if (config.frameSizeChange) {
90         auto geometryNode = dirty->GetGeometryNode();
91         auto size = geometryNode->GetFrameSize();
92         context->AddAfterLayoutTask([weak = WeakClaim(this), size]() {
93             auto pattern = weak.Upgrade();
94             CHECK_NULL_VOID(pattern);
95             pattern->FireOnResize(size);
96         });
97     }
98     if (surfaceId_ != 0U && !exportTextureNode_.Invalid()) {
99         context->AddAfterLayoutTask([weak = WeakClaim(this)]() {
100             auto pattern = weak.Upgrade();
101             CHECK_NULL_VOID(pattern);
102             auto host = pattern->GetHost();
103             auto ret = pattern->HandleTextureExport(false, Referenced::RawPtr(host));
104             if (!ret) {
105                 TAG_LOGW(AceLogTag::ACE_NODE_CONTAINER, "DoTextureExport fail");
106             }
107         });
108     }
109     return false;
110 }
111 
HandleTextureExport(bool isStop,FrameNode * frameNode)112 bool NodeContainerPattern::HandleTextureExport(bool isStop, FrameNode* frameNode)
113 {
114     auto exportTextureNode = GetExportTextureNode();
115     CHECK_NULL_RETURN(exportTextureNode, false);
116     auto exportTextureRenderContext = exportTextureNode->GetRenderContext();
117     CHECK_NULL_RETURN(exportTextureRenderContext, false);
118     if (frameNode) {
119         auto renderContext = frameNode->GetRenderContext();
120         CHECK_NULL_RETURN(renderContext, false);
121         renderContext->SetIsNeedRebuildRSTree(isStop);
122     }
123     auto elementRegister = ElementRegister::GetInstance();
124     if (isStop) {
125         if (elementRegister) {
126             elementRegister->UnregisterEmbedNode(surfaceId_, WeakPtr(exportTextureNode));
127         }
128         return exportTextureRenderContext->StopTextureExport();
129     }
130     if (elementRegister) {
131         elementRegister->RegisterEmbedNode(surfaceId_, WeakPtr(exportTextureNode));
132     }
133     return exportTextureRenderContext->DoTextureExport(surfaceId_);
134 }
135 
OnDetachFromFrameNode(FrameNode * frameNode)136 void NodeContainerPattern::OnDetachFromFrameNode(FrameNode* frameNode)
137 {
138     HandleTextureExport(true, frameNode);
139 }
140 
GetExportTextureNode() const141 RefPtr<FrameNode> NodeContainerPattern::GetExportTextureNode() const
142 {
143     auto exportTextureNode = exportTextureNode_.Upgrade();
144     CHECK_NULL_RETURN(exportTextureNode, nullptr);
145     auto exportTextureFrameNode = DynamicCast<FrameNode>(exportTextureNode);
146     while (exportTextureNode && !exportTextureFrameNode) {
147         exportTextureNode = exportTextureNode->GetFirstChild();
148         exportTextureFrameNode = DynamicCast<FrameNode>(exportTextureNode);
149     }
150     return exportTextureFrameNode;
151 }
152 
ResetExportTextureInfo()153 void NodeContainerPattern::ResetExportTextureInfo()
154 {
155     surfaceId_ = 0U;
156     exportTextureNode_.Reset();
157 }
158 
SetExportTextureInfoIfNeeded()159 void NodeContainerPattern::SetExportTextureInfoIfNeeded()
160 {
161     ResetExportTextureInfo();
162     auto host = GetHost();
163     CHECK_NULL_VOID(host);
164     auto viewNode = host->GetChildAtIndex(0);
165     CHECK_NULL_VOID(viewNode);
166     if (!viewNode->IsNeedExportTexture()) {
167         return;
168     }
169     auto parent = host->GetAncestorNodeOfFrame(false);
170     if (parent) {
171         auto nodeContainer = parent->GetNodeContainer();
172         if (nodeContainer) {
173             auto parentViewNode = nodeContainer->GetChildAtIndex(0);
174             CHECK_NULL_VOID(parentViewNode);
175             auto parnetExportTextureInfo = parentViewNode->GetExportTextureInfo();
176             if (parnetExportTextureInfo &&
177                 parnetExportTextureInfo->GetCurrentRenderType() == NodeRenderType::RENDER_TYPE_TEXTURE) {
178                 return;
179             }
180         }
181     }
182     auto exportTextureInfo = viewNode->GetExportTextureInfo();
183     exportTextureNode_ = viewNode;
184     surfaceId_ = StringUtils::StringToLongUint(exportTextureInfo->GetSurfaceId());
185 }
186 
OnAddBaseNode()187 void NodeContainerPattern::OnAddBaseNode()
188 {
189     auto host = GetHost();
190     HandleTextureExport(true, Referenced::RawPtr(host));
191     SetExportTextureInfoIfNeeded();
192 }
193 
OnMountToParentDone()194 void NodeContainerPattern::OnMountToParentDone()
195 {
196     SetExportTextureInfoIfNeeded();
197 }
198 
GetNodeContainerEventHub()199 RefPtr<NodeContainerEventHub> NodeContainerPattern::GetNodeContainerEventHub()
200 {
201     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
202     if (frameNode) {
203         return frameNode->GetOrCreateEventHub<NodeContainerEventHub>();
204     }
205     return nullptr;
206 }
207 
FireOnWillBind(int32_t containerId)208 void NodeContainerPattern::FireOnWillBind(int32_t containerId)
209 {
210     auto nodeContainerEventHub = GetNodeContainerEventHub();
211     if (nodeContainerEventHub) {
212         nodeContainerEventHub->FireOnWillBind(containerId);
213     }
214 }
215 
FireOnWillUnbind(int32_t containerId)216 void NodeContainerPattern::FireOnWillUnbind(int32_t containerId)
217 {
218     auto nodeContainerEventHub = GetNodeContainerEventHub();
219     if (nodeContainerEventHub) {
220         nodeContainerEventHub->FireOnWillUnbind(containerId);
221     }
222 }
223 
FireOnBind(int32_t containerId)224 void NodeContainerPattern::FireOnBind(int32_t containerId)
225 {
226     auto nodeContainerEventHub = GetNodeContainerEventHub();
227     if (nodeContainerEventHub) {
228         nodeContainerEventHub->FireOnBind(containerId);
229     }
230 }
231 
FireOnUnbind(int32_t containerId)232 void NodeContainerPattern::FireOnUnbind(int32_t containerId)
233 {
234     auto nodeContainerEventHub = GetNodeContainerEventHub();
235     if (nodeContainerEventHub) {
236         nodeContainerEventHub->FireOnUnbind(containerId);
237     }
238 }
239 } // namespace OHOS::Ace::NG
240