/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H #include #include #include #include #include #include "base/utils/macros.h" #include "core/animation/animator_info.h" #include "core/common/ace_page.h" #include "core/common/thread_checker.h" #include "core/components/checkable/radio_group_component.h" #include "core/components/page/page_target.h" #include "core/components/page_transition/page_transition_component.h" #include "frameworks/bridge/common/dom/dom_document.h" #include "frameworks/bridge/common/utils/source_map.h" #include "frameworks/bridge/common/utils/utils.h" #include "frameworks/bridge/js_frontend/engine/common/base_animation_bridge.h" #include "frameworks/bridge/js_frontend/engine/common/base_canvas_bridge.h" #include "frameworks/bridge/js_frontend/engine/common/base_xcomponent_bridge.h" #include "frameworks/bridge/js_frontend/js_command.h" namespace OHOS::Ace::Framework { using JsPageRadioGroups = std::unordered_map>; // One JsAcePage corresponding to a JS bundle, so it should maintain page's lifecycle. class ACE_EXPORT JsAcePage final : public AcePage { DECLARE_ACE_TYPE(JsAcePage, AcePage); public: JsAcePage(int32_t pageId, const RefPtr& document, const std::string& url, const WeakPtr& container = nullptr) : AcePage(pageId), domDoc_(document), url_(url), container_(container), radioGroups_(std::make_shared()) { ACE_DCHECK(domDoc_); } ~JsAcePage() override; RefPtr BuildPage(const std::string& url) override; RefPtr BuildPagePatch(int32_t nodeId); RefPtr GetDomDocument() const { return domDoc_; } const std::string& GetUrl() const { return url_; } bool CheckPageCreated() const { return pageCreated_; } void SetPageCreated() { pageCreated_ = true; } void SetPageTransition(const RefPtr& pageTransition) { pageTransition_ = pageTransition; } void PushCommand(const RefPtr& jsCommand) { jsCommands_.emplace_back(jsCommand); } void PopAllCommands(std::vector>& jsCommands) { jsCommands = std::move(jsCommands_); } void PushNewNode(NodeId nodeId, NodeId parentNodeId) { CHECK_RUN_ON(UI); dirtyNodes_.emplace(nodeId); PushDirtyNode(parentNodeId); } void PushDirtyNode(NodeId nodeId) { CHECK_RUN_ON(UI); auto result = dirtyNodes_.emplace(nodeId); if (result.second) { dirtyNodesOrderedByTime_.emplace_back(nodeId); } } void PopAllDirtyNodes(std::vector& dirtyNodes) { CHECK_RUN_ON(UI); dirtyNodes = std::move(dirtyNodesOrderedByTime_); dirtyNodes_.clear(); } void ClearAllDirtyNodes() { CHECK_RUN_ON(UI); dirtyNodesOrderedByTime_.clear(); dirtyNodes_.clear(); } void ReserveShowCommand(const RefPtr& command) { if (command) { std::unique_lock lock(cmdMutex_); showCommands_.emplace_back(command); } } void UpdateShowAttr() { CHECK_RUN_ON(UI); std::unique_lock lock(cmdMutex_); if (showCommands_.empty()) { return; } for (auto& command : showCommands_) { command->Execute(AceType::Claim(this)); } showCommandConsumed_ = true; } bool CheckShowCommandConsumed() const { return showCommandConsumed_; } void ClearShowCommand() { std::unique_lock lock(cmdMutex_); showCommands_.clear(); showCommandConsumed_ = false; } RefPtr GetBridgeById(NodeId nodeId); void PushCanvasBridge(NodeId nodeId, const RefPtr& bridge); void PushOffscreenCanvasBridge(int32_t bridgeId, const RefPtr& bridge); RefPtr GetOffscreenCanvasBridgeById(int32_t nodeId); RefPtr GetXComponentBridgeById(NodeId nodeId); void PushXComponentBridge(NodeId nodeId, const RefPtr& bridge); RefPtr GetAnimationBridge(NodeId nodeId); void RemoveAnimationBridge(NodeId nodeId); void AddAnimationBridge(NodeId nodeId, const RefPtr& animationBridge); RefPtr GetAnimatorBridge(int32_t bridgeId); void RemoveAnimatorBridge(int32_t bridgeId); void AddAnimatorBridge(int32_t bridgeId, const RefPtr& animatorBridge); RefPtr GetCurve(const std::string& curveString); void RemoveCurve(const std::string& curveString); void AddCurve(const std::string& curveString, const RefPtr& curve); RefPtr GetAnimatorInfo(const std::string& animatorId); void RemoveAnimatorInfo(const std::string& animatorId); void AddAnimatorInfo(const std::string animatorId, const RefPtr& animatorInfo); void SetPageParams(const std::string& params) { pageParams_ = params; } const std::string& GetPageParams() const { return pageParams_; } void SetFlushCallback(std::function&)>&& callback) { flushCallback_ = std::move(callback); } void FlushCommands() { if (flushCallback_) { fragmentCount_++; flushCallback_(AceType::Claim(this)); } } int32_t FragmentCount() const { return fragmentCount_; } size_t GetCommandSize() const { return jsCommands_.size(); } void SetPipelineContext(const WeakPtr& pipelineContext) { pipelineContext_ = pipelineContext; } WeakPtr GetPipelineContext() const { return pipelineContext_; } bool IsLiteStyle() const { return useLiteStyle_; } void SetUseLiteStyle(bool useLiteStyle) { useLiteStyle_ = useLiteStyle; } bool IsUseBoxWrap() const { return useBoxWrap_; } void SetUseBoxWrap(bool useBoxWrap) { useBoxWrap_ = useBoxWrap; } bool IsUsePluginComponent() const { return usePluginComponent_; } void SetUsePluginComponent(bool usePluginComponent) { usePluginComponent_ = usePluginComponent; } const std::string& GetPluginComponentJsonData() const { return pluginComponentJsonData_; } void SetPluginComponentJsonData(const std::string& pluginComponentJsonData) { pluginComponentJsonData_ = pluginComponentJsonData; } void AddNodeEvent(int32_t nodeId, const std::string& actionType, const std::string& eventAction); std::string GetNodeEventAction(int32_t nodeId, const std::string& actionType); std::shared_ptr GetRadioGroups(); void SetRootComponent(const RefPtr& component) { component_ = component; } void SetPageMap(const std::string& pageMap) { pageMap_ = AceType::MakeRefPtr(); pageMap_->Init(pageMap); } RefPtr GetPageMap() const { return pageMap_; } void SetAppMap(const std::string& appMap) { appMap_ = AceType::MakeRefPtr(); appMap_->Init(appMap); } RefPtr GetAppMap() const { return appMap_; } RefPtr GetStageElement() const { return container_.Upgrade(); } void SetDeclarativeOnPageAppearCallback(std::function&& callback) { onPageAppear_ = callback; } void SetDeclarativeOnPageDisAppearCallback(std::function&& callback) { onPageDisAppear_ = callback; } void SetDeclarativeOnBackPressCallback(std::function&& callback) { onBackPress_ = callback; } void SetDeclarativeOnPageRefreshCallback(std::function&& callback) { onPageRefresh_ = callback; } void FireDeclarativeOnPageAppearCallback() const { if (onPageAppear_) { onPageAppear_(); } } void FireDeclarativeOnPageDisAppearCallback() const { if (onPageDisAppear_) { onPageDisAppear_(); } } bool FireDeclarativeOnBackPressCallback() const { if (onBackPress_) { return onBackPress_(); } return false; } void FireDeclarativeOnPageRefreshCallback() const { if (onPageRefresh_) { onPageRefresh_(); } } void OnJsEngineDestroy(); private: void SwapBackgroundDecoration(const RefPtr& transition); std::string GetCardId() const; bool pageCreated_ = false; bool showCommandConsumed_ = false; int32_t fragmentCount_ = 0; WeakPtr pipelineContext_; RefPtr pageTransition_; RefPtr component_; RefPtr domDoc_; std::string url_; WeakPtr container_; RefPtr pageMap_; RefPtr appMap_; bool useLiteStyle_ = false; bool useBoxWrap_ = false; bool usePluginComponent_ = false; std::string pluginComponentJsonData_; std::vector> jsCommands_; std::vector dirtyNodesOrderedByTime_; std::unordered_set dirtyNodes_; std::mutex cmdMutex_; std::vector> showCommands_; std::function&)> flushCallback_; std::string pageParams_; std::mutex eventMutex_; std::unordered_map> nodeEvent_; std::mutex bridgeMutex_; std::unordered_map> animationBridges_; std::unordered_map> canvasBridges_; std::unordered_map> offscreenCanvasBridges_; std::unordered_map> xcomponentBridges_; std::unordered_map> animatorBridges_; std::unordered_map> curves_; std::unordered_map> animatorInfos_; std::shared_ptr radioGroups_; std::function onPageAppear_; std::function onPageDisAppear_; std::function onBackPress_; std::function onPageRefresh_; }; } // namespace OHOS::Ace::Framework #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H