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( 234 const std::string& name, bool needIgnoreBegin = false); 235 int32_t FindPageInRestoreStack(const std::string& url); 236 237 void SetPageInfoRouteName(const RefPtr<EntryPageInfo>& info); 238 239 void LoadOhmUrl(const RouterPageInfo& target); 240 void PushOhmUrl(const RouterPageInfo& target); 241 void ReplaceOhmUrl(const RouterPageInfo& target); 242 void StartPush(const RouterPageInfo& target); 243 void StartReplace(const RouterPageInfo& target); 244 void StartBack(const RouterPageInfo& target); 245 void StartBackToIndex(int32_t index, const std::string& params); 246 bool StartPop(); 247 void StartRestore(const RouterPageInfo& target); 248 void BackCheckAlert(const RouterPageInfo& target); 249 void BackToIndexCheckAlert(int32_t index, const std::string& params); 250 void StartClean(); 251 void CleanPageOverlay(); 252 253 void UpdateSrcPage(); 254 255 enum class RestorePageDestination : int32_t { 256 TOP = 0, // restore page to pageRouterStack_'s top 257 BELLOW_TOP = 1, // restore page bellow pageRouterStack_'s top 258 BOTTOM = 2, // restore page to pageRouterStack_'s bottom 259 }; 260 261 // page operations 262 virtual void LoadPage(int32_t pageId, const RouterPageInfo& target, 263 bool needHideLast = true, bool needTransition = true, bool isPush = false); 264 void MovePageToFront(int32_t index, const RefPtr<FrameNode>& pageNode, const RouterPageInfo& target, 265 bool needHideLast, bool forceShowCurrent = false, bool needTransition = true); 266 void RefreshPageIndex(std::list<WeakPtr<FrameNode>>::iterator startIter, int32_t startIndex); 267 void RefreshAllPageIndex(); 268 void RestorePageWithTarget(int32_t index, bool removeRestorePages, 269 const RouterPageInfo& target, RestorePageDestination dest, bool needTransition = true); 270 void RestorePageWithTargetInner( 271 const RouterPageInfo& target, RestorePageDestination dest, bool needTransition = true); 272 void StartRestorePageWithTarget(const RouterPageInfo& target, std::function<void()>&& finishCallback, 273 RestorePageDestination dest, bool needTransition); 274 275 void PopPage(const std::string& params, bool needShowNext, bool needTransition, bool needReplaceParams = true); 276 void PopPageToIndex(int32_t index, const std::string& params, bool needShowNext, bool needTransition); 277 void DealReplacePage(const RouterPageInfo& target); 278 virtual void ReplacePageInNewLifecycle(const RouterPageInfo& info); 279 280 static bool OnPageReady(const RefPtr<FrameNode>& pageNode, bool needHideLast, bool needTransition, 281 bool isCardRouter = false, int64_t cardId = 0); 282 bool OnPopPage(bool needShowNext, bool needTransition); 283 static bool OnPopPageToIndex(int32_t index, bool needShowNext, bool needTransition); 284 static bool OnCleanPageStack(); 285 286 UIContentErrorCode LoadCard(int32_t pageId, const RouterPageInfo& target, const std::string& params, int64_t cardId, 287 bool isRestore = false, bool needHideLast = true, const std::string& entryPoint = ""); 288 289 bool CheckIndexValid(int32_t index) const; 290 bool CheckOhmUrlValid(const std::string& ohmUrl); 291 void ThrowError(const std::string& msg, int32_t code); 292 293 bool TryPreloadNamedRouter(const std::string& name, std::function<void()>&& finishCallback); 294 void PushNamedRouteInner(const RouterPageInfo& target); 295 void ReplaceNamedRouteInner(const RouterPageInfo& target); 296 void RunPageByNamedRouterInner(const std::string& name, const std::string& params); 297 298 RefPtr<FrameNode> CreatePage(int32_t pageId, const RouterPageInfo& target); 299 void RestoreOhmUrl(const RouterPageInfo& target, std::function<void()>&& finishCallback, 300 RestorePageDestination dest, bool needTransition); 301 void PushPageToTop(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback, bool needTransition); 302 void InsertPageBellowTop(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback); 303 void InsertPageToBottom(RefPtr<FrameNode>& pageNode, std::function<void()>&& finishCallback); 304 void LoadOhmUrlPage(const std::string& url, std::function<void()>&& finishCallback, 305 const std::function<void(const std::string& errorMsg, int32_t errorCode)>& errorCallback, 306 const std::string& finishCallbackTaskName, const std::string& errorCallbackTaskName); 307 308 RefPtr<Framework::ManifestParser> manifestParser_; 309 310 enum class InsertPageProcessingType : int32_t { 311 NONE = 0, 312 INSERT_BELLOW_TOP = 1, 313 INSERT_BOTTOM = 2, 314 }; 315 InsertPageProcessingType insertPageProcessingType_ = InsertPageProcessingType::NONE; 316 bool inRouterOpt_ = false; 317 LoadPageCallback loadJs_; 318 LoadPageByBufferCallback loadJsByBuffer_; 319 LoadCardCallback loadCard_; 320 LoadNamedRouterCallback loadNamedRouter_; 321 GetFullPathInfoCallback getFullPathInfo_; 322 RestoreFullPathInfoCallback restoreFullPathInfo_; 323 GetNamedRouterInfoCallback getNamedRouterInfo_; 324 RestoreNamedRouterInfoCallback restoreNamedRouterInfo_; 325 IsNamedRouterNeedPreloadCallback isNamedRouterNeedPreload_; 326 PreloadNamedRouterCallback preloadNamedRouter_; 327 UpdateRootComponentCallback updateRootComponent_; 328 bool isCardRouter_ = false; 329 int32_t pageId_ = 0; 330 std::list<WeakPtr<FrameNode>> pageRouterStack_; 331 std::list<RouterRecoverRecord> restorePageStack_; 332 RouterPageInfo ngBackTarget_; 333 bool isNewPageReplacing_ = false; 334 #if defined(PREVIEW) 335 IsComponentPreviewCallback isComponentPreview_; 336 #endif 337 338 ACE_DISALLOW_COPY_AND_MOVE(PageRouterManager); 339 }; 340 341 } // namespace OHOS::Ace::NG 342 343 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_PAGE_ROUTER_MANAGER_H 344