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