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