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