• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/layout/layout_wrapper.h"
17 
18 #include <algorithm>
19 
20 #include "base/log/ace_checker.h"
21 #include "base/utils/utils.h"
22 #include "core/common/container.h"
23 #include "core/components/common/properties/alignment.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/layout/layout_property.h"
26 #include "core/components_ng/layout/layout_wrapper_builder.h"
27 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
28 #include "core/components_ng/property/layout_constraint.h"
29 #include "core/components_ng/property/measure_property.h"
30 #include "core/components_ng/property/property.h"
31 #include "core/components_ng/property/safe_area_insets.h"
32 #include "core/components_v2/inspector/inspector_constants.h"
33 #include "core/pipeline_ng/pipeline_context.h"
34 
35 namespace OHOS::Ace::NG {
36 namespace {
IsSyntaxNode(const std::string & tag)37 bool IsSyntaxNode(const std::string& tag)
38 {
39     return tag == V2::JS_VIEW_ETS_TAG || tag == V2::JS_IF_ELSE_ETS_TAG || tag == V2::JS_FOR_EACH_ETS_TAG ||
40            tag == V2::JS_LAZY_FOR_EACH_ETS_TAG || tag == V2::JS_SYNTAX_ITEM_ETS_TAG || tag == V2::JS_NODE_SLOT_ETS_TAG;
41 }
42 } // namespace
43 
SkipMeasureContent() const44 bool LayoutWrapper::SkipMeasureContent() const
45 {
46     return skipMeasureContent_ == true;
47 }
48 
ApplySafeArea(const SafeAreaInsets & insets,LayoutConstraintF & constraint)49 void LayoutWrapper::ApplySafeArea(const SafeAreaInsets& insets, LayoutConstraintF& constraint)
50 {
51     ACE_SCOPED_TRACE(
52         "ApplySafeArea: SafeAreaInsets: %s to constraint %s", insets.ToString().c_str(), constraint.ToString().c_str());
53     constraint.MinusPadding(
54         insets.left_.Length(), insets.right_.Length(), insets.top_.Length(), insets.bottom_.Length());
55 }
56 
OffsetNodeToSafeArea()57 void LayoutWrapper::OffsetNodeToSafeArea()
58 {
59     auto&& insets = GetLayoutProperty()->GetSafeAreaInsets();
60     CHECK_NULL_VOID(insets);
61     auto geometryNode = GetGeometryNode();
62     auto offset = geometryNode->GetMarginFrameOffset();
63     if (offset.GetX() < insets->left_.end) {
64         offset.SetX(insets->left_.end);
65     }
66     if (offset.GetY() < insets->top_.end) {
67         offset.SetY(insets->top_.end);
68     }
69 
70     auto right = offset.GetX() + geometryNode->GetMarginFrameSize().Width();
71     auto rightBound = insets->right_.IsValid() ? insets->right_.start : PipelineContext::GetCurrentRootWidth();
72     if (right > rightBound) {
73         offset.SetX(rightBound - geometryNode->GetMarginFrameSize().Width());
74     }
75     auto bottomBound = insets->bottom_.IsValid() ? insets->bottom_.start : PipelineContext::GetCurrentRootHeight();
76     auto bottom = offset.GetY() + geometryNode->GetMarginFrameSize().Height();
77     if (bottom > bottomBound) {
78         offset.SetY(bottomBound - geometryNode->GetMarginFrameSize().Height());
79     }
80     geometryNode->SetMarginFrameOffset(offset);
81 }
82 
AvoidKeyboard(bool isFocusOnPage)83 bool LayoutWrapper::AvoidKeyboard(bool isFocusOnPage)
84 {
85     auto host = GetHostNode();
86     CHECK_NULL_RETURN(host, false);
87     auto pipeline = host->GetContext();
88     CHECK_NULL_RETURN(pipeline, false);
89     auto manager = pipeline->GetSafeAreaManager();
90     bool isFocusOnOverlay = pipeline->CheckOverlayFocus();
91     bool isNeedAvoidKeyboard = manager->CheckPageNeedAvoidKeyboard(GetHostNode());
92     // apply keyboard avoidance on Page or Overlay
93     if ((GetHostTag() == V2::PAGE_ETS_TAG && isNeedAvoidKeyboard && !isFocusOnOverlay) ||
94         GetHostTag() == V2::OVERLAY_ETS_TAG) {
95         CHECK_NULL_RETURN(IsActive(), false);
96         auto renderContext = GetHostNode()->GetRenderContext();
97         CHECK_NULL_RETURN(renderContext, false);
98         auto safeArea = manager->GetSafeArea();
99         auto pageCurrentOffset = GetPageCurrentOffset();
100         auto pageHasOffset = LessNotEqual(pageCurrentOffset, 0.0f);
101         if (!(isFocusOnPage || isFocusOnOverlay || pageHasOffset) && LessNotEqual(manager->GetKeyboardOffset(), 0.0)) {
102             renderContext->SavePaintRect(true, GetLayoutProperty()->GetPixelRound());
103             return false;
104         }
105         auto geometryNode = GetGeometryNode();
106         auto x = geometryNode->GetFrameOffset().GetX();
107         if (manager->IsAtomicService()) {
108             auto usingRect = RectF(OffsetF(x, manager->GetKeyboardOffset()), geometryNode->GetFrameSize());
109             renderContext->UpdatePaintRect(usingRect);
110             geometryNode->SetSelfAdjust(usingRect - geometryNode->GetFrameRect());
111             renderContext->SyncPartialRsProperties();
112             return true;
113         }
114         auto usingRect =
115             RectF(OffsetF(x, safeArea.top_.Length() + manager->GetKeyboardOffset()), geometryNode->GetFrameSize());
116         renderContext->UpdatePaintRect(usingRect);
117         geometryNode->SetSelfAdjust(usingRect - geometryNode->GetFrameRect());
118         renderContext->SyncPartialRsProperties();
119         return true;
120     }
121     return false;
122 }
123 
CheckValidSafeArea()124 bool LayoutWrapper::CheckValidSafeArea()
125 {
126     auto host = GetHostNode();
127     CHECK_NULL_RETURN(host, false);
128     auto pipeline = host->GetContext();
129     CHECK_NULL_RETURN(pipeline, false);
130     auto safeAreaManager = pipeline->GetSafeAreaManager();
131     CHECK_NULL_RETURN(safeAreaManager, false);
132     SafeAreaInsets safeArea;
133     auto&& opts = GetLayoutProperty()->GetSafeAreaExpandOpts();
134     // if self does not have opts, check parent's
135     if (!opts) {
136         auto parent = host->GetAncestorNodeOfFrame();
137         CHECK_NULL_RETURN(parent, false);
138         CHECK_NULL_RETURN(parent->GetLayoutProperty(), false);
139         auto&& parentOpts = parent->GetLayoutProperty()->GetSafeAreaExpandOpts();
140         CHECK_NULL_RETURN(parentOpts, false);
141         safeArea = safeAreaManager->GetCombinedSafeArea(*parentOpts);
142     } else {
143         safeArea = safeAreaManager->GetCombinedSafeArea(*opts);
144     }
145     return safeArea.IsValid();
146 }
147 
GetParentGlobalOffsetWithSafeArea(bool checkBoundary,bool checkPosition) const148 OffsetF LayoutWrapper::GetParentGlobalOffsetWithSafeArea(bool checkBoundary, bool checkPosition) const
149 {
150     OffsetF offset {};
151     auto host = GetHostNode();
152     CHECK_NULL_RETURN(host, offset);
153     auto parent = host->GetAncestorNodeOfFrame(checkBoundary);
154     while (parent) {
155         auto parentRenderContext = parent->GetRenderContext();
156         if (checkPosition && parentRenderContext && parentRenderContext->GetPositionProperty() && parentRenderContext->GetPositionProperty()->HasPosition()) {
157             auto parentLayoutProp = parent->GetLayoutProperty();
158             CHECK_NULL_RETURN(parentLayoutProp, offset);
159             auto parentLayoutConstraint = parentLayoutProp->GetLayoutConstraint();
160             CHECK_NULL_RETURN(parentLayoutConstraint.has_value(), offset);
161             auto renderPosition =
162                 FrameNode::ContextPositionConvertToPX(parentRenderContext, parentLayoutConstraint.value().percentReference);
163             offset += OffsetF(static_cast<float>(renderPosition.first), static_cast<float>(renderPosition.second));
164         } else {
165             offset += parent->GetFrameRectWithSafeArea().GetOffset();
166         }
167         parent = parent->GetAncestorNodeOfFrame(checkBoundary);
168     }
169     return offset;
170 }
171 
GetFrameRectWithoutSafeArea() const172 RectF LayoutWrapper::GetFrameRectWithoutSafeArea() const
173 {
174     auto geometryNode = GetGeometryNode();
175     CHECK_NULL_RETURN(geometryNode, RectF());
176     return geometryNode->GetFrameRect();
177 }
178 
GetFrameRectWithSafeArea(bool checkPosition) const179 RectF LayoutWrapper::GetFrameRectWithSafeArea(bool checkPosition) const
180 {
181     auto geometryNode = GetGeometryNode();
182     CHECK_NULL_RETURN(geometryNode, RectF());
183     RectF rect {};
184     auto host = GetHostNode();
185     CHECK_NULL_RETURN(host, rect);
186     auto renderContext = host->GetRenderContext();
187     if (checkPosition && renderContext && renderContext->GetPositionProperty() &&
188         renderContext->GetPositionProperty()->HasPosition()) {
189         auto layoutProp = host->GetLayoutProperty();
190         CHECK_NULL_RETURN(layoutProp, rect);
191         auto layoutConstraint = layoutProp->GetLayoutConstraint();
192         CHECK_NULL_RETURN(layoutConstraint.has_value(), rect);
193         auto renderPosition = FrameNode::ContextPositionConvertToPX(
194             renderContext, layoutConstraint.value().percentReference);
195         auto size = (geometryNode->GetSelfAdjust() + geometryNode->GetFrameRect()).GetSize();
196         rect = RectF(OffsetF(static_cast<float>(renderPosition.first),
197             static_cast<float>(renderPosition.second)), size);
198         return rect;
199     }
200     return geometryNode->GetSelfAdjust() + geometryNode->GetFrameRect();
201 }
202 
AdjustNotExpandNode()203 void LayoutWrapper::AdjustNotExpandNode()
204 {
205     auto host = GetHostNode();
206     CHECK_NULL_VOID(host);
207     auto pipeline = host->GetContext();
208     CHECK_NULL_VOID(pipeline);
209     auto safeAreaManager = pipeline->GetSafeAreaManager();
210     CHECK_NULL_VOID(safeAreaManager);
211     auto parent = host->GetAncestorNodeOfFrame();
212     auto renderContext = host->GetRenderContext();
213     CHECK_NULL_VOID(renderContext);
214     auto geometryNode = GetGeometryNode();
215     CHECK_NULL_VOID(geometryNode);
216     auto adjustedRect = geometryNode->GetFrameRect();
217     if (safeAreaManager->IsSafeAreaValid()) {
218         adjustedRect += geometryNode->GetParentAdjust();
219     }
220     geometryNode->SetSelfAdjust(adjustedRect - geometryNode->GetFrameRect());
221     renderContext->UpdatePaintRect(
222         adjustedRect + geometryNode->GetPixelGridRoundRect() - geometryNode->GetFrameRect());
223 }
224 
ExpandSafeArea()225 void LayoutWrapper::ExpandSafeArea()
226 {
227     auto host = GetHostNode();
228     CHECK_NULL_VOID(host);
229     auto pipeline = host->GetContext();
230     CHECK_NULL_VOID(pipeline);
231     auto safeAreaManager = pipeline->GetSafeAreaManager();
232     CHECK_NULL_VOID(safeAreaManager);
233     auto&& opts = GetLayoutProperty()->GetSafeAreaExpandOpts();
234     auto selfExpansive = host->SelfExpansive();
235     if (!selfExpansive) {
236         AdjustNotExpandNode();
237         return;
238     }
239     CHECK_NULL_VOID(selfExpansive);
240     opts->switchToNone = false;
241     auto geometryNode = GetGeometryNode();
242     CHECK_NULL_VOID(geometryNode);
243     OffsetF keyboardAdjust;
244     if ((opts->edges & SAFE_AREA_EDGE_BOTTOM) && (opts->type & SAFE_AREA_TYPE_KEYBOARD)) {
245         keyboardAdjust = ExpandIntoKeyboard();
246     }
247 
248     // get frame in global offset
249     auto parentGlobalOffset = GetParentGlobalOffsetWithSafeArea();
250     auto parentAdjust = geometryNode->GetParentAdjust();
251     if (!safeAreaManager->IsSafeAreaValid()) {
252         parentAdjust = RectF();
253     }
254     auto frame = geometryNode->GetFrameRect() + parentGlobalOffset + keyboardAdjust + parentAdjust.GetOffset();
255     auto originGlobal = frame;
256 
257     ExpandHelper(opts, frame);
258 
259     AdjustFixedSizeNode(frame);
260     auto parent = host->GetAncestorNodeOfFrame();
261     auto parentScrollable = (parent && parent->GetPattern<ScrollablePattern>());
262     // restore to local offset
263     auto diff = originGlobal.GetOffset() - frame.GetOffset();
264     frame -= parentGlobalOffset;
265     // since adjustment is not accumulated and we did not track previous diff, diff need to be updated
266     AdjustChildren(diff, parentScrollable);
267 
268     if (parentScrollable) {
269         AdjustNotExpandNode();
270         return;
271     }
272     auto selfAdjust = frame - geometryNode->GetFrameRect();
273     geometryNode->SetSelfAdjust(selfAdjust);
274     auto renderContext = host->GetRenderContext();
275     CHECK_NULL_VOID(renderContext);
276     renderContext->UpdatePaintRect(frame + geometryNode->GetPixelGridRoundRect() - geometryNode->GetFrameRect());
277 }
278 
ExpandHelper(const std::unique_ptr<SafeAreaExpandOpts> & opts,RectF & frame)279 void LayoutWrapper::ExpandHelper(const std::unique_ptr<SafeAreaExpandOpts>& opts, RectF& frame)
280 {
281     CHECK_NULL_VOID(opts);
282     auto host = GetHostNode();
283     CHECK_NULL_VOID(host);
284     auto pipeline = host->GetContext();
285     CHECK_NULL_VOID(pipeline);
286     auto safeArea = pipeline->GetSafeAreaManager()->GetCombinedSafeArea(*opts);
287     if ((opts->edges & SAFE_AREA_EDGE_START) && safeArea.left_.IsOverlapped(frame.Left())) {
288         frame.SetWidth(frame.Width() + frame.Left() - safeArea.left_.start);
289         frame.SetLeft(safeArea.left_.start);
290     }
291     if ((opts->edges & SAFE_AREA_EDGE_TOP) && safeArea.top_.IsOverlapped(frame.Top())) {
292         frame.SetHeight(frame.Height() + frame.Top() - safeArea.top_.start);
293         frame.SetTop(safeArea.top_.start);
294     }
295 
296     if ((opts->edges & SAFE_AREA_EDGE_END) && safeArea.right_.IsOverlapped(frame.Right())) {
297         frame.SetWidth(frame.Width() + (safeArea.right_.end - frame.Right()));
298     }
299     if ((opts->edges & SAFE_AREA_EDGE_BOTTOM) && safeArea.bottom_.IsOverlapped(frame.Bottom())) {
300         frame.SetHeight(frame.Height() + (safeArea.bottom_.end - frame.Bottom()));
301     }
302 }
303 
AdjustFixedSizeNode(RectF & frame)304 void LayoutWrapper::AdjustFixedSizeNode(RectF& frame)
305 {
306     // reset if User has fixed size
307     auto layoutProperty = GetLayoutProperty();
308     CHECK_NULL_VOID(layoutProperty);
309     auto geometryNode = GetGeometryNode();
310     CHECK_NULL_VOID(geometryNode);
311     if (layoutProperty->HasFixedWidth()) {
312         frame.SetWidth(geometryNode->GetFrameRect().Width());
313     }
314     if (layoutProperty->HasFixedHeight()) {
315         frame.SetHeight(geometryNode->GetFrameRect().Height());
316     }
317     if (layoutProperty->HasAspectRatio()) {
318         frame.SetHeight(frame.Width() / layoutProperty->GetAspectRatio());
319     }
320 }
321 
AdjustChildren(const OffsetF & offset,bool parentScrollable)322 void LayoutWrapper::AdjustChildren(const OffsetF& offset, bool parentScrollable)
323 {
324     auto host = GetHostNode();
325     CHECK_NULL_VOID(host);
326     auto pattern = host->GetPattern();
327     if (pattern && pattern->ConsumeChildrenAdjustment(offset)) {
328         return;
329     }
330     for (const auto& childUI : GetHostNode()->GetChildren()) {
331         AdjustChild(childUI, offset, parentScrollable);
332     }
333 }
334 
AdjustChild(RefPtr<UINode> childUI,const OffsetF & offset,bool parentScrollable)335 void LayoutWrapper::AdjustChild(RefPtr<UINode> childUI, const OffsetF& offset, bool parentScrollable)
336 {
337     auto child = DynamicCast<FrameNode>(childUI);
338     if (!child) {
339         if (!IsSyntaxNode(childUI->GetTag())) {
340             return;
341         }
342         for (const auto& syntaxChild : childUI->GetChildren()) {
343             AdjustChild(syntaxChild, offset, parentScrollable);
344         }
345         return;
346     }
347     auto childGeo = child->GetGeometryNode();
348     auto parentAdjust = childGeo->GetParentAdjust();
349     if (parentAdjust.GetOffset() != offset) {
350         AddChildToExpandListIfNeeded(AceType::WeakClaim(AceType::RawPtr(child)));
351     }
352     if (!parentScrollable) {
353         childGeo->SetParentAdjust(RectF(offset, SizeF()));
354     }
355 }
356 
AddChildToExpandListIfNeeded(const WeakPtr<FrameNode> & node)357 void LayoutWrapper::AddChildToExpandListIfNeeded(const WeakPtr<FrameNode>& node)
358 {
359     auto host = node.Upgrade();
360     CHECK_NULL_VOID(host);
361     auto pipeline = host->GetContext();
362     CHECK_NULL_VOID(pipeline);
363     auto safeAreaManager = pipeline->GetSafeAreaManager();
364     CHECK_NULL_VOID(safeAreaManager);
365     bool canAdd = safeAreaManager->AddNodeToExpandListIfNeeded(node);
366     CHECK_NULL_VOID(canAdd);
367     auto task = [weak = node]() {
368         auto frameNode = weak.Upgrade();
369         CHECK_NULL_VOID(frameNode);
370         DirtySwapConfig emptyConfig;
371         frameNode->SyncGeometryNode(true, emptyConfig);
372     };
373     pipeline->AddSyncGeometryNodeTask(task);
374 }
375 
ExpandIntoKeyboard()376 OffsetF LayoutWrapper::ExpandIntoKeyboard()
377 {
378     auto pageOffset = GetPageCurrentOffset();
379     if (GreatOrEqual(pageOffset, 0.0f)) {
380         return OffsetF();
381     }
382     // if parent already expanded into keyboard, offset shouldn't be applied again
383     auto parent = GetHostNode()->GetAncestorNodeOfFrame();
384     while (parent) {
385         auto pattern = parent->GetPattern();
386         if (pattern && pattern->CheckCustomAvoidKeyboard()) {
387             // if parent need avoid keyboard and child need expand into keyboard,
388             // keep child expand into keyboard
389             break;
390         }
391         auto&& opts = parent->GetLayoutProperty()->GetSafeAreaExpandOpts();
392         if (opts && (opts->edges & SAFE_AREA_EDGE_BOTTOM) && opts->type & SAFE_AREA_TYPE_KEYBOARD) {
393             return OffsetF();
394         }
395         parent = parent->GetAncestorNodeOfFrame();
396     }
397     auto host = GetHostNode();
398     CHECK_NULL_RETURN(host, OffsetF());
399     auto pipeline = host->GetContext();
400     CHECK_NULL_RETURN(pipeline, OffsetF());
401     return OffsetF(0.0f, -pipeline->GetSafeAreaManager()->GetKeyboardOffset());
402 }
403 
GetPageCurrentOffset()404 float LayoutWrapper::GetPageCurrentOffset()
405 {
406     auto host = GetHostNode();
407     CHECK_NULL_RETURN(host, 0.0f);
408     auto pipeline = host->GetContext();
409     CHECK_NULL_RETURN(pipeline, 0.0f);
410     auto stageManager = pipeline->GetStageManager();
411     CHECK_NULL_RETURN(stageManager, 0.0f);
412     auto pageNode = stageManager->GetPageById(host->GetPageId());
413     CHECK_NULL_RETURN(pageNode, 0.0f);
414     auto pageRenderContext = pageNode->GetRenderContext();
415     CHECK_NULL_RETURN(pageRenderContext, 0.0f);
416     auto safeAreaManager = pipeline->GetSafeAreaManager();
417     CHECK_NULL_RETURN(safeAreaManager, 0.0f);
418     auto safeArea = safeAreaManager->GetSafeArea();
419     auto safeAreaTop = safeAreaManager->IsAtomicService() ? 0 : safeArea.top_.Length();
420     return pageRenderContext->GetPaintRectWithoutTransform().GetY() - safeAreaTop;
421 }
422 
ApplyConstraint(LayoutConstraintF constraint)423 void LayoutWrapper::ApplyConstraint(LayoutConstraintF constraint)
424 {
425     GetGeometryNode()->SetParentLayoutConstraint(constraint);
426 
427     auto layoutProperty = GetLayoutProperty();
428     auto& magicItemProperty = layoutProperty->GetMagicItemProperty();
429     if (magicItemProperty.HasAspectRatio()) {
430         std::optional<CalcSize> idealSize = std::nullopt;
431         if (layoutProperty->GetCalcLayoutConstraint()) {
432             idealSize = layoutProperty->GetCalcLayoutConstraint()->selfIdealSize;
433         }
434         auto greaterThanApiTen = Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN);
435         constraint.ApplyAspectRatio(magicItemProperty.GetAspectRatioValue(), idealSize, greaterThanApiTen);
436     }
437 
438     auto&& insets = layoutProperty->GetSafeAreaInsets();
439     if (insets) {
440         ApplySafeArea(*insets, constraint);
441     }
442 
443     layoutProperty->UpdateLayoutConstraint(constraint);
444 }
445 
ApplyConstraintWithoutMeasure(const std::optional<LayoutConstraintF> & constraint)446 void LayoutWrapper::ApplyConstraintWithoutMeasure(const std::optional<LayoutConstraintF>& constraint)
447 {
448     if (constraint) {
449         ApplyConstraint(*constraint);
450     }
451 }
452 
CreateRootConstraint()453 void LayoutWrapper::CreateRootConstraint()
454 {
455     LayoutConstraintF layoutConstraint;
456     layoutConstraint.percentReference.SetWidth(PipelineContext::GetCurrentRootWidth());
457     auto layoutProperty = GetLayoutProperty();
458     auto& magicItemProperty = layoutProperty->GetMagicItemProperty();
459     if (magicItemProperty.HasAspectRatio()) {
460         auto aspectRatio = magicItemProperty.GetAspectRatioValue();
461         if (Positive(aspectRatio)) {
462             auto height = PipelineContext::GetCurrentRootHeight() / aspectRatio;
463             layoutConstraint.percentReference.SetHeight(height);
464         }
465     } else {
466         layoutConstraint.percentReference.SetHeight(PipelineContext::GetCurrentRootHeight());
467     }
468     layoutProperty->UpdateLayoutConstraint(layoutConstraint);
469 }
470 
GetHostNode() const471 RefPtr<FrameNode> LayoutWrapper::GetHostNode() const
472 {
473     return hostNode_.Upgrade();
474 }
475 
AddNodeFlexLayouts()476 void LayoutWrapper::AddNodeFlexLayouts()
477 {
478     if (!AceChecker::IsPerformanceCheckEnabled()) {
479         return;
480     }
481     auto host = GetHostNode();
482     CHECK_NULL_VOID(host);
483     auto frameNodeParent = host->GetAncestorNodeOfFrame();
484     CHECK_NULL_VOID(frameNodeParent);
485     if (frameNodeParent->GetTag() == V2::FLEX_ETS_TAG) {
486         auto parent = host->GetParent();
487         CHECK_NULL_VOID(parent);
488         if (parent->GetTag() == V2::JS_VIEW_ETS_TAG) {
489             parent->AddFlexLayouts();
490         } else if (host->GetTag() == V2::COMMON_VIEW_ETS_TAG) {
491             auto children = host->GetChildren();
492             if (!children.empty()) {
493                 auto begin = children.begin();
494                 (*begin)->AddFlexLayouts();
495             }
496         } else {
497             host->AddFlexLayouts();
498         }
499     }
500 }
501 
AddNodeLayoutTime(int64_t time)502 void LayoutWrapper::AddNodeLayoutTime(int64_t time)
503 {
504     if (!AceChecker::IsPerformanceCheckEnabled()) {
505         return;
506     }
507     auto host = GetHostNode();
508     CHECK_NULL_VOID(host);
509     host->SetLayoutTime(time);
510 }
511 
512 } // namespace OHOS::Ace::NG
513