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/common/router_recover_record.h" 30 #include "core/components_ng/base/frame_node.h" 31 #include "frameworks/bridge/common/manifest/manifest_parser.h" 32 #include "interfaces/inner_api/ace/constants.h" 33 #include "bridge/js_frontend/frontend_delegate.h" 34 35 namespace OHOS::Ace::NG { 36 37 using LoadPageCallback = std::function<bool(const std::string&, 38 const std::function<void(const std::string&, int32_t)>&)>; 39 using LoadPageByBufferCallback = std::function<bool(const std::shared_ptr<std::vector<uint8_t>>& content, 40 const std::function<void(const std::string&, int32_t)>&, const std::string& contentName)>; 41 using LoadCardCallback = std::function<bool(const std::string&, int64_t cardId, const std::string&)>; 42 using LoadNamedRouterCallback = std::function<bool(const std::string&, bool isTriggeredByJs)>; 43 using RestoreFullPathInfoCallback = std::function<void(std::unique_ptr<JsonValue>)>; 44 using GetFullPathInfoCallback = std::function<std::unique_ptr<JsonValue>()>; 45 using RestoreNamedRouterInfoCallback = std::function<void(std::unique_ptr<JsonValue>)>; 46 using GetNamedRouterInfoCallback = std::function<std::unique_ptr<JsonValue>()>; 47 using IsNamedRouterNeedPreloadCallback = std::function<bool(const std::string&)>; 48 using PreloadNamedRouterCallback = std::function<void(const std::string&, std::function<void(bool)>&&)>; 49 using UpdateRootComponentCallback = std::function<bool()>; 50 #if defined(PREVIEW) 51 using IsComponentPreviewCallback = std::function<bool()>; 52 #endif 53 54 enum class RouterMode { 55 STANDARD = 0, 56 SINGLE, 57 }; 58 59 struct RouterPageInfo { 60 std::string url; 61 std::string params; 62 bool recoverable = true; 63 RouterMode routerMode = RouterMode::STANDARD; 64 std::function<void(const std::string&, int32_t)> errorCallback; 65 std::string path; 66 bool isNamedRouterMode = false; 67 std::shared_ptr<std::vector<uint8_t>> content; 68 }; 69 70 class PageRouterManager : public AceType { 71 DECLARE_ACE_TYPE(PageRouterManager, AceType) 72 public: 73 PageRouterManager() = default; 74 ~PageRouterManager() override = default; 75 76 void RunPage(const std::string& url, const std::string& params); 77 void RunPage(const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params); 78 void RunPageByNamedRouter(const std::string& name, const std::string& params); 79 UIContentErrorCode RunCard( 80 const std::string& url, const std::string& params, int64_t cardId, const std::string& entryPoint = ""); 81 SetManifestParser(const RefPtr<Framework::ManifestParser> & manifestParser)82 void SetManifestParser(const RefPtr<Framework::ManifestParser>& manifestParser) 83 { 84 manifestParser_ = manifestParser; 85 } 86 SetLoadJsCallback(LoadPageCallback && callback)87 void SetLoadJsCallback(LoadPageCallback&& callback) 88 { 89 loadJs_ = std::move(callback); 90 } 91 SetLoadJsByBufferCallback(LoadPageByBufferCallback && callback)92 void SetLoadJsByBufferCallback(LoadPageByBufferCallback&& callback) 93 { 94 loadJsByBuffer_ = std::move(callback); 95 } 96 SetLoadCardCallback(const LoadCardCallback & callback)97 void SetLoadCardCallback(const LoadCardCallback& callback) 98 { 99 loadCard_ = callback; 100 } 101 SetLoadNamedRouterCallback(LoadNamedRouterCallback && callback)102 void SetLoadNamedRouterCallback(LoadNamedRouterCallback&& callback) 103 { 104 loadNamedRouter_ = callback; 105 } 106 SetRestoreFullPathInfoCallback(RestoreFullPathInfoCallback && callback)107 void SetRestoreFullPathInfoCallback(RestoreFullPathInfoCallback&& callback) 108 { 109 restoreFullPathInfo_ = callback; 110 } 111 SetGetFullPathInfoCallback(GetFullPathInfoCallback && callback)112 void SetGetFullPathInfoCallback(GetFullPathInfoCallback&& callback) 113 { 114 getFullPathInfo_ = callback; 115 } 116 SetRestoreNamedRouterInfoCallback(RestoreNamedRouterInfoCallback && callback)117 void SetRestoreNamedRouterInfoCallback(RestoreNamedRouterInfoCallback&& callback) 118 { 119 restoreNamedRouterInfo_ = callback; 120 } 121 SetGetNamedRouterInfoCallback(GetNamedRouterInfoCallback && callback)122 void SetGetNamedRouterInfoCallback(GetNamedRouterInfoCallback&& callback) 123 { 124 getNamedRouterInfo_ = callback; 125 } 126 SetIsNamedRouterNeedPreloadCallback(IsNamedRouterNeedPreloadCallback && callback)127 void SetIsNamedRouterNeedPreloadCallback(IsNamedRouterNeedPreloadCallback&& callback) 128 { 129 isNamedRouterNeedPreload_ = callback; 130 } 131 SetPreloadNamedRouterCallback(PreloadNamedRouterCallback && callback)132 void SetPreloadNamedRouterCallback(PreloadNamedRouterCallback&& callback) 133 { 134 preloadNamedRouter_ = callback; 135 } 136 SetUpdateRootComponentCallback(UpdateRootComponentCallback && callback)137 void SetUpdateRootComponentCallback(UpdateRootComponentCallback&& callback) 138 { 139 updateRootComponent_ = callback; 140 } 141 #if defined(PREVIEW) SetIsComponentPreview(IsComponentPreviewCallback && callback)142 void SetIsComponentPreview(IsComponentPreviewCallback&& callback) 143 { 144 isComponentPreview_ = callback; 145 } 146 #endif 147 148 void EnableAlertBeforeBackPage(const std::string& message, std::function<void(int32_t)>&& callback); 149 150 void DisableAlertBeforeBackPage(); 151 152 // router operation 153 void Push(const RouterPageInfo& target); 154 void PushNamedRoute(const RouterPageInfo& target); 155 bool Pop(); 156 void Replace(const RouterPageInfo& target); 157 void ReplaceNamedRoute(const RouterPageInfo& target); 158 void BackWithTarget(const RouterPageInfo& target); 159 void BackToIndexWithTarget(int32_t index, const std::string& params); 160 void Clear(); 161 int32_t GetStackSize() const; 162 int32_t GetCurrentPageIndex() const; 163 RouterPageInfo GetPageInfoByIndex(int32_t index, const std::string& params); 164 165 void GetState(int32_t& index, std::string& name, std::string& path); 166 void GetStateByIndex(int32_t index, std::string& name, std::string& path, std::string& params); 167 void GetStateByUrl(std::string& url, std::vector<Framework::StateInfo>& stateArray); 168 169 void GetPageNameAndPath(const std::string& url, std::string& name, std::string& path); 170 int32_t GetPageIndex(const WeakPtr<FrameNode>& page); 171 172 std::string GetParams() const; 173 174 int32_t GetIndexByUrl(const std::string& url) const; 175 GetCurrentPageNode()176 RefPtr<FrameNode> GetCurrentPageNode() const 177 { 178 if (pageRouterStack_.empty()) { 179 return nullptr; 180 } 181 return pageRouterStack_.back().Upgrade(); 182 } 183 184 std::string GetCurrentPageUrl(); 185 186 // Get the currently running JS page information in NG structure. 187 RefPtr<Framework::RevSourceMap> GetCurrentPageSourceMap(const RefPtr<AssetManager>& assetManager); 188 SetIsCard()189 void SetIsCard() 190 { 191 isCardRouter_ = true; 192 } 193 194 void FlushFrontend(); 195 196 std::unique_ptr<JsonValue> GetStackInfo(ContentInfoType type); 197 std::unique_ptr<JsonValue> GetNamedRouterInfo(); 198 std::unique_ptr<JsonValue> GetFullPathInfo(); 199 200 std::pair<RouterRecoverRecord, UIContentErrorCode> RestoreRouterStack( 201 std::unique_ptr<JsonValue> stackInfo, ContentInfoType type); 202 void RestoreNamedRouterInfo(std::unique_ptr<JsonValue> namedRouterInfo); 203 void RestoreFullPathInfo(std::unique_ptr<JsonValue> fullPathInfo); 204 205 // begin from 1 206 bool IsUnrestoreByIndex(int32_t index); 207 208 protected: 209 class RouterOptScope { 210 public: RouterOptScope(PageRouterManager * manager)211 explicit RouterOptScope(PageRouterManager* manager) : manager_(manager) 212 { 213 manager_->inRouterOpt_ = true; 214 } ~RouterOptScope()215 ~RouterOptScope() 216 { 217 manager_->inRouterOpt_ = false; 218 } 219 220 private: 221 PageRouterManager* manager_ = nullptr; 222 }; 223 224 // page id manage 225 int32_t GenerateNextPageId(); 226 GetLastPageIndex()227 virtual int32_t GetLastPageIndex() 228 { 229 return static_cast<int32_t>(pageRouterStack_.size()) - 1; 230 } 231 232 std::pair<int32_t, RefPtr<FrameNode>> FindPageInStack(const std::string& url, bool needIgnoreBegin = false); 233 std::pair<int32_t, RefPtr<FrameNode>> FindPageInStackByRouteName(const std::string& name) const; 234 int32_t FindPageInRestoreStack(const std::string& url); 235 236 void SetPageInfoRouteName(const RefPtr<EntryPageInfo>& info, bool isNamedRouterMode); 237 238 void LoadOhmUrl(const RouterPageInfo& target); 239 void PushOhmUrl(const RouterPageInfo& target); 240 void ReplaceOhmUrl(const RouterPageInfo& target); 241 void StartPush(const RouterPageInfo& target); 242 void StartReplace(const RouterPageInfo& target); 243 void StartBack(const RouterPageInfo& target); 244 void StartBackToIndex(int32_t index, const std::string& params); 245 bool StartPop(); 246 void StartRestore(const RouterPageInfo& target); 247 void BackCheckAlert(const RouterPageInfo& target); 248 void BackToIndexCheckAlert(int32_t index, const std::string& params); 249 void StartClean(); 250 void CleanPageOverlay(); 251 252 enum class RestorePageDestination : int32_t { 253 TOP = 0, // restore page to pageRouterStack_'s top 254 BELLOW_TOP = 1, // restore page bellow pageRouterStack_'s top 255 BOTTOM = 2, // restore page to pageRouterStack_'s bottom 256 }; 257 258 // page operations 259 virtual void LoadPage(int32_t pageId, const RouterPageInfo& target, 260 bool needHideLast = true, bool needTransition = true, bool isPush = false); 261 void MovePageToFront(int32_t index, const RefPtr<FrameNode>& pageNode, const RouterPageInfo& target, 262 bool needHideLast, bool forceShowCurrent = false, bool needTransition = true); 263 void RefreshPageIndex(std::list<WeakPtr<FrameNode>>::iterator startIter, int32_t startIndex); 264 void RefreshAllPageIndex(); 265 void RestorePageWithTarget(int32_t index, bool removeRestorePages, 266 const RouterPageInfo& target, RestorePageDestination dest, bool needTransition = true); 267 void RestorePageWithTargetInner( 268 const RouterPageInfo& target, RestorePageDestination dest, bool needTransition = true); 269 void StartRestorePageWithTarget(const RouterPageInfo& target, std::function<void()>&& finishCallback, 270 RestorePageDestination dest, bool needTransition); 271 272 void PopPage(const std::string& params, bool needShowNext, bool needTransition, bool needReplaceParams = true); 273 void PopPageToIndex(int32_t index, const std::string& params, bool needShowNext, bool needTransition); 274 void DealReplacePage(const RouterPageInfo& target); 275 virtual void ReplacePageInNewLifecycle(const RouterPageInfo& target); 276 277 static bool OnPageReady(const RefPtr<FrameNode>& pageNode, bool needHideLast, bool needTransition, 278 bool isCardRouter = false, int64_t cardId = 0); 279 static bool OnPopPage(bool needShowNext, bool needTransition); 280 static bool OnPopPageToIndex(int32_t index, bool needShowNext, bool needTransition); 281 static bool OnCleanPageStack(); 282 283 UIContentErrorCode LoadCard(int32_t pageId, const RouterPageInfo& target, const std::string& params, int64_t cardId, 284 bool isRestore = false, bool needHideLast = true, const std::string& entryPoint = ""); 285 286 bool CheckIndexValid(int32_t index) const; 287 bool CheckOhmUrlValid(const std::string& ohmUrl); 288 void ThrowError(const std::string& msg, int32_t code); 289 290 bool TryPreloadNamedRouter(const std::string& name, std::function<void()>&& finishCallback); 291 void PushNamedRouteInner(const RouterPageInfo& target); 292 void ReplaceNamedRouteInner(const RouterPageInfo& target); 293 void RunPageByNamedRouterInner(const std::string& name, const std::string& params); 294 295 RefPtr<FrameNode> CreatePage(int32_t pageId, const RouterPageInfo& target); 296 void RestoreOhmUrl(const RouterPageInfo& target, std::function<void()>&& finishCallback, 297 RestorePageDestination dest, bool needTransition); 298 void PushPageToTop(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback, bool needTransition); 299 void InsertPageBellowTop(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback); 300 void InsertPageToBottom(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback); 301 void LoadOhmUrlPage(const std::string& url, std::function<void()>&& finishCallback, 302 const std::function<void(const std::string& errorMsg, int32_t errorCode)>& errorCallback, 303 const std::string& finishCallbackTaskName, const std::string& errorCallbackTaskName); 304 305 RefPtr<Framework::ManifestParser> manifestParser_; 306 307 enum class InsertPageProcessingType : int32_t { 308 NONE = 0, 309 INSERT_BELLOW_TOP = 1, 310 INSERT_BOTTOM = 2, 311 }; 312 InsertPageProcessingType insertPageProcessingType_ = InsertPageProcessingType::NONE; 313 bool inRouterOpt_ = false; 314 LoadPageCallback loadJs_; 315 LoadPageByBufferCallback loadJsByBuffer_; 316 LoadCardCallback loadCard_; 317 LoadNamedRouterCallback loadNamedRouter_; 318 GetFullPathInfoCallback getFullPathInfo_; 319 RestoreFullPathInfoCallback restoreFullPathInfo_; 320 GetNamedRouterInfoCallback getNamedRouterInfo_; 321 RestoreNamedRouterInfoCallback restoreNamedRouterInfo_; 322 IsNamedRouterNeedPreloadCallback isNamedRouterNeedPreload_; 323 PreloadNamedRouterCallback preloadNamedRouter_; 324 UpdateRootComponentCallback updateRootComponent_; 325 bool isCardRouter_ = false; 326 int32_t pageId_ = 0; 327 std::list<WeakPtr<FrameNode>> pageRouterStack_; 328 std::list<RouterRecoverRecord> restorePageStack_; 329 RouterPageInfo ngBackTarget_; 330 bool isNewPageReplacing_ = false; 331 #if defined(PREVIEW) 332 IsComponentPreviewCallback isComponentPreview_; 333 #endif 334 335 ACE_DISALLOW_COPY_AND_MOVE(PageRouterManager); 336 }; 337 338 } // namespace OHOS::Ace::NG 339 340 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_PAGE_ROUTER_MANAGER_H 341