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 #ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_VIEW_STACK_PROCESSOR_H 17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_VIEW_STACK_PROCESSOR_H 18 19 #include <memory> 20 #include <stack> 21 #include <unordered_map> 22 #include <vector> 23 24 #include "core/accessibility/accessibility_node.h" 25 #include "core/components/common/properties/animation_option.h" 26 #include "core/components/grid_layout/grid_layout_component.h" 27 #include "core/pipeline/base/component.h" 28 #include "frameworks/core/components/box/box_component.h" 29 #include "frameworks/core/components/checkable/radio_group_component.h" 30 #include "frameworks/core/components/coverage/coverage_component.h" 31 #include "frameworks/core/components/display/display_component.h" 32 #include "frameworks/core/components/flex/flex_item_component.h" 33 #include "frameworks/core/components/focusable/focusable_component.h" 34 #include "frameworks/core/components/gesture_listener/gesture_component.h" 35 #include "frameworks/core/components/gesture_listener/gesture_listener_component.h" 36 #include "frameworks/core/components/menu/menu_component.h" 37 #include "frameworks/core/components/mouse_listener/mouse_listener_component.h" 38 #include "frameworks/core/components/navigation_bar/navigation_container_component.h" 39 #include "frameworks/core/components/page_transition/page_transition_component.h" 40 #include "frameworks/core/components/scroll/scroll_component.h" 41 #include "frameworks/core/components/stepper/stepper_item_component.h" 42 #ifndef WEARABLE_PRODUCT 43 #include "frameworks/core/components/popup/popup_component_v2.h" 44 #endif 45 #include "core/pipeline/base/element_register.h" 46 #include "frameworks/core/components/positioned/positioned_component.h" 47 #include "frameworks/core/components/shared_transition/shared_transition_component.h" 48 #include "frameworks/core/components/touch_listener/touch_listener_component.h" 49 #include "frameworks/core/components/transform/transform_component.h" 50 #include "frameworks/core/components_v2/inspector/inspector_composed_component.h" 51 52 namespace OHOS::Ace::Framework { 53 using JsPageRadioGroups = std::unordered_map<std::string, RadioGroupComponent<std::string>>; 54 using JsPageCheckboxGroups = std::unordered_map<std::string, RefPtr<CheckboxComponent>>; 55 56 class ViewStackProcessor final { 57 public: 58 using SaveComponentEvent = std::function<void(std::unordered_map<std::string, RefPtr<Component>>)>; 59 friend class ScopedViewStackProcessor; 60 61 ACE_FORCE_EXPORT static ViewStackProcessor* GetInstance(); 62 ~ViewStackProcessor() = default; 63 // possible wrapping components 64 RefPtr<FlexItemComponent> GetFlexItemComponent(); 65 RefPtr<StepperItemComponent> GetStepperItemComponent(); 66 RefPtr<DisplayComponent> GetStepperDisplayComponent(); 67 RefPtr<ScrollComponent> GetStepperScrollComponent(); 68 RefPtr<BoxComponent> GetBoxComponent(); 69 RefPtr<Component> GetMainComponent() const; 70 RefPtr<DisplayComponent> GetDisplayComponent(); 71 bool HasDisplayComponent() const; 72 RefPtr<TransformComponent> GetTransformComponent(); 73 RefPtr<TouchListenerComponent> GetTouchListenerComponent(); 74 bool HasTouchListenerComponent() const; 75 RefPtr<MouseListenerComponent> GetMouseListenerComponent(); 76 RefPtr<GestureListenerComponent> GetClickGestureListenerComponent(); 77 bool HasClickGestureListenerComponent() const; 78 RefPtr<GestureListenerComponent> GetPanGestureListenerComponent(); 79 RefPtr<FocusableComponent> GetFocusableComponent(bool createIfNotExist = true); 80 RefPtr<SharedTransitionComponent> GetSharedTransitionComponent(); 81 RefPtr<GestureComponent> GetGestureComponent(); 82 RefPtr<PositionedComponent> GetPositionedComponent(); 83 RefPtr<ComposedComponent> GetRootComponent(const std::string& id = "", const std::string& name = ""); 84 RefPtr<PageTransitionComponent> GetPageTransitionComponent(); 85 RefPtr<CoverageComponent> GetCoverageComponent(); 86 void ClearPageTransitionComponent(); 87 RefPtr<MenuComponent> GetMenuComponent(bool createNewComponent = true); 88 #ifndef WEARABLE_PRODUCT 89 RefPtr<PopupComponentV2> GetPopupComponent(bool createNewComponent = true); 90 #endif 91 92 // create wrappingComponentsMap and the component to map and then Push 93 // the map to the stack. 94 // use flag: isCustomView to avoid creating redundant Components. 95 void Push(const RefPtr<Component>& component, bool isCustomView = false); 96 97 // special versions of Push and Pop for JSGrid 98 // maintains a stack of GridLayoutComponent 99 // to be accessed when creating JSGridItems PushGrid(const RefPtr<GridLayoutComponent> & gridComponent)100 void PushGrid(const RefPtr<GridLayoutComponent>& gridComponent) 101 { 102 gridStack_.push(gridComponent); 103 Push(gridComponent); 104 } 105 PopGrid()106 void PopGrid() 107 { 108 if (!gridStack_.empty()) { 109 gridStack_.pop(); 110 } 111 Pop(); 112 } 113 GetTopGrid()114 RefPtr<GridLayoutComponent> GetTopGrid() const 115 { 116 if (gridStack_.empty()) { 117 return nullptr; 118 } 119 return gridStack_.top(); 120 } 121 122 // Push special tabs component for tabs, tabContent. PushTabs(const RefPtr<Component> & component)123 void PushTabs(const RefPtr<Component>& component) 124 { 125 tabsStack_.push(component); 126 } 127 PopTabs()128 void PopTabs() 129 { 130 tabsStack_.pop(); 131 } 132 GetTopTabs()133 RefPtr<Component> GetTopTabs() const 134 { 135 if (tabsStack_.empty()) { 136 return nullptr; 137 } 138 return tabsStack_.top(); 139 } 140 141 // Wrap the components map for the stack top and then pop the stack. 142 // Add the wrappedcomponent has child of the new stack top's main component. 143 void Pop(); 144 145 // pop the last container 146 void PopContainer(); 147 148 // End of Render function, create component tree. Finish()149 RefPtr<Component> Finish() 150 { 151 return FinishReturnMain().first; 152 } 153 154 // return mainComponent ... outmostWrappingComponent 155 // local Component to Element updates will be performed on these any any Component in-between 156 // returns the same cComponent twice if no wrapping Components. 157 std::pair<RefPtr<Component>, RefPtr<Component>> FinishReturnMain(); 158 Size()159 int32_t Size() const 160 { 161 return static_cast<int32_t>(componentsStack_.size()); 162 } 163 164 // Set key to be used for next custom component on the stack 165 void PushKey(const std::string& key); 166 167 // Returns a key for the CustomComponent if it has been pushed to the stack. Default is "" 168 std::string GetKey(); 169 170 // Takes care of the viewId wrt to foreach 171 std::string ProcessViewId(const std::string& viewId); 172 173 // Clear the key pushed to the stack 174 void PopKey(); 175 176 // Sets the implicit animation option. All the views use the same option. 177 void SetImplicitAnimationOption(const AnimationOption& option); 178 179 // Returns implicit animation option. 180 const AnimationOption& GetImplicitAnimationOption() const; 181 182 void SetZIndex(RefPtr<Component>& component); 183 bool ShouldPopImmediately(); 184 185 void SetIsPercentSize(RefPtr<Component>& component); 186 std::shared_ptr<JsPageRadioGroups> GetRadioGroupComponent(); 187 std::shared_ptr<JsPageCheckboxGroups> GetCheckboxGroupComponent(); 188 189 RefPtr<Component> GetNewComponent(); 190 RefPtr<V2::InspectorComposedComponent> GetInspectorComposedComponent() const; 191 SetVisualState(VisualState state)192 void SetVisualState(VisualState state) 193 { 194 visualState_ = state; 195 } 196 GetVisualState()197 VisualState GetVisualState() 198 { 199 return visualState_; 200 } 201 IsVisualStateSet()202 bool IsVisualStateSet() 203 { 204 return visualState_ != VisualState::NOTSET; 205 } 206 ClearVisualState()207 void ClearVisualState() 208 { 209 visualState_ = VisualState::NOTSET; 210 } 211 ClearStack()212 void ClearStack() 213 { 214 auto emptyStack = std::stack<std::unordered_map<std::string, RefPtr<Component>>>(); 215 componentsStack_.swap(emptyStack); 216 } 217 218 /** 219 * start 'get' access recording 220 * account all get access to given elmtId 221 * next component creation will claim the given elmtId 222 * see ClaimElementId() 223 */ StartGetAccessRecordingFor(int32_t elmtId)224 void StartGetAccessRecordingFor(int32_t elmtId) 225 { 226 accountGetAccessToElmtId_ = elmtId; 227 reservedElementId_ = elmtId; 228 } 229 230 /** 231 * Use reserved elementId for given component 232 * sets the reserved lemntId to none 233 */ 234 void ClaimElementId(const RefPtr<Component>& component); 235 ClaimElementId()236 int32_t ClaimElementId() 237 { 238 ACE_DCHECK( 239 (reservedElementId_ != ElementRegister::UndefinedElementId) && "No reserved elmtId, internal error!"); 240 const auto result = reservedElementId_; 241 reservedElementId_ = ElementRegister::UndefinedElementId; 242 return result; 243 } 244 245 /** 246 * get the elmtId to which all get access should be accounted 247 * ElementRegister::UndefinedElementId; means no get access recording enabled 248 */ GetElmtIdToAccountFor()249 ElementIdType GetElmtIdToAccountFor() 250 { 251 return accountGetAccessToElmtId_; 252 } SetElmtIdToAccountFor(ElementIdType elmtId)253 void SetElmtIdToAccountFor(ElementIdType elmtId) 254 { 255 accountGetAccessToElmtId_ = elmtId; 256 } 257 258 /** 259 * inverse of StartGetAccessRecordingFor 260 */ StopGetAccessRecording()261 void StopGetAccessRecording() 262 { 263 accountGetAccessToElmtId_ = ElementRegister::UndefinedElementId; 264 // normally already set like this, but just in case 265 reservedElementId_ = ElementRegister::UndefinedElementId; 266 } 267 RefPtr<ComposedComponent> CreateInspectorWrapper(const std::string& inspectorTag); 268 GetAndPushFrameNode(const std::string & tag,int32_t elmtId)269 void GetAndPushFrameNode(const std::string& tag, int32_t elmtId) 270 { 271 LOGW("NON NG ViewStackProcessor GetAndPushFrameNode()"); 272 // FrameNode is not available in NON-NG pipeline. 273 } 274 275 private: 276 ViewStackProcessor(); 277 278 #ifdef ACE_DEBUG 279 // Dump view stack comtent 280 void DumpStack(); 281 #endif 282 283 // Go through the wrappingComponentsMap and wrap the components 284 // should be done before pushing to the stack. 285 // returns pair(outmost wrapping Component, main Component) 286 std::pair<RefPtr<Component>, RefPtr<Component>> WrapComponents(); 287 288 // Update position and enabled status 289 void UpdateTopComponentProps(const RefPtr<Component>& component); 290 291 void CreateInspectorComposedComponent(const std::string& inspectorTag); 292 void CreateScoringComponent(const std::string& tag); 293 RefPtr<Component> GetScoringComponent() const; 294 295 // Singleton instance 296 static thread_local std::unique_ptr<ViewStackProcessor> instance; 297 298 // stack 299 std::stack<std::unordered_map<std::string, RefPtr<Component>>> componentsStack_; 300 std::shared_ptr<JsPageRadioGroups> radioGroups_; 301 std::shared_ptr<JsPageCheckboxGroups> checkboxGroups_; 302 // stack for tabs component. 303 std::stack<RefPtr<Component>> tabsStack_; 304 305 // stack for Grid component. 306 std::stack<RefPtr<GridLayoutComponent>> gridStack_; 307 308 RefPtr<PageTransitionComponent> pageTransitionComponent_; 309 310 std::string viewKey_; 311 std::stack<size_t> keyStack_; 312 313 RefPtr<AccessibilityManager> accessibilityManager_; 314 std::stack<int32_t> parentIdStack_; 315 316 AnimationOption implicitAnimationOption_; 317 VisualState visualState_ = VisualState::NOTSET; 318 319 bool isScoringEnable_ = false; 320 321 // elmtId reserved for next component creation 322 ElementIdType reservedElementId_ = ElementRegister::UndefinedElementId; 323 324 // elmtId to accouunt get access to 325 ElementIdType accountGetAccessToElmtId_ = ElementRegister::UndefinedElementId; 326 327 ACE_DISALLOW_COPY_AND_MOVE(ViewStackProcessor); 328 }; 329 330 class ScopedViewStackProcessor final { 331 public: 332 ScopedViewStackProcessor(); 333 ~ScopedViewStackProcessor(); 334 335 private: 336 std::unique_ptr<ViewStackProcessor> instance_; 337 338 ACE_DISALLOW_COPY_AND_MOVE(ScopedViewStackProcessor); 339 }; 340 341 } // namespace OHOS::Ace::Framework 342 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_VIEW_STACK_PROCESSOR_H 343