• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "bridge/declarative_frontend/view_stack_processor.h"
17 
18 #include <string>
19 
20 #include "base/log/ace_trace.h"
21 #include "base/utils/system_properties.h"
22 #include "core/accessibility/accessibility_node.h"
23 #include "core/common/ace_application_info.h"
24 #include "core/components/button/button_component.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/form/form_component.h"
27 #include "core/components/grid_layout/grid_layout_item_component.h"
28 #include "core/components/image/image_component.h"
29 #include "core/components/menu/menu_component.h"
30 #include "core/components/remote_window/remote_window_component.h"
31 #include "core/components/scoring/scoring_component.h"
32 #include "core/components/stepper/stepper_item_component_v2.h"
33 #include "core/components/text/text_component.h"
34 #include "core/components/text_field/text_field_component.h"
35 #include "core/components/text_span/text_span_component.h"
36 #include "core/components/video/video_component_v2.h"
37 #include "core/components/web/web_component.h"
38 #include "core/components/xcomponent/xcomponent_component.h"
39 #include "core/components_v2/list/list_item_component.h"
40 #include "core/components_v2/water_flow/water_flow_item_component.h"
41 #include "core/pipeline/base/component.h"
42 #include "core/pipeline/base/multi_composed_component.h"
43 #include "core/pipeline/base/sole_child_component.h"
44 
45 namespace OHOS::Ace::Framework {
46 thread_local std::unique_ptr<ViewStackProcessor> ViewStackProcessor::instance = nullptr;
47 
GetInstance()48 ViewStackProcessor* ViewStackProcessor::GetInstance()
49 {
50     if (!instance) {
51         instance.reset(new ViewStackProcessor);
52     }
53     return instance.get();
54 }
55 
ViewStackProcessor()56 ViewStackProcessor::ViewStackProcessor()
57 {
58     radioGroups_ = std::make_shared<JsPageRadioGroups>();
59     checkboxGroups_ = std::make_shared<JsPageCheckboxGroups>();
60 }
61 
GetRadioGroupComponent()62 std::shared_ptr<JsPageRadioGroups> ViewStackProcessor::GetRadioGroupComponent()
63 {
64     return radioGroups_;
65 }
66 
GetCheckboxGroupComponent()67 std::shared_ptr<JsPageCheckboxGroups> ViewStackProcessor::GetCheckboxGroupComponent()
68 {
69     return checkboxGroups_;
70 }
71 
GetRootComponent(const std::string & id,const std::string & name)72 RefPtr<ComposedComponent> ViewStackProcessor::GetRootComponent(const std::string& id, const std::string& name)
73 {
74     auto& wrappingComponentsMap = componentsStack_.top();
75     if (wrappingComponentsMap.find("root") != wrappingComponentsMap.end()) {
76         return AceType::DynamicCast<ComposedComponent>(wrappingComponentsMap["root"]);
77     }
78 
79     RefPtr<ComposedComponent> rootComponent = AceType::MakeRefPtr<OHOS::Ace::ComposedComponent>(id, name);
80     wrappingComponentsMap.emplace("root", rootComponent);
81     return rootComponent;
82 }
83 
GetCoverageComponent()84 RefPtr<CoverageComponent> ViewStackProcessor::GetCoverageComponent()
85 {
86     auto& wrappingComponentsMap = componentsStack_.top();
87     if (wrappingComponentsMap.find("coverage") != wrappingComponentsMap.end()) {
88         return AceType::DynamicCast<CoverageComponent>(wrappingComponentsMap["coverage"]);
89     }
90 
91     std::list<RefPtr<Component>> children;
92     RefPtr<CoverageComponent> coverageComponent = AceType::MakeRefPtr<OHOS::Ace::CoverageComponent>(children);
93     wrappingComponentsMap.emplace("coverage", coverageComponent);
94     return coverageComponent;
95 }
96 
97 #ifndef WEARABLE_PRODUCT
GetPopupComponent(bool createNewComponent)98 RefPtr<PopupComponentV2> ViewStackProcessor::GetPopupComponent(bool createNewComponent)
99 {
100     auto& wrappingComponentsMap = componentsStack_.top();
101     if (wrappingComponentsMap.find("popup") != wrappingComponentsMap.end()) {
102         return AceType::DynamicCast<PopupComponentV2>(wrappingComponentsMap["popup"]);
103     }
104 
105     if (!createNewComponent) {
106         return nullptr;
107     }
108 
109     RefPtr<PopupComponentV2> popupComponent =
110         AceType::MakeRefPtr<OHOS::Ace::PopupComponentV2>(V2::InspectorComposedComponent::GenerateId(), "popup");
111     wrappingComponentsMap.emplace("popup", popupComponent);
112     return popupComponent;
113 }
114 #endif
115 
GetMenuComponent(bool createNewComponent)116 RefPtr<MenuComponent> ViewStackProcessor::GetMenuComponent(bool createNewComponent)
117 {
118     auto& wrappingComponentsMap = componentsStack_.top();
119     if (wrappingComponentsMap.find("menu") != wrappingComponentsMap.end()) {
120         return AceType::DynamicCast<MenuComponent>(wrappingComponentsMap["menu"]);
121     }
122 
123     if (!createNewComponent) {
124         return nullptr;
125     }
126 
127     RefPtr<MenuComponent> menuComponent =
128         AceType::MakeRefPtr<OHOS::Ace::MenuComponent>(V2::InspectorComposedComponent::GenerateId(), "menu");
129     wrappingComponentsMap.emplace("menu", menuComponent);
130     return menuComponent;
131 }
132 
GetPositionedComponent()133 RefPtr<PositionedComponent> ViewStackProcessor::GetPositionedComponent()
134 {
135     auto& wrappingComponentsMap = componentsStack_.top();
136     if (wrappingComponentsMap.find("position") != wrappingComponentsMap.end()) {
137         return AceType::DynamicCast<PositionedComponent>(wrappingComponentsMap["position"]);
138     }
139 
140     RefPtr<PositionedComponent> positionedComponent = AceType::MakeRefPtr<OHOS::Ace::PositionedComponent>();
141     wrappingComponentsMap.emplace("position", positionedComponent);
142     return positionedComponent;
143 }
144 
GetFlexItemComponent()145 RefPtr<FlexItemComponent> ViewStackProcessor::GetFlexItemComponent()
146 {
147     auto& wrappingComponentsMap = componentsStack_.top();
148     if (wrappingComponentsMap.find("flexItem") != wrappingComponentsMap.end()) {
149         return AceType::DynamicCast<FlexItemComponent>(wrappingComponentsMap["flexItem"]);
150     }
151     // flex values are all changed to 0.0 in Render.
152     RefPtr<FlexItemComponent> flexItem = AceType::MakeRefPtr<OHOS::Ace::FlexItemComponent>(0.0, -1.0, 0.0);
153     wrappingComponentsMap.emplace("flexItem", flexItem);
154     return flexItem;
155 }
156 
GetStepperItemComponent()157 RefPtr<StepperItemComponent> ViewStackProcessor::GetStepperItemComponent()
158 {
159     auto& wrappingComponentsMap = componentsStack_.top();
160     if (wrappingComponentsMap.find("stepperItem") != wrappingComponentsMap.end()) {
161         return AceType::DynamicCast<StepperItemComponent>(wrappingComponentsMap["stepperItem"]);
162     }
163 
164     RefPtr<StepperItemComponent> stepperItem = AceType::MakeRefPtr<StepperItemComponent>(RefPtr<Component>());
165     wrappingComponentsMap.emplace("stepperItem", stepperItem);
166     return stepperItem;
167 }
168 
GetStepperDisplayComponent()169 RefPtr<DisplayComponent> ViewStackProcessor::GetStepperDisplayComponent()
170 {
171     auto& wrappingComponentsMap = componentsStack_.top();
172     if (wrappingComponentsMap.find("stepperDisplay") != wrappingComponentsMap.end()) {
173         return AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["stepperDisplay"]);
174     }
175 
176     RefPtr<DisplayComponent> stepperDisplay = AceType::MakeRefPtr<DisplayComponent>();
177     wrappingComponentsMap.emplace("stepperDisplay", stepperDisplay);
178     return stepperDisplay;
179 }
180 
GetStepperScrollComponent()181 RefPtr<ScrollComponent> ViewStackProcessor::GetStepperScrollComponent()
182 {
183     auto& wrappingComponentsMap = componentsStack_.top();
184     if (wrappingComponentsMap.find("stepperScroll") != wrappingComponentsMap.end()) {
185         return AceType::DynamicCast<ScrollComponent>(wrappingComponentsMap["stepperScroll"]);
186     }
187 
188     RefPtr<ScrollComponent> stepperScroll = AceType::MakeRefPtr<ScrollComponent>(RefPtr<Component>());
189     wrappingComponentsMap.emplace("stepperScroll", stepperScroll);
190     return stepperScroll;
191 }
192 
GetBoxComponent()193 RefPtr<BoxComponent> ViewStackProcessor::GetBoxComponent()
194 {
195 #if defined(PREVIEW)
196     if (componentsStack_.empty()) {
197         RefPtr<BoxComponent> boxComponent = AceType::MakeRefPtr<OHOS::Ace::BoxComponent>();
198         std::unordered_map<std::string, RefPtr<Component>> wrappingComponentsMap;
199         wrappingComponentsMap.emplace("box", boxComponent);
200         componentsStack_.push(wrappingComponentsMap);
201         return boxComponent;
202     }
203 #endif
204     auto& wrappingComponentsMap = componentsStack_.top();
205     if (wrappingComponentsMap.find("box") != wrappingComponentsMap.end()) {
206         auto boxComponent = AceType::DynamicCast<BoxComponent>(wrappingComponentsMap["box"]);
207         if (boxComponent) {
208             return boxComponent;
209         }
210     }
211 
212     RefPtr<BoxComponent> boxComponent = AceType::MakeRefPtr<OHOS::Ace::BoxComponent>();
213     boxComponent->SetEnableDebugBoundary(true);
214     wrappingComponentsMap.emplace("box", boxComponent);
215     return boxComponent;
216 }
217 
GetMainComponent() const218 RefPtr<Component> ViewStackProcessor::GetMainComponent() const
219 {
220     if (componentsStack_.empty()) {
221         return nullptr;
222     }
223     auto& wrappingComponentsMap = componentsStack_.top();
224     auto main = wrappingComponentsMap.find("main");
225     if (main == wrappingComponentsMap.end()) {
226         return nullptr;
227     }
228     return main->second;
229 }
230 
HasDisplayComponent() const231 bool ViewStackProcessor::HasDisplayComponent() const
232 {
233     auto& wrappingComponentsMap = componentsStack_.top();
234     if (wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
235         return true;
236     }
237     return false;
238 }
239 
GetDisplayComponent()240 RefPtr<DisplayComponent> ViewStackProcessor::GetDisplayComponent()
241 {
242     auto& wrappingComponentsMap = componentsStack_.top();
243     if (wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
244         auto displayComponent = AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["display"]);
245         if (displayComponent) {
246             return displayComponent;
247         }
248     }
249 
250     RefPtr<DisplayComponent> displayComponent = AceType::MakeRefPtr<OHOS::Ace::DisplayComponent>();
251     wrappingComponentsMap.emplace("display", displayComponent);
252     return displayComponent;
253 }
254 
GetTransformComponent()255 RefPtr<TransformComponent> ViewStackProcessor::GetTransformComponent()
256 {
257     auto& wrappingComponentsMap = componentsStack_.top();
258     if (wrappingComponentsMap.find("transform") != wrappingComponentsMap.end()) {
259         auto transformComponent = AceType::DynamicCast<TransformComponent>(wrappingComponentsMap["transform"]);
260         if (transformComponent) {
261             return transformComponent;
262         }
263     }
264 
265     RefPtr<TransformComponent> transformComponent = AceType::MakeRefPtr<OHOS::Ace::TransformComponent>();
266     wrappingComponentsMap.emplace("transform", transformComponent);
267     return transformComponent;
268 }
269 
HasTouchListenerComponent() const270 bool ViewStackProcessor::HasTouchListenerComponent() const
271 {
272     auto& wrappingComponentsMap = componentsStack_.top();
273     if (wrappingComponentsMap.find("touch") != wrappingComponentsMap.end()) {
274         return true;
275     }
276     return false;
277 }
278 
GetTouchListenerComponent()279 RefPtr<TouchListenerComponent> ViewStackProcessor::GetTouchListenerComponent()
280 {
281     auto& wrappingComponentsMap = componentsStack_.top();
282     if (wrappingComponentsMap.find("touch") != wrappingComponentsMap.end()) {
283         auto touchListenerComponent = AceType::DynamicCast<TouchListenerComponent>(wrappingComponentsMap["touch"]);
284         if (touchListenerComponent) {
285             return touchListenerComponent;
286         }
287     }
288 
289     RefPtr<TouchListenerComponent> touchComponent = AceType::MakeRefPtr<OHOS::Ace::TouchListenerComponent>();
290     wrappingComponentsMap.emplace("touch", touchComponent);
291     return touchComponent;
292 }
293 
GetMouseListenerComponent()294 RefPtr<MouseListenerComponent> ViewStackProcessor::GetMouseListenerComponent()
295 {
296     auto& wrappingComponentsMap = componentsStack_.top();
297     if (wrappingComponentsMap.find("mouse") != wrappingComponentsMap.end()) {
298         auto mouseListenerComponent = AceType::DynamicCast<MouseListenerComponent>(wrappingComponentsMap["mouse"]);
299         if (mouseListenerComponent) {
300             return mouseListenerComponent;
301         }
302     }
303 
304     RefPtr<MouseListenerComponent> mouseComponent = AceType::MakeRefPtr<OHOS::Ace::MouseListenerComponent>();
305     wrappingComponentsMap.emplace("mouse", mouseComponent);
306     return mouseComponent;
307 }
308 
HasClickGestureListenerComponent() const309 bool ViewStackProcessor::HasClickGestureListenerComponent() const
310 {
311     auto& wrappingComponentsMap = componentsStack_.top();
312     if (wrappingComponentsMap.find("click_gesture") != wrappingComponentsMap.end()) {
313         return true;
314     }
315     return false;
316 }
317 
GetClickGestureListenerComponent()318 RefPtr<GestureListenerComponent> ViewStackProcessor::GetClickGestureListenerComponent()
319 {
320     auto& wrappingComponentsMap = componentsStack_.top();
321     if (wrappingComponentsMap.find("click_gesture") != wrappingComponentsMap.end()) {
322         auto gestureListenerComponent =
323             AceType::DynamicCast<GestureListenerComponent>(wrappingComponentsMap["click_gesture"]);
324         if (gestureListenerComponent) {
325             return gestureListenerComponent;
326         }
327     }
328 
329     RefPtr<GestureListenerComponent> clickGestureComponent =
330         AceType::MakeRefPtr<OHOS::Ace::GestureListenerComponent>();
331     wrappingComponentsMap.emplace("click_gesture", clickGestureComponent);
332     return clickGestureComponent;
333 }
334 
GetFocusableComponent(bool createIfNotExist)335 RefPtr<FocusableComponent> ViewStackProcessor::GetFocusableComponent(bool createIfNotExist)
336 {
337     auto& wrappingComponentsMap = componentsStack_.top();
338     if (wrappingComponentsMap.find("focusable") != wrappingComponentsMap.end()) {
339         return AceType::DynamicCast<FocusableComponent>(wrappingComponentsMap["focusable"]);
340     }
341     if (createIfNotExist) {
342         RefPtr<FocusableComponent> focusableComponent = AceType::MakeRefPtr<OHOS::Ace::FocusableComponent>();
343         wrappingComponentsMap.emplace("focusable", focusableComponent);
344         Component::MergeRSNode(focusableComponent);
345         return focusableComponent;
346     }
347     return nullptr;
348 }
349 
GetPanGestureListenerComponent()350 RefPtr<GestureListenerComponent> ViewStackProcessor::GetPanGestureListenerComponent()
351 {
352     auto& wrappingComponentsMap = componentsStack_.top();
353     if (wrappingComponentsMap.find("pan_gesture") != wrappingComponentsMap.end()) {
354         auto gestureListenerComponent =
355             AceType::DynamicCast<GestureListenerComponent>(wrappingComponentsMap["pan_gesture"]);
356         if (gestureListenerComponent) {
357             return gestureListenerComponent;
358         }
359     }
360 
361     RefPtr<GestureListenerComponent> panGestureComponent = AceType::MakeRefPtr<OHOS::Ace::GestureListenerComponent>();
362     wrappingComponentsMap.emplace("pan_gesture", panGestureComponent);
363     return panGestureComponent;
364 }
365 
GetSharedTransitionComponent()366 RefPtr<SharedTransitionComponent> ViewStackProcessor::GetSharedTransitionComponent()
367 {
368     auto& wrappingComponentsMap = componentsStack_.top();
369     if (wrappingComponentsMap.find("shared_transition") != wrappingComponentsMap.end()) {
370         auto sharedTransitionComponent =
371             AceType::DynamicCast<SharedTransitionComponent>(wrappingComponentsMap["shared_transition"]);
372         if (sharedTransitionComponent) {
373             return sharedTransitionComponent;
374         }
375     }
376 
377     RefPtr<SharedTransitionComponent> sharedTransitionComponent =
378         AceType::MakeRefPtr<OHOS::Ace::SharedTransitionComponent>("", "", "");
379     wrappingComponentsMap.emplace("shared_transition", sharedTransitionComponent);
380     return sharedTransitionComponent;
381 }
382 
GetGestureComponent()383 RefPtr<GestureComponent> ViewStackProcessor::GetGestureComponent()
384 {
385     auto& wrappingComponentsMap = componentsStack_.top();
386     if (wrappingComponentsMap.find("gesture") != wrappingComponentsMap.end()) {
387         auto gestureComponent = AceType::DynamicCast<GestureComponent>(wrappingComponentsMap["gesture"]);
388         if (gestureComponent) {
389             return gestureComponent;
390         }
391     }
392 
393     RefPtr<GestureComponent> gestureComponent = AceType::MakeRefPtr<OHOS::Ace::GestureComponent>();
394     wrappingComponentsMap.emplace("gesture", gestureComponent);
395     return gestureComponent;
396 }
397 
GetPageTransitionComponent()398 RefPtr<PageTransitionComponent> ViewStackProcessor::GetPageTransitionComponent()
399 {
400     if (!pageTransitionComponent_) {
401         pageTransitionComponent_ = AceType::MakeRefPtr<PageTransitionComponent>();
402     }
403     return pageTransitionComponent_;
404 }
405 
ClearPageTransitionComponent()406 void ViewStackProcessor::ClearPageTransitionComponent()
407 {
408     if (pageTransitionComponent_) {
409         pageTransitionComponent_.Reset();
410     }
411 }
412 
Push(const RefPtr<Component> & component,bool isCustomView)413 void ViewStackProcessor::Push(const RefPtr<Component>& component, bool isCustomView)
414 {
415     CHECK_NULL_VOID_NOLOG(component);
416     std::unordered_map<std::string, RefPtr<Component>> wrappingComponentsMap;
417     if (componentsStack_.size() > 1 && ShouldPopImmediately()) {
418         Pop();
419     }
420     wrappingComponentsMap.emplace("main", component);
421     componentsStack_.push(wrappingComponentsMap);
422     std::string name;
423     auto composedComponent = AceType::DynamicCast<ComposedComponent>(component);
424     if (composedComponent) {
425         name = composedComponent->GetName();
426     }
427     auto tag = component->GetInspectorTag();
428     tag = tag.empty() ? (name.empty() ? AceType::TypeName(component) : name) : tag;
429     CreateInspectorComposedComponent(tag);
430     CreateScoringComponent(tag);
431 
432 #if defined(PREVIEW)
433     if (!isCustomView && !AceType::InstanceOf<MultiComposedComponent>(component) &&
434         !AceType::InstanceOf<TextSpanComponent>(component)) {
435         GetBoxComponent();
436     }
437 #else
438     bool isAccessEnable =
439         AceApplicationInfo::GetInstance().IsAccessibilityEnabled()
440         || SystemProperties::GetAccessibilityEnabled()
441         || SystemProperties::GetDebugBoundaryEnabled();
442     if (!isCustomView && !AceType::InstanceOf<MultiComposedComponent>(component) &&
443         !AceType::InstanceOf<TextSpanComponent>(component) && isAccessEnable) {
444         GetBoxComponent();
445     }
446 #endif
447 }
448 
ShouldPopImmediately()449 bool ViewStackProcessor::ShouldPopImmediately()
450 {
451     auto type = AceType::TypeName(GetMainComponent());
452     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
453     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
454     auto soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
455     auto menuComponent = AceType::DynamicCast<MenuComponent>(GetMainComponent());
456     return (strcmp(type, AceType::TypeName<TextSpanComponent>()) == 0 ||
457             !(componentGroup || multiComposedComponent || soleChildComponent || menuComponent));
458 }
459 
Pop()460 void ViewStackProcessor::Pop()
461 {
462     if (componentsStack_.empty() || componentsStack_.size() == 1) {
463         return;
464     }
465 
466     auto component = WrapComponents().first;
467     if (AceType::DynamicCast<ComposedComponent>(component)) {
468         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
469         SetZIndex(childComponent);
470         SetIsPercentSize(childComponent);
471     } else {
472         SetZIndex(component);
473         SetIsPercentSize(component);
474     }
475 
476     UpdateTopComponentProps(component);
477 
478     componentsStack_.pop();
479     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
480     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
481     if (componentGroup) {
482         componentGroup->AppendChild(component);
483     } else if (multiComposedComponent) {
484         multiComposedComponent->AddChild(component);
485     } else {
486         auto singleChild = AceType::DynamicCast<SingleChild>(GetMainComponent());
487         if (singleChild) {
488             singleChild->SetChild(component);
489         }
490     }
491     LOGD("ViewStackProcessor Pop size %{public}zu", componentsStack_.size());
492 }
493 
GetNewComponent()494 RefPtr<Component> ViewStackProcessor::GetNewComponent()
495 {
496     if (componentsStack_.empty()) {
497         return nullptr;
498     }
499     auto component = WrapComponents().first;
500     if (AceType::DynamicCast<ComposedComponent>(component)) {
501         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
502         SetZIndex(childComponent);
503         SetIsPercentSize(childComponent);
504     } else {
505         SetZIndex(component);
506         SetIsPercentSize(component);
507     }
508     UpdateTopComponentProps(component);
509     componentsStack_.pop();
510     return component;
511 }
512 
PopContainer()513 void ViewStackProcessor::PopContainer()
514 {
515     auto type = AceType::TypeName(GetMainComponent());
516     auto componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
517     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
518     auto soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
519     if ((componentGroup && strcmp(type, AceType::TypeName<TextSpanComponent>()) != 0) || multiComposedComponent ||
520         soleChildComponent) {
521         Pop();
522         return;
523     }
524 
525     while ((!componentGroup && !multiComposedComponent && !soleChildComponent) ||
526            strcmp(type, AceType::TypeName<TextSpanComponent>()) == 0) {
527         if (componentsStack_.size() <= 1) {
528             break;
529         }
530         Pop();
531         type = AceType::TypeName(GetMainComponent());
532         componentGroup = AceType::DynamicCast<ComponentGroup>(GetMainComponent());
533         multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(GetMainComponent());
534         soleChildComponent = AceType::DynamicCast<SoleChildComponent>(GetMainComponent());
535     }
536     Pop();
537 }
538 
539 #ifdef ACE_DEBUG_LOG
DumpStack()540 void ViewStackProcessor::DumpStack()
541 {
542     LOGD("| stack size: \033[0;33m %{public}d \033[0m", (int)componentsStack_.size());
543     if (componentsStack_.empty()) {
544         return;
545     }
546     LOGD("| stack top size: \033[0;33m %{public}d \033[0m", (int)componentsStack_.top().size());
547     std::stack<std::unordered_map<std::string, RefPtr<Component>>> tmp;
548     int count = 0;
549     while (!componentsStack_.empty()) {
550         LOGD("| stack level: \033[0;33m %{public}d \033[0m", count++);
551         auto& wrappingComponentsMap = componentsStack_.top();
552         for (const auto& j : wrappingComponentsMap) {
553             LOGD("|\033[0;36m %{public}s - %{public}s \033[0m", j.first.c_str(), AceType::TypeName(j.second));
554         }
555         tmp.push(componentsStack_.top());
556         componentsStack_.pop();
557     }
558     while (!tmp.empty()) {
559         componentsStack_.push(tmp.top());
560         tmp.pop();
561     }
562 }
563 #endif
564 
WrapComponents()565 std::pair<RefPtr<Component>, RefPtr<Component>> ViewStackProcessor::WrapComponents()
566 {
567     auto& wrappingComponentsMap = componentsStack_.top();
568     std::vector<RefPtr<Component>> components;
569 
570     auto mainComponent = wrappingComponentsMap["main"];
571 
572     auto videoComponentV2 = AceType::DynamicCast<VideoComponentV2>(mainComponent);
573     SaveComponentEvent saveComponentEvent;
574     if (videoComponentV2) {
575         saveComponentEvent = videoComponentV2->GetSaveComponentEvent();
576     }
577     std::unordered_map<std::string, RefPtr<Component>> videoMap;
578 
579     bool isItemComponent = AceType::InstanceOf<V2::ListItemComponent>(mainComponent) ||
580                            AceType::InstanceOf<GridLayoutItemComponent>(mainComponent) ||
581                            AceType::InstanceOf<V2::WaterFlowItemComponent>(mainComponent);
582 
583     RefPtr<Component> itemChildComponent;
584 
585     if (isItemComponent) {
586         itemChildComponent = AceType::DynamicCast<SingleChild>(mainComponent)->GetChild();
587         components.emplace_back(mainComponent);
588     }
589 
590     auto composedComponent = GetInspectorComposedComponent();
591     if (composedComponent) {
592         components.emplace_back(composedComponent);
593     }
594 
595     auto scoringComponent = GetScoringComponent();
596     if (scoringComponent) {
597         components.emplace_back(scoringComponent);
598     }
599 
600     std::string componentNames[] = { "stepperItem", "stepperDisplay", "flexItem", "display", "transform", "touch",
601         "pan_gesture", "click_gesture", "focusable", "coverage", "box", "shared_transition", "mouse",
602         "stepperScroll" };
603     // In RS extra case, use isFirstNode to determine the top node.
604     bool isFirstNode = true;
605     for (auto& name : componentNames) {
606         auto iter = wrappingComponentsMap.find(name);
607         if (iter != wrappingComponentsMap.end()) {
608             if (isFirstNode) {
609                 iter->second->SetIsFirst(isFirstNode);
610                 isFirstNode = false;
611             }
612             iter->second->OnWrap();
613             components.emplace_back(iter->second);
614             if (videoComponentV2 && saveComponentEvent) {
615                 videoMap.emplace(std::make_pair(name, iter->second));
616             }
617         }
618     }
619 
620     // Adjust layout param in TextComponent
621     auto isTextComponent = AceType::InstanceOf<TextComponent>(mainComponent);
622     if (isTextComponent) {
623         auto iter = wrappingComponentsMap.find("box");
624         if (iter != wrappingComponentsMap.end()) {
625             auto boxComponent = AceType::DynamicCast<BoxComponent>(wrappingComponentsMap["box"]);
626             if (boxComponent) {
627                 boxComponent->SetDeliverMinToChild(false);
628             }
629         }
630     }
631 
632     if (wrappingComponentsMap.find("shared_transition") != wrappingComponentsMap.end() &&
633         wrappingComponentsMap.find("display") != wrappingComponentsMap.end()) {
634         auto sharedTransitionComponent =
635             AceType::DynamicCast<SharedTransitionComponent>(wrappingComponentsMap["shared_transition"]);
636         auto displayComponent = AceType::DynamicCast<DisplayComponent>(wrappingComponentsMap["display"]);
637         if (sharedTransitionComponent && displayComponent) {
638             sharedTransitionComponent->SetOpacity(displayComponent->GetOpacity());
639         }
640     }
641 
642     if (videoComponentV2 && saveComponentEvent) {
643         saveComponentEvent(videoMap);
644         videoComponentV2->SetSaveComponentEvent(nullptr);
645     }
646 
647     if (isItemComponent) {
648         // itemComponent is placed before other components, they should share the same RSNode.
649         // we should not touch itemChildComponent as it's already marked.
650         //    (head)       (tail)      (unchanged)
651         // mainComponent - others - itemChildComponent
652         Component::MergeRSNode(mainComponent);
653         Component::MergeRSNode(components);
654         if (itemChildComponent) {
655             components.emplace_back(itemChildComponent);
656         }
657     } else if (!components.empty() && (
658         AceType::InstanceOf<BoxComponent>(mainComponent) ||
659         AceType::InstanceOf<FormComponent>(mainComponent) ||
660         AceType::InstanceOf<TextFieldComponent>(mainComponent) ||
661         AceType::InstanceOf<TextureComponent>(mainComponent) ||
662         AceType::InstanceOf<WebComponent>(mainComponent) ||
663         AceType::InstanceOf<XComponentComponent>(mainComponent))) {
664         // special types of mainComponent need be marked as standalone.
665         // (head)(tail)  (standalone)
666         //    others  -  mainComponent
667         Component::MergeRSNode(components);
668         Component::MergeRSNode(mainComponent);
669         components.emplace_back(mainComponent);
670     } else if (AceType::InstanceOf<RemoteWindowComponent>(mainComponent)) {
671         // mark head component, it should use external RSNode stored in tail component.
672         components.emplace_back(mainComponent);
673         Component::MergeRSNode(components);
674         components.front()->MarkUseExternalRSNode(true);
675     } else {
676         // by default, mainComponent is placed after other components, they should share the same RSNode.
677         //  (head)      (tail)
678         // (others) - mainComponent
679         components.emplace_back(mainComponent);
680         Component::MergeRSNode(components);
681     }
682 
683     // First, composite all components.
684     for (int32_t idx = static_cast<int32_t>(components.size()) - 1; idx - 1 >= 0; --idx) {
685         auto singleChild = AceType::DynamicCast<SingleChild>(components[idx - 1]);
686         if (singleChild) {
687             singleChild->SetChild(components[idx]);
688             continue;
689         }
690 
691         auto coverageComponent = AceType::DynamicCast<CoverageComponent>(components[idx - 1]);
692         if (coverageComponent) {
693             coverageComponent->InsertChild(0, components[idx]);
694             if (coverageComponent->IsOverLay()) {
695                 coverageComponent->Initialization();
696                 Component::MergeRSNode(components[idx], coverageComponent);
697             }
698 #ifndef WEARABLE_PRODUCT
699             auto popupComponent = GetPopupComponent(false);
700             if (popupComponent) {
701                 coverageComponent->AppendChild(popupComponent);
702             }
703 #endif
704             auto menuComponent = GetMenuComponent(false);
705             if (menuComponent) {
706                 coverageComponent->AppendChild(menuComponent);
707             }
708         }
709 
710         auto focusableComponent = AceType::DynamicCast<FocusableComponent>(components[idx - 1]);
711         if (focusableComponent) {
712             Component::MergeRSNode(components[idx], focusableComponent);
713         }
714     }
715 
716     auto component = components.front();
717     auto iter = wrappingComponentsMap.find("box");
718     if (iter != wrappingComponentsMap.end() && (iter->second->GetTextDirection() != component->GetTextDirection())) {
719         component->SetTextDirection(iter->second->GetTextDirection());
720     }
721 
722     for (auto&& component : components) {
723         component->SetTouchable(mainComponent->IsTouchable() &&
724         mainComponent->GetHitTestMode() != HitTestMode::HTMNONE);
725     }
726 
727     for (auto&& component : components) {
728         component->SetHitTestMode(mainComponent->GetHitTestMode());
729     }
730 
731     for (auto&& component : components) {
732         component->SetDisabledStatus(mainComponent->IsDisabledStatus());
733     }
734 
735 #ifdef ACE_DEBUG_LOG
736     LOGD("Unwrap result: components size %{public}d (outmost child first, inner most Component last)",
737         static_cast<int32_t>(components.size()));
738     for (int32_t idx = static_cast<int32_t>(components.size()) - 1; idx >= 0; idx--) {
739         LOGD("   %{public}s elmtId: %{public}u", AceType::TypeName(components[idx]), components[idx]->GetElementId());
740     }
741 #endif
742 
743     return std::pair<RefPtr<Component>, RefPtr<Component>>(components[0], components[components.size() - 1]);
744 }
745 
UpdateTopComponentProps(const RefPtr<Component> & component)746 void ViewStackProcessor::UpdateTopComponentProps(const RefPtr<Component>& component)
747 {
748     auto& wrappingComponentsMap = componentsStack_.top();
749     if (wrappingComponentsMap.find("position") != wrappingComponentsMap.end()) {
750         auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
751         if (renderComponent) {
752             auto positionedComponent = GetPositionedComponent();
753             if (positionedComponent->HasPositionStyle()) {
754                 renderComponent->SetMotionPathOption(positionedComponent->GetMotionPathOption());
755                 renderComponent->SetHasLeft(positionedComponent->HasLeft());
756                 renderComponent->SetLeft(positionedComponent->GetLeft());
757                 renderComponent->SetHasTop(positionedComponent->HasTop());
758                 renderComponent->SetTop(positionedComponent->GetTop());
759                 renderComponent->SetHasBottom(positionedComponent->HasBottom());
760                 renderComponent->SetBottom(positionedComponent->GetBottom());
761                 renderComponent->SetHasRight(positionedComponent->HasRight());
762                 renderComponent->SetRight(positionedComponent->GetRight());
763                 renderComponent->SetPositionType(positionedComponent->GetPositionType());
764             }
765         }
766     }
767 }
768 
FinishReturnMain()769 std::pair<RefPtr<Component>, RefPtr<Component>> ViewStackProcessor::FinishReturnMain()
770 {
771     if (componentsStack_.empty()) {
772         LOGE("ViewStackProcessor FinishInternal failed, input empty render or invalid root component");
773         return std::pair<RefPtr<Component>, RefPtr<Component>>(nullptr, nullptr);
774     }
775     const auto& componentsPair = WrapComponents();
776     auto component = componentsPair.first;
777     if (AceType::DynamicCast<ComposedComponent>(component)) {
778         auto childComponent = AceType::DynamicCast<ComposedComponent>(component)->GetChild();
779         SetZIndex(childComponent);
780     } else {
781         SetZIndex(component);
782     }
783     componentsStack_.pop();
784 
785     LOGD("Done with processing on ViewStackProcessor, returning main Component %{public}s elmtId %{public}d, "
786         "outmost wrapping %{public}s. Remaining stack size %{public}d (should be zero).",
787         AceType::TypeName(componentsPair.second), componentsPair.second->GetElementId(),
788         AceType::TypeName(componentsPair.first), static_cast<int32_t>(componentsStack_.size()));
789 
790     return componentsPair;
791 }
792 
PushKey(const std::string & key)793 void ViewStackProcessor::PushKey(const std::string& key)
794 {
795     if (viewKey_.empty()) {
796         viewKey_ = key;
797         keyStack_.emplace(key.length());
798     } else {
799         viewKey_.append("_").append(key);
800         keyStack_.emplace(key.length() + 1);
801     }
802 }
803 
PopKey()804 void ViewStackProcessor::PopKey()
805 {
806     size_t length = keyStack_.top();
807     keyStack_.pop();
808 
809     if (length > 0) {
810         viewKey_.erase(viewKey_.length() - length);
811     }
812 }
813 
GetKey()814 std::string ViewStackProcessor::GetKey()
815 {
816     return viewKey_.empty() ? "" : viewKey_;
817 }
818 
ProcessViewId(const std::string & viewId)819 std::string ViewStackProcessor::ProcessViewId(const std::string& viewId)
820 {
821     return viewKey_.empty() ? viewId : viewKey_ + "_" + viewId;
822 }
823 
SetImplicitAnimationOption(const AnimationOption & option)824 void ViewStackProcessor::SetImplicitAnimationOption(const AnimationOption& option)
825 {
826     implicitAnimationOption_ = option;
827 }
828 
GetImplicitAnimationOption() const829 const AnimationOption& ViewStackProcessor::GetImplicitAnimationOption() const
830 {
831     return implicitAnimationOption_;
832 }
833 
SetZIndex(RefPtr<Component> & component)834 void ViewStackProcessor::SetZIndex(RefPtr<Component>& component)
835 {
836     int32_t zIndex = 0;
837     auto mainComponent = AceType::DynamicCast<RenderComponent>(GetMainComponent());
838     if (mainComponent) {
839         zIndex = mainComponent->GetZIndex();
840     }
841 
842     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
843     if (renderComponent) {
844         renderComponent->SetZIndex(zIndex);
845     }
846 }
847 
GetInspectorComposedComponent() const848 RefPtr<V2::InspectorComposedComponent> ViewStackProcessor::GetInspectorComposedComponent() const
849 {
850     if (componentsStack_.empty()) {
851         return nullptr;
852     }
853     auto& wrappingComponentsMap = componentsStack_.top();
854     auto iter = wrappingComponentsMap.find("inspector");
855     if (iter != wrappingComponentsMap.end()) {
856         return AceType::DynamicCast<V2::InspectorComposedComponent>(iter->second);
857     }
858     return nullptr;
859 }
860 
GetScoringComponent() const861 RefPtr<Component> ViewStackProcessor::GetScoringComponent() const
862 {
863     if (componentsStack_.empty()) {
864         return nullptr;
865     }
866     auto& wrappingComponentsMap = componentsStack_.top();
867     auto iter = wrappingComponentsMap.find("scoring");
868     if (iter != wrappingComponentsMap.end()) {
869         return iter->second;
870     }
871     return nullptr;
872 }
873 
CreateInspectorWrapper(const std::string & inspectorTag)874 RefPtr<ComposedComponent> ViewStackProcessor::CreateInspectorWrapper(const std::string& inspectorTag)
875 {
876     return AceType::MakeRefPtr<V2::InspectorComposedComponent>(
877         V2::InspectorComposedComponent::GenerateId(), inspectorTag);
878 }
879 
CreateInspectorComposedComponent(const std::string & inspectorTag)880 void ViewStackProcessor::CreateInspectorComposedComponent(const std::string& inspectorTag)
881 {
882     if (V2::InspectorComposedComponent::HasInspectorFinished(inspectorTag)) {
883         auto composedComponent = AceType::MakeRefPtr<V2::InspectorComposedComponent>(
884             V2::InspectorComposedComponent::GenerateId(), inspectorTag);
885         auto& wrappingComponentsMap = componentsStack_.top();
886 #if defined(PREVIEW)
887         composedComponent->SetViewId(viewKey_);
888 #endif
889         wrappingComponentsMap.emplace("inspector", composedComponent);
890     }
891 }
892 
CreateScoringComponent(const std::string & tag)893 void ViewStackProcessor::CreateScoringComponent(const std::string& tag)
894 {
895     static std::once_flag onceFlag;
896     std::call_once(onceFlag, [this]() {
897         auto name = AceApplicationInfo::GetInstance().GetProcessName().empty()
898                         ? AceApplicationInfo::GetInstance().GetPackageName()
899                         : AceApplicationInfo::GetInstance().GetProcessName();
900         isScoringEnable_ = SystemProperties::IsScoringEnabled(name);
901     });
902 
903     if (isScoringEnable_ && V2::InspectorComposedComponent::HasInspectorFinished(tag)) {
904         auto component =
905             AceType::MakeRefPtr<ScoringComponent>(V2::InspectorComposedComponent::GetEtsTag(tag), viewKey_);
906         auto& wrappingComponentsMap = componentsStack_.top();
907         wrappingComponentsMap.emplace("scoring", component);
908     }
909 }
910 
SetIsPercentSize(RefPtr<Component> & component)911 void ViewStackProcessor::SetIsPercentSize(RefPtr<Component>& component)
912 {
913     bool isPercentSize = false;
914     auto mainComponent = AceType::DynamicCast<RenderComponent>(GetMainComponent());
915     if (mainComponent) {
916         isPercentSize = mainComponent->GetIsPercentSize();
917     }
918 
919     auto renderComponent = AceType::DynamicCast<RenderComponent>(component);
920     if (renderComponent) {
921         renderComponent->SetIsPercentSize(isPercentSize);
922     }
923 }
924 
ClaimElementId(const RefPtr<Component> & component)925 void ViewStackProcessor::ClaimElementId(const RefPtr<Component>& component)
926 {
927     LOGD("Assigning elmtId %{public}u to new %{public}s .", reservedElementId_, AceType::TypeName(component));
928     component->AssignUniqueElementId(reservedElementId_);
929     reservedElementId_ = ElementRegister::UndefinedElementId;
930 }
931 
ScopedViewStackProcessor()932 ScopedViewStackProcessor::ScopedViewStackProcessor()
933 {
934     std::swap(instance_, ViewStackProcessor::instance);
935 }
936 
~ScopedViewStackProcessor()937 ScopedViewStackProcessor::~ScopedViewStackProcessor()
938 {
939     std::swap(instance_, ViewStackProcessor::instance);
940 }
941 
942 } // namespace OHOS::Ace::Framework
943