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