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