1 /* 2 * Copyright (c) 2021 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 FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H 18 19 #include <mutex> 20 #include <string> 21 #include <unordered_set> 22 #include <functional> 23 #include <vector> 24 25 #include "base/utils/macros.h" 26 #include "core/animation/animator_info.h" 27 #include "core/common/ace_page.h" 28 #include "core/common/thread_checker.h" 29 #include "core/components/checkable/radio_group_component.h" 30 #include "core/components/page/page_target.h" 31 #include "core/components/page_transition/page_transition_component.h" 32 #include "frameworks/bridge/common/dom/dom_document.h" 33 #include "frameworks/bridge/common/utils/source_map.h" 34 #include "frameworks/bridge/common/utils/utils.h" 35 #include "frameworks/bridge/js_frontend/engine/common/base_animation_bridge.h" 36 #include "frameworks/bridge/js_frontend/engine/common/base_canvas_bridge.h" 37 #include "frameworks/bridge/js_frontend/engine/common/base_xcomponent_bridge.h" 38 #include "frameworks/bridge/js_frontend/js_command.h" 39 40 namespace OHOS::Ace::Framework { 41 42 using JsPageRadioGroups = std::unordered_map<std::string, RadioGroupComponent<std::string>>; 43 44 // One JsAcePage corresponding to a JS bundle, so it should maintain page's lifecycle. 45 class ACE_EXPORT JsAcePage final : public AcePage { 46 DECLARE_ACE_TYPE(JsAcePage, AcePage); 47 48 public: 49 JsAcePage(int32_t pageId, const RefPtr<DOMDocument>& document, const std::string& url, 50 const WeakPtr<StageElement>& container = nullptr) AcePage(pageId)51 : AcePage(pageId), domDoc_(document), url_(url), container_(container), 52 radioGroups_(std::make_shared<JsPageRadioGroups>()) 53 { 54 ACE_DCHECK(domDoc_); 55 } 56 57 ~JsAcePage() override; 58 59 RefPtr<PageComponent> BuildPage(const std::string& url) override; 60 RefPtr<ComposedComponent> BuildPagePatch(int32_t nodeId); 61 GetDomDocument()62 RefPtr<DOMDocument> GetDomDocument() const 63 { 64 return domDoc_; 65 } 66 GetUrl()67 const std::string& GetUrl() const 68 { 69 return url_; 70 } 71 CheckPageCreated()72 bool CheckPageCreated() const 73 { 74 return pageCreated_; 75 } 76 SetPageCreated()77 void SetPageCreated() 78 { 79 pageCreated_ = true; 80 } 81 SetPageTransition(const RefPtr<PageTransitionComponent> & pageTransition)82 void SetPageTransition(const RefPtr<PageTransitionComponent>& pageTransition) 83 { 84 pageTransition_ = pageTransition; 85 } 86 PushCommand(const RefPtr<JsCommand> & jsCommand)87 void PushCommand(const RefPtr<JsCommand>& jsCommand) 88 { 89 jsCommands_.emplace_back(jsCommand); 90 } 91 PopAllCommands(std::vector<RefPtr<JsCommand>> & jsCommands)92 void PopAllCommands(std::vector<RefPtr<JsCommand>>& jsCommands) 93 { 94 jsCommands = std::move(jsCommands_); 95 } 96 PushNewNode(NodeId nodeId,NodeId parentNodeId)97 void PushNewNode(NodeId nodeId, NodeId parentNodeId) 98 { 99 CHECK_RUN_ON(UI); 100 dirtyNodes_.emplace(nodeId); 101 PushDirtyNode(parentNodeId); 102 } 103 PushDirtyNode(NodeId nodeId)104 void PushDirtyNode(NodeId nodeId) 105 { 106 CHECK_RUN_ON(UI); 107 auto result = dirtyNodes_.emplace(nodeId); 108 if (result.second) { 109 dirtyNodesOrderedByTime_.emplace_back(nodeId); 110 } 111 } 112 PopAllDirtyNodes(std::vector<NodeId> & dirtyNodes)113 void PopAllDirtyNodes(std::vector<NodeId>& dirtyNodes) 114 { 115 CHECK_RUN_ON(UI); 116 dirtyNodes = std::move(dirtyNodesOrderedByTime_); 117 dirtyNodes_.clear(); 118 } 119 ClearAllDirtyNodes()120 void ClearAllDirtyNodes() 121 { 122 CHECK_RUN_ON(UI); 123 dirtyNodesOrderedByTime_.clear(); 124 dirtyNodes_.clear(); 125 } 126 ReserveShowCommand(const RefPtr<JsCommand> & command)127 void ReserveShowCommand(const RefPtr<JsCommand>& command) 128 { 129 if (command) { 130 std::unique_lock<std::mutex> lock(cmdMutex_); 131 showCommands_.emplace_back(command); 132 } 133 } 134 UpdateShowAttr()135 void UpdateShowAttr() 136 { 137 CHECK_RUN_ON(UI); 138 std::unique_lock<std::mutex> lock(cmdMutex_); 139 if (showCommands_.empty()) { 140 return; 141 } 142 143 for (auto& command : showCommands_) { 144 command->Execute(AceType::Claim(this)); 145 } 146 showCommandConsumed_ = true; 147 } 148 CheckShowCommandConsumed()149 bool CheckShowCommandConsumed() const 150 { 151 return showCommandConsumed_; 152 } 153 ClearShowCommand()154 void ClearShowCommand() 155 { 156 std::unique_lock<std::mutex> lock(cmdMutex_); 157 showCommands_.clear(); 158 showCommandConsumed_ = false; 159 } 160 161 RefPtr<BaseCanvasBridge> GetBridgeById(NodeId nodeId); 162 void PushCanvasBridge(NodeId nodeId, const RefPtr<BaseCanvasBridge>& bridge); 163 void PushOffscreenCanvasBridge(int32_t bridgeId, const RefPtr<BaseCanvasBridge>& bridge); 164 RefPtr<BaseCanvasBridge> GetOffscreenCanvasBridgeById(int32_t nodeId); 165 166 RefPtr<BaseXComponentBridge> GetXComponentBridgeById(NodeId nodeId); 167 void PushXComponentBridge(NodeId nodeId, const RefPtr<BaseXComponentBridge>& bridge); 168 169 RefPtr<BaseAnimationBridge> GetAnimationBridge(NodeId nodeId); 170 void RemoveAnimationBridge(NodeId nodeId); 171 void AddAnimationBridge(NodeId nodeId, const RefPtr<BaseAnimationBridge>& animationBridge); 172 173 RefPtr<BaseAnimationBridge> GetAnimatorBridge(int32_t bridgeId); 174 void RemoveAnimatorBridge(int32_t bridgeId); 175 void AddAnimatorBridge(int32_t bridgeId, const RefPtr<BaseAnimationBridge>& animatorBridge); 176 177 RefPtr<Curve> GetCurve(const std::string& curveString); 178 void RemoveCurve(const std::string& curveString); 179 void AddCurve(const std::string& curveString, const RefPtr<Curve>& curve); 180 181 RefPtr<AnimatorInfo> GetAnimatorInfo(const std::string& animatorId); 182 void RemoveAnimatorInfo(const std::string& animatorId); 183 void AddAnimatorInfo(const std::string animatorId, const RefPtr<AnimatorInfo>& animatorInfo); 184 SetPageParams(const std::string & params)185 void SetPageParams(const std::string& params) 186 { 187 pageParams_ = params; 188 } 189 GetPageParams()190 const std::string& GetPageParams() const 191 { 192 return pageParams_; 193 } 194 SetFlushCallback(std::function<void (const RefPtr<JsAcePage> &)> && callback)195 void SetFlushCallback(std::function<void(const RefPtr<JsAcePage>&)>&& callback) 196 { 197 flushCallback_ = std::move(callback); 198 } 199 FlushCommands()200 void FlushCommands() 201 { 202 if (flushCallback_) { 203 fragmentCount_++; 204 flushCallback_(AceType::Claim(this)); 205 } 206 } 207 FragmentCount()208 int32_t FragmentCount() const 209 { 210 return fragmentCount_; 211 } 212 GetCommandSize()213 size_t GetCommandSize() const 214 { 215 return jsCommands_.size(); 216 } 217 SetPipelineContext(const WeakPtr<PipelineContext> & pipelineContext)218 void SetPipelineContext(const WeakPtr<PipelineContext>& pipelineContext) 219 { 220 pipelineContext_ = pipelineContext; 221 } 222 GetPipelineContext()223 WeakPtr<PipelineContext> GetPipelineContext() const 224 { 225 return pipelineContext_; 226 } 227 IsLiteStyle()228 bool IsLiteStyle() const 229 { 230 return useLiteStyle_; 231 } 232 SetUseLiteStyle(bool useLiteStyle)233 void SetUseLiteStyle(bool useLiteStyle) 234 { 235 useLiteStyle_ = useLiteStyle; 236 } 237 IsUseBoxWrap()238 bool IsUseBoxWrap() const 239 { 240 return useBoxWrap_; 241 } 242 SetUseBoxWrap(bool useBoxWrap)243 void SetUseBoxWrap(bool useBoxWrap) 244 { 245 useBoxWrap_ = useBoxWrap; 246 } 247 IsUsePluginComponent()248 bool IsUsePluginComponent() const 249 { 250 return usePluginComponent_; 251 } 252 SetUsePluginComponent(bool usePluginComponent)253 void SetUsePluginComponent(bool usePluginComponent) 254 { 255 usePluginComponent_ = usePluginComponent; 256 } 257 GetPluginComponentJsonData()258 const std::string& GetPluginComponentJsonData() const 259 { 260 return pluginComponentJsonData_; 261 } 262 SetPluginComponentJsonData(const std::string & pluginComponentJsonData)263 void SetPluginComponentJsonData(const std::string& pluginComponentJsonData) 264 { 265 pluginComponentJsonData_ = pluginComponentJsonData; 266 } 267 268 void AddNodeEvent(int32_t nodeId, const std::string& actionType, const std::string& eventAction); 269 270 std::string GetNodeEventAction(int32_t nodeId, const std::string& actionType); 271 std::shared_ptr<JsPageRadioGroups> GetRadioGroups(); 272 SetRootComponent(const RefPtr<Component> & component)273 void SetRootComponent(const RefPtr<Component>& component) 274 { 275 component_ = component; 276 } 277 SetPageMap(const std::string & pageMap)278 void SetPageMap(const std::string& pageMap) 279 { 280 pageMap_ = AceType::MakeRefPtr<RevSourceMap>(); 281 pageMap_->Init(pageMap); 282 } 283 GetPageMap()284 RefPtr<RevSourceMap> GetPageMap() const 285 { 286 return pageMap_; 287 } 288 SetAppMap(const std::string & appMap)289 void SetAppMap(const std::string& appMap) 290 { 291 appMap_ = AceType::MakeRefPtr<RevSourceMap>(); 292 appMap_->Init(appMap); 293 } 294 GetAppMap()295 RefPtr<RevSourceMap> GetAppMap() const 296 { 297 return appMap_; 298 } 299 GetStageElement()300 RefPtr<StageElement> GetStageElement() const 301 { 302 return container_.Upgrade(); 303 } 304 SetDeclarativeOnPageAppearCallback(std::function<void ()> && callback)305 void SetDeclarativeOnPageAppearCallback(std::function<void()>&& callback) 306 { 307 onPageAppear_ = callback; 308 } 309 SetDeclarativeOnPageDisAppearCallback(std::function<void ()> && callback)310 void SetDeclarativeOnPageDisAppearCallback(std::function<void()>&& callback) 311 { 312 onPageDisAppear_ = callback; 313 } 314 SetDeclarativeOnBackPressCallback(std::function<bool ()> && callback)315 void SetDeclarativeOnBackPressCallback(std::function<bool()>&& callback) 316 { 317 onBackPress_ = callback; 318 } 319 SetDeclarativeOnPageRefreshCallback(std::function<void ()> && callback)320 void SetDeclarativeOnPageRefreshCallback(std::function<void()>&& callback) 321 { 322 onPageRefresh_ = callback; 323 } 324 FireDeclarativeOnPageAppearCallback()325 void FireDeclarativeOnPageAppearCallback() const 326 { 327 if (onPageAppear_) { 328 onPageAppear_(); 329 } 330 } 331 FireDeclarativeOnPageDisAppearCallback()332 void FireDeclarativeOnPageDisAppearCallback() const 333 { 334 if (onPageDisAppear_) { 335 onPageDisAppear_(); 336 } 337 } 338 FireDeclarativeOnBackPressCallback()339 bool FireDeclarativeOnBackPressCallback() const 340 { 341 if (onBackPress_) { 342 return onBackPress_(); 343 } 344 return false; 345 } 346 FireDeclarativeOnPageRefreshCallback()347 void FireDeclarativeOnPageRefreshCallback() const 348 { 349 if (onPageRefresh_) { 350 onPageRefresh_(); 351 } 352 } 353 354 void OnJsEngineDestroy(); 355 356 private: 357 void SwapBackgroundDecoration(const RefPtr<PageTransitionComponent>& transition); 358 std::string GetCardId() const; 359 360 bool pageCreated_ = false; 361 bool showCommandConsumed_ = false; 362 int32_t fragmentCount_ = 0; 363 364 WeakPtr<PipelineContext> pipelineContext_; 365 RefPtr<PageTransitionComponent> pageTransition_; 366 RefPtr<Component> component_; 367 RefPtr<DOMDocument> domDoc_; 368 std::string url_; 369 WeakPtr<StageElement> container_; 370 371 RefPtr<RevSourceMap> pageMap_; 372 RefPtr<RevSourceMap> appMap_; 373 bool useLiteStyle_ = false; 374 bool useBoxWrap_ = false; 375 bool usePluginComponent_ = false; 376 std::string pluginComponentJsonData_; 377 378 std::vector<RefPtr<JsCommand>> jsCommands_; 379 std::vector<NodeId> dirtyNodesOrderedByTime_; 380 std::unordered_set<NodeId> dirtyNodes_; 381 std::mutex cmdMutex_; 382 std::vector<RefPtr<JsCommand>> showCommands_; 383 std::function<void(const RefPtr<JsAcePage>&)> flushCallback_; 384 std::string pageParams_; 385 std::mutex eventMutex_; 386 std::unordered_map<NodeId, std::unordered_map<std::string, std::string>> nodeEvent_; 387 std::mutex bridgeMutex_; 388 std::unordered_map<NodeId, RefPtr<BaseAnimationBridge>> animationBridges_; 389 std::unordered_map<NodeId, RefPtr<BaseCanvasBridge>> canvasBridges_; 390 std::unordered_map<int32_t, RefPtr<BaseCanvasBridge>> offscreenCanvasBridges_; 391 std::unordered_map<NodeId, RefPtr<BaseXComponentBridge>> xcomponentBridges_; 392 std::unordered_map<int32_t, RefPtr<BaseAnimationBridge>> animatorBridges_; 393 std::unordered_map<std::string, RefPtr<Curve>> curves_; 394 std::unordered_map<std::string, RefPtr<AnimatorInfo>> animatorInfos_; 395 std::shared_ptr<JsPageRadioGroups> radioGroups_; 396 397 std::function<void()> onPageAppear_; 398 std::function<void()> onPageDisAppear_; 399 std::function<bool()> onBackPress_; 400 std::function<void()> onPageRefresh_; 401 }; 402 403 } // namespace OHOS::Ace::Framework 404 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H 405