1 /* 2 * Copyright (c) 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 FOUNDATION_ACE_FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_PAGE_ROUTER_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_PAGE_ROUTER_MANAGER_H 18 19 #include <cstdint> 20 #include <list> 21 #include <string> 22 #include <utility> 23 24 #include "base/memory/ace_type.h" 25 #include "base/memory/referenced.h" 26 #include "base/thread/task_executor.h" 27 #include "base/utils/noncopyable.h" 28 #include "bridge/declarative_frontend/ng/entry_page_info.h" 29 #include "core/components_ng/base/frame_node.h" 30 #include "frameworks/bridge/common/manifest/manifest_parser.h" 31 #include "interfaces/inner_api/ace/constants.h" 32 #include "bridge/js_frontend/frontend_delegate.h" 33 34 namespace OHOS::Ace::NG { 35 36 using LoadPageCallback = std::function<bool(const std::string&, 37 const std::function<void(const std::string&, int32_t)>&)>; 38 using LoadPageByBufferCallback = std::function<bool(const std::shared_ptr<std::vector<uint8_t>>& content, 39 const std::function<void(const std::string&, int32_t)>&, const std::string& contentName)>; 40 using LoadCardCallback = std::function<bool(const std::string&, int64_t cardId, const std::string&)>; 41 using LoadNamedRouterCallback = std::function<bool(const std::string&, bool isTriggeredByJs)>; 42 using UpdateRootComponentCallback = std::function<bool()>; 43 #if defined(PREVIEW) 44 using IsComponentPreviewCallback = std::function<bool()>; 45 #endif 46 47 enum class RouterMode { 48 STANDARD = 0, 49 SINGLE, 50 }; 51 52 struct RouterPageInfo { 53 std::string url; 54 std::string params; 55 RouterMode routerMode = RouterMode::STANDARD; 56 std::function<void(const std::string&, int32_t)> errorCallback; 57 std::string path; 58 bool isNamedRouterMode = false; 59 std::shared_ptr<std::vector<uint8_t>> content; 60 }; 61 62 class PageRouterManager : public AceType { 63 DECLARE_ACE_TYPE(PageRouterManager, AceType) 64 public: 65 PageRouterManager() = default; 66 ~PageRouterManager() override = default; 67 68 void RunPage(const std::string& url, const std::string& params); 69 void RunPage(const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params); 70 void RunPageByNamedRouter(const std::string& name, const std::string& params); 71 UIContentErrorCode RunCard( 72 const std::string& url, const std::string& params, int64_t cardId, const std::string& entryPoint = ""); 73 SetManifestParser(const RefPtr<Framework::ManifestParser> & manifestParser)74 void SetManifestParser(const RefPtr<Framework::ManifestParser>& manifestParser) 75 { 76 manifestParser_ = manifestParser; 77 } 78 SetLoadJsCallback(LoadPageCallback && callback)79 void SetLoadJsCallback(LoadPageCallback&& callback) 80 { 81 loadJs_ = std::move(callback); 82 } 83 SetLoadJsByBufferCallback(LoadPageByBufferCallback && callback)84 void SetLoadJsByBufferCallback(LoadPageByBufferCallback&& callback) 85 { 86 loadJsByBuffer_ = std::move(callback); 87 } 88 SetLoadCardCallback(const LoadCardCallback & callback)89 void SetLoadCardCallback(const LoadCardCallback& callback) 90 { 91 loadCard_ = callback; 92 } 93 SetLoadNamedRouterCallback(LoadNamedRouterCallback && callback)94 void SetLoadNamedRouterCallback(LoadNamedRouterCallback&& callback) 95 { 96 loadNamedRouter_ = callback; 97 } 98 SetUpdateRootComponentCallback(UpdateRootComponentCallback && callback)99 void SetUpdateRootComponentCallback(UpdateRootComponentCallback&& callback) 100 { 101 updateRootComponent_ = callback; 102 } 103 #if defined(PREVIEW) SetIsComponentPreview(IsComponentPreviewCallback && callback)104 void SetIsComponentPreview(IsComponentPreviewCallback&& callback) 105 { 106 isComponentPreview_ = callback; 107 } 108 #endif 109 110 void EnableAlertBeforeBackPage(const std::string& message, std::function<void(int32_t)>&& callback); 111 112 void DisableAlertBeforeBackPage(); 113 114 // router operation 115 void Push(const RouterPageInfo& target); 116 void PushNamedRoute(const RouterPageInfo& target); 117 bool Pop(); 118 void Replace(const RouterPageInfo& target); 119 void ReplaceNamedRoute(const RouterPageInfo& target); 120 void BackWithTarget(const RouterPageInfo& target); 121 void BackToIndexWithTarget(int32_t index, const std::string& params); 122 void Clear(); 123 int32_t GetStackSize() const; 124 RouterPageInfo GetPageInfoByIndex(int32_t index, const std::string& params); 125 126 void GetState(int32_t& index, std::string& name, std::string& path); 127 void GetStateByIndex(int32_t index, std::string& name, std::string& path, std::string& params); 128 void GetStateByUrl(std::string& url, std::vector<Framework::StateInfo>& stateArray); 129 130 void GetPageNameAndPath(const RefPtr<FrameNode>& pageNode, std::string& name, std::string& path); 131 int32_t GetPageIndex(const WeakPtr<FrameNode>& page); 132 133 std::string GetParams() const; 134 135 int32_t GetIndexByUrl(const std::string& url) const; 136 GetCurrentPageNode()137 RefPtr<FrameNode> GetCurrentPageNode() const 138 { 139 if (pageRouterStack_.empty()) { 140 return nullptr; 141 } 142 return pageRouterStack_.back().Upgrade(); 143 } 144 145 std::string GetCurrentPageUrl(); 146 147 // Get the currently running JS page information in NG structure. 148 RefPtr<Framework::RevSourceMap> GetCurrentPageSourceMap(const RefPtr<AssetManager>& assetManager); 149 SetIsCard()150 void SetIsCard() 151 { 152 isCardRouter_ = true; 153 } 154 155 void FlushFrontend(); 156 157 std::unique_ptr<JsonValue> GetStackInfo(); 158 159 std::pair<std::string, UIContentErrorCode> RestoreRouterStack(std::unique_ptr<JsonValue> stackInfo); 160 161 protected: 162 class RouterOptScope { 163 public: RouterOptScope(PageRouterManager * manager)164 explicit RouterOptScope(PageRouterManager* manager) : manager_(manager) 165 { 166 manager_->inRouterOpt_ = true; 167 } ~RouterOptScope()168 ~RouterOptScope() 169 { 170 manager_->inRouterOpt_ = false; 171 } 172 173 private: 174 PageRouterManager* manager_ = nullptr; 175 }; 176 177 // page id manage 178 int32_t GenerateNextPageId(); 179 GetLastPageIndex()180 virtual int32_t GetLastPageIndex() 181 { 182 return static_cast<int32_t>(pageRouterStack_.size()) - 1; 183 } 184 185 std::pair<int32_t, RefPtr<FrameNode>> FindPageInStack(const std::string& url, bool needIgnoreBegin = false); 186 std::pair<int32_t, RefPtr<FrameNode>> FindPageInStackByRouteName(const std::string& name) const; 187 188 void SetPageInfoRouteName(const RefPtr<EntryPageInfo>& info, bool isNamedRouterMode); 189 190 void LoadOhmUrl(const RouterPageInfo& target); 191 void PushOhmUrl(const RouterPageInfo& target); 192 void ReplaceOhmUrl(const RouterPageInfo& target); 193 void StartPush(const RouterPageInfo& target); 194 void StartReplace(const RouterPageInfo& target); 195 void StartBack(const RouterPageInfo& target); 196 void StartBackToIndex(int32_t index, const std::string& params); 197 bool StartPop(); 198 void StartRestore(const RouterPageInfo& target); 199 void BackCheckAlert(const RouterPageInfo& target); 200 void BackToIndexCheckAlert(int32_t index, const std::string& params); 201 void StartClean(); 202 void CleanPageOverlay(); 203 204 // page operations 205 virtual void LoadPage(int32_t pageId, const RouterPageInfo& target, 206 bool needHideLast = true, bool needTransition = true, bool isPush = false); 207 void MovePageToFront(int32_t index, const RefPtr<FrameNode>& pageNode, const RouterPageInfo& target, 208 bool needHideLast, bool forceShowCurrent = false, bool needTransition = true); 209 void PopPage(const std::string& params, bool needShowNext, bool needTransition); 210 void PopPageToIndex(int32_t index, const std::string& params, bool needShowNext, bool needTransition); 211 void DealReplacePage(const RouterPageInfo& target); 212 virtual void ReplacePageInNewLifecycle(const RouterPageInfo& info); 213 214 static bool OnPageReady(const RefPtr<FrameNode>& pageNode, bool needHideLast, bool needTransition, 215 bool isCardRouter = false, int64_t cardId = 0); 216 static bool OnPopPage(bool needShowNext, bool needTransition); 217 static bool OnPopPageToIndex(int32_t index, bool needShowNext, bool needTransition); 218 static bool OnCleanPageStack(); 219 220 UIContentErrorCode LoadCard(int32_t pageId, const RouterPageInfo& target, const std::string& params, int64_t cardId, 221 bool isRestore = false, bool needHideLast = true, const std::string& entryPoint = ""); 222 223 bool CheckIndexValid(int32_t index) const; 224 bool CheckOhmUrlValid(const std::string& ohmUrl); 225 void ThrowError(const std::string& msg, int32_t code); 226 227 RefPtr<FrameNode> CreatePage(int32_t pageId, const RouterPageInfo& target); 228 RefPtr<Framework::ManifestParser> manifestParser_; 229 230 bool inRouterOpt_ = false; 231 LoadPageCallback loadJs_; 232 LoadPageByBufferCallback loadJsByBuffer_; 233 LoadCardCallback loadCard_; 234 LoadNamedRouterCallback loadNamedRouter_; 235 UpdateRootComponentCallback updateRootComponent_; 236 bool isCardRouter_ = false; 237 int32_t pageId_ = 0; 238 std::list<WeakPtr<FrameNode>> pageRouterStack_; 239 std::list<std::string> restorePageStack_; 240 RouterPageInfo ngBackTarget_; 241 bool isNewPageReplacing_ = false; 242 #if defined(PREVIEW) 243 IsComponentPreviewCallback isComponentPreview_; 244 #endif 245 246 ACE_DISALLOW_COPY_AND_MOVE(PageRouterManager); 247 }; 248 249 } // namespace OHOS::Ace::NG 250 251 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_PAGE_ROUTER_MANAGER_H 252