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