/* * Copyright (c) 2021-2022 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" #ifndef NG_BUILD #include "core/components/checkable/radio_group_component.h" #endif #include "core/components/page/page_target.h" #include "core/components/page_transition/page_transition_component.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::NG { class UINode; } // namespace OHOS::Ace::NG namespace OHOS::Ace::Framework { #ifndef NG_BUILD class DOMDocument; using JsPageRadioGroups = std::unordered_map>; #endif const char MERGE_SOURCEMAPS_PATH[] = "sourceMaps.map"; // One JsAcePage corresponding to a JS bundle, so it should maintain page's lifecycle. class ACE_FORCE_EXPORT JsAcePage final : public AcePage { DECLARE_ACE_TYPE(JsAcePage, AcePage); public: #ifdef NG_BUILD JsAcePage(int32_t pageId, const std::string& url); #else JsAcePage(int32_t pageId, const RefPtr& document, const std::string& url, const WeakPtr& container = nullptr); #endif ~JsAcePage() override; RefPtr BuildPage(const std::string& url) override; #ifndef NG_BUILD RefPtr BuildPagePatch(int32_t nodeId); RefPtr GetDomDocument() const { return domDoc_; } #endif const std::string& GetUrl() const { return url_; } bool CheckPageCreated() const { return pageCreated_; } void SetPageCreated() { pageCreated_ = true; } #ifndef NG_BUILD 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_); } #endif 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(); } #ifndef NG_BUILD 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; } #endif 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 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_; } #ifndef NG_BUILD size_t GetCommandSize() const { return jsCommands_.size(); } #endif 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; } 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); #ifndef NG_BUILD std::shared_ptr GetRadioGroups(); #endif void SetRootComponent(const RefPtr& component) { component_ = component; } void SetRootNode(const RefPtr& node); const RefPtr& GetRootNode() const { return pageRootNode_; } 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 SetDeclarativeOnUpdateWithValueParamsCallback(std::function&& callback) { onUpdateWithValueParams_ = 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 FireDeclarativeOnUpdateWithValueParamsCallback(const std::string& params) const { if (onUpdateWithValueParams_) { onUpdateWithValueParams_(params); } } void OnJsEngineDestroy(); private: #ifndef NG_BUILD void SwapBackgroundDecoration(const RefPtr& transition); #endif std::string GetCardId() const; bool pageCreated_ = false; #ifndef NG_BUILD bool showCommandConsumed_ = false; #endif int32_t fragmentCount_ = 0; WeakPtr pipelineContext_; RefPtr pageTransition_; RefPtr component_; RefPtr pageRootNode_; RefPtr domDoc_; std::string url_; WeakPtr container_; RefPtr pageMap_; RefPtr appMap_; bool useLiteStyle_ = false; bool useBoxWrap_ = 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> animatorInfos_; #ifndef NG_BUILD std::shared_ptr radioGroups_; #endif std::function onPageAppear_; std::function onPageDisAppear_; std::function onBackPress_; std::function onPageRefresh_; std::function onUpdateWithValueParams_; }; } // namespace OHOS::Ace::Framework #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H