1 /* 2 * Copyright (c) 2024 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_CORE_COMMON_PIPELINE_NG_NAVIGATION_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_NAVIGATION_MANAGER_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <map> 22 23 #include "base/json/json_util.h" 24 #include "base/memory/ace_type.h" 25 #include "core/components_ng/base/frame_node.h" 26 #include "core/components/common/layout/constants.h" 27 #include "core/components/common/properties/color.h" 28 29 namespace OHOS::Ace::NG { 30 class NavigationStack; 31 struct NavigationInfo { 32 int32_t nodeId = -1; 33 std::string navigationId; // inspectorId 34 WeakPtr<NavigationStack> pathStack; 35 WeakPtr<FrameNode> navigationNode; 36 int32_t uniqueId = -1; 37 38 NavigationInfo() = default; NavigationInfoNavigationInfo39 NavigationInfo(const std::string& id, const WeakPtr<NavigationStack>& navigationStack) 40 : navigationId(std::move(id)), pathStack(navigationStack) 41 {} NavigationInfoNavigationInfo42 NavigationInfo(int32_t nodeId, const std::string& navigationId, WeakPtr<FrameNode> navigationNode) 43 : nodeId(nodeId), navigationId(std::move(navigationId)), navigationNode(navigationNode) 44 {} NavigationInfoNavigationInfo45 NavigationInfo(const std::string& id, const WeakPtr<NavigationStack>& navigationStack, int32_t navigationUniqueId) 46 : navigationId(std::move(id)), pathStack(navigationStack), uniqueId(std::move(navigationUniqueId)) 47 {} 48 }; 49 50 struct NavigationIntentInfo { 51 std::string navigationInspectorId; 52 std::string navDestinationName; 53 std::string param; 54 bool isColdStart; 55 ToStringNavigationIntentInfo56 std::string ToString() 57 { 58 return "-------- Navigation info below --------\n" 59 "navigationId: " + navigationInspectorId + "\n" 60 "navDestName: " + navDestinationName + "\n" 61 "isColdStart: " + (isColdStart? "yes" : "no") + "\n" 62 "---------------------------------------\n"; 63 } 64 }; 65 struct NavdestinationRecoveryInfo { 66 std::string name; 67 std::string param; 68 // mode of navdestination, 0 for standard page and 1 for dialog page 69 int32_t mode; 70 NavdestinationRecoveryInfoNavdestinationRecoveryInfo71 NavdestinationRecoveryInfo(const std::string& name, const std::string& param, int32_t mode) 72 : name(std::move(name)), param(std::move(param)), mode(mode) {} 73 }; 74 75 using GetSystemColorCallback = std::function<bool(const std::string&, Color&)>; 76 77 const std::pair<bool, int32_t> DEFAULT_EXIST_FORCESPLIT_NAV_VALUE = {false, -1}; 78 79 class NavigationManager : public virtual AceType { 80 DECLARE_ACE_TYPE(NavigationManager, AceType); 81 public: 82 using DumpLogDepth = int; 83 using DumpCallback = std::function<void(DumpLogDepth)>; NavigationManager()84 NavigationManager() 85 { 86 #ifdef PREVIEW 87 hasCacheNavigationNodeEnable_ = false; 88 #else 89 hasCacheNavigationNodeEnable_ = SystemProperties::GetCacheNavigationNodeEnable(); 90 #endif 91 } 92 ~NavigationManager() = default; 93 SetPipelineContext(const WeakPtr<PipelineContext> & pipeline)94 void SetPipelineContext(const WeakPtr<PipelineContext>& pipeline) 95 { 96 pipeline_ = pipeline; 97 } 98 99 void AddNavigationDumpCallback(const RefPtr<FrameNode>& navigationNode, const DumpCallback& callback); 100 void RemoveNavigationDumpCallback(int32_t nodeId, int32_t depth); 101 102 void OnDumpInfo(); 103 AddNavigationUpdateCallback(std::function<void ()> callback)104 void AddNavigationUpdateCallback(std::function<void()> callback) 105 { 106 updateCallbacks_.emplace_back(callback); 107 } 108 109 void FireNavigationUpdateCallback(); 110 std::shared_ptr<NavigationInfo> GetNavigationInfo(const RefPtr<AceType>& node); 111 IsInteractive()112 bool IsInteractive() const 113 { 114 return isInteractive_; 115 } 116 SetInteractive(int32_t frameNodeId)117 void SetInteractive(int32_t frameNodeId) 118 { 119 isInteractive_ = true; 120 interactiveAnimationId_ = frameNodeId; 121 } 122 FinishInteractiveAnimation()123 void FinishInteractiveAnimation() 124 { 125 isInteractive_ = false; 126 } 127 SetNodeAddAnimation(bool isNodeAddAnimation)128 void SetNodeAddAnimation(bool isNodeAddAnimation) 129 { 130 isNodeAddAnimation_ = isNodeAddAnimation; 131 } 132 SetCurNodeAnimationCached(bool curNodeAnimationCached)133 void SetCurNodeAnimationCached(bool curNodeAnimationCached) 134 { 135 curNodeAnimationCached_ = curNodeAnimationCached; 136 } 137 SetCurrentNodeNeverSet(bool currentNodeNeverSet)138 void SetCurrentNodeNeverSet(bool currentNodeNeverSet) 139 { 140 currentNodeNeverSet_ = currentNodeNeverSet; 141 } 142 SetPreNodeNeverSet(bool preNodeNeverSet)143 void SetPreNodeNeverSet(bool preNodeNeverSet) 144 { 145 preNodeNeverSet_ = preNodeNeverSet; 146 } 147 SetPreNodeAnimationCached(bool preNodeAnimationCached)148 void SetPreNodeAnimationCached(bool preNodeAnimationCached) 149 { 150 preNodeAnimationCached_ = preNodeAnimationCached; 151 } 152 SetNavNodeInTransition(const RefPtr<FrameNode> & curNode,const RefPtr<FrameNode> & preNode)153 void SetNavNodeInTransition(const RefPtr<FrameNode>& curNode, const RefPtr<FrameNode>& preNode) 154 { 155 curNavNode_ = curNode; 156 preNavNode_ = preNode; 157 } 158 SetIsNavigationOnAnimation(bool isInAnimation)159 void SetIsNavigationOnAnimation(bool isInAnimation) 160 { 161 isInAnimation_ = isInAnimation; 162 } 163 IsNavigationInAnimation()164 bool IsNavigationInAnimation() const 165 { 166 return isInAnimation_; 167 } 168 HasCacheNavigationNodeEnable()169 bool HasCacheNavigationNodeEnable() 170 { 171 return hasCacheNavigationNodeEnable_; 172 } 173 174 void UpdateAnimationCachedRenderGroup(const RefPtr<FrameNode>& curNode, bool isSet); 175 void UpdatePreNavNodeRenderGroupProperty(); 176 void ResetCurNavNodeRenderGroupProperty(); 177 void UpdateCurNavNodeRenderGroupProperty(); 178 void CacheNavigationNodeAnimation(); 179 bool CheckNodeNeedCache(const RefPtr<FrameNode>& node); 180 RefPtr<FrameNode> GetNavDestContentFrameNode(const RefPtr<FrameNode>& node); 181 bool AddInteractiveAnimation(const std::function<void()>& addCallback); 182 183 bool AddRecoverableNavigation(std::string id, RefPtr<AceType> navigationNode); 184 std::unique_ptr<JsonValue> GetNavigationJsonInfo(); 185 void StorageNavigationRecoveryInfo(std::unique_ptr<JsonValue> allNavigationInfo); 186 const std::vector<NavdestinationRecoveryInfo> GetNavigationRecoveryInfo(std::string navigationId); 187 188 void AddNavigation(int32_t parentNodeId, const RefPtr<FrameNode>& navigationNode); 189 190 void RemoveNavigation(int32_t navigationNodeId); 191 192 std::vector<int32_t> FindNavigationInTargetParent(int32_t targetId); 193 194 void FireNavigationLifecycle(const RefPtr<UINode>& node, int32_t lifecycle, int32_t reason); 195 196 void FireOverlayLifecycle(const RefPtr<UINode>& node, int32_t lifecycle, int32_t reason); 197 198 void FireLowerLayerLifecycle(const RefPtr<UINode>& node, int lifecycle, int32_t reason); 199 200 void FireSubWindowLifecycle(const RefPtr<UINode>& node, int32_t lifecycle, int32_t reason); 201 202 // for non-animation 203 void AddBeforeOrientationChangeTask(const std::function<void()>&& task); 204 void ClearBeforeOrientationChangeTask(); 205 void OnOrientationChanged(); 206 // for intent framework 207 bool FireNavigationIntentActively(int32_t pageId, bool needTransition); 208 void SetNavigationIntentInfo(const std::string& intentInfoSerialized, bool isColdStart); 209 GetNavigationIntentInfo()210 std::optional<NavigationIntentInfo> GetNavigationIntentInfo() const 211 { 212 return navigationIntentInfo_; 213 } 214 ResetNavigationIntentInfo()215 void ResetNavigationIntentInfo() 216 { 217 navigationIntentInfo_.reset(); 218 } 219 SetGetSystemColorCallback(GetSystemColorCallback && callback)220 void SetGetSystemColorCallback(GetSystemColorCallback&& callback) 221 { 222 getSystemColorCallback_ = std::move(callback); 223 } GetSystemColor(const std::string & name,Color & color)224 bool GetSystemColor(const std::string& name, Color& color) 225 { 226 if (getSystemColorCallback_) { 227 return getSystemColorCallback_(name, color); 228 } 229 return false; 230 } IsForceSplitSupported()231 bool IsForceSplitSupported() const 232 { 233 return isForceSplitSupported_; 234 } 235 void SetForceSplitEnable(bool isForceSplit, const std::string& homePage, bool ignoreOrientation = false); IsForceSplitEnable()236 bool IsForceSplitEnable() const 237 { 238 return isForceSplitEnable_; 239 } GetHomePageName()240 const std::string& GetHomePageName() const 241 { 242 return homePageName_; 243 } 244 bool GetIgnoreOrientation() const; 245 246 void AddForceSplitListener(int32_t nodeId, std::function<void()>&& listener); 247 void RemoveForceSplitListener(int32_t nodeId); 248 bool IsOuterMostNavigation(int32_t nodeId, int32_t depth); 249 250 std::string GetTopNavDestinationInfo(int32_t pageId, bool onlyFullScreen, bool needParam); 251 void RestoreNavDestinationInfo(const std::string& navDestinationInfo, bool isColdStart); 252 253 //-------force split begin------- 254 void IsTargetForceSplitNav(const RefPtr<FrameNode>& navigationNode); 255 void SetForceSplitNavState(bool isTargetForceSplitNav, const RefPtr<FrameNode>& navigationNode); 256 void RemoveForceSplitNavStateIfNeed(int32_t nodeId); SetExistForceSplitNav(bool isTargetForceSplitNav,int32_t id)257 void SetExistForceSplitNav(bool isTargetForceSplitNav, int32_t id) 258 { 259 existForceSplitNav_ = {isTargetForceSplitNav, id}; 260 } GetExistForceSplitNav()261 std::pair<bool, int32_t> GetExistForceSplitNav() const 262 { 263 return existForceSplitNav_; 264 } TargetIdOrDepthExists()265 bool TargetIdOrDepthExists() const 266 { 267 return forceSplitNavigationId_.has_value() || forceSplitNavigationDepth_.has_value(); 268 } SetForceSplitNavigationId(std::optional<std::string> forceSplitNavigationId)269 void SetForceSplitNavigationId(std::optional<std::string> forceSplitNavigationId) 270 { 271 forceSplitNavigationId_ = forceSplitNavigationId; 272 } SetForceSplitNavigationDepth(std::optional<int32_t> forceSplitNavigationDepth)273 void SetForceSplitNavigationDepth(std::optional<int32_t> forceSplitNavigationDepth) 274 { 275 forceSplitNavigationDepth_ = forceSplitNavigationDepth; 276 } GetTargetNavigationId()277 std::optional<std::string> GetTargetNavigationId() const 278 { 279 return forceSplitNavigationId_; 280 } GetTargetNavigationDepth()281 std::optional<int32_t> GetTargetNavigationDepth() const 282 { 283 return forceSplitNavigationDepth_; 284 } 285 //-------force split end------- 286 private: 287 struct DumpMapKey { 288 int32_t nodeId; 289 int32_t depth; 290 DumpMapKeyDumpMapKey291 DumpMapKey(int32_t n, int32_t d) : nodeId(n), depth(d) {} 292 bool operator== (const DumpMapKey& o) const 293 { 294 return nodeId == o.nodeId && depth == o.depth; 295 } 296 bool operator< (const DumpMapKey& o) const 297 { 298 if (depth != o.depth) { 299 return depth < o.depth; 300 } 301 return nodeId < o.nodeId; 302 } 303 }; 304 305 RefPtr<FrameNode> GetNavigationByInspectorId(const std::string& id) const; 306 bool IsOverlayValid(const RefPtr<UINode>& frameNode); 307 bool IsCustomDialogValid(const RefPtr<UINode>& node); 308 NavigationIntentInfo ParseNavigationIntentInfo(const std::string& intentInfoSerialized); 309 310 std::unordered_map<std::string, WeakPtr<AceType>> recoverableNavigationMap_; 311 std::unordered_map<std::string, std::vector<NavdestinationRecoveryInfo>> navigationRecoveryInfo_; 312 // record all the navigation in current UI-Context. The key is the page/model id where the navigation is located. 313 std::unordered_map<int32_t, std::vector<NavigationInfo>> navigationMap_; 314 std::map<DumpMapKey, DumpCallback> dumpMap_; 315 std::vector<std::function<void()>> updateCallbacks_; 316 bool isInteractive_ = false; 317 318 WeakPtr<FrameNode> curNavNode_; 319 WeakPtr<FrameNode> preNavNode_; 320 bool currentNodeNeverSet_ = true; 321 bool curNodeAnimationCached_ = false; 322 bool preNodeNeverSet_ = true; 323 bool preNodeAnimationCached_ = false; 324 bool isInAnimation_ = false; 325 bool isNodeAddAnimation_ = false; 326 bool hasCacheNavigationNodeEnable_ = true; 327 int32_t interactiveAnimationId_ = -1; 328 329 WeakPtr<PipelineContext> pipeline_; 330 std::vector<std::function<void()>> beforeOrientationChangeTasks_; 331 std::optional<NavigationIntentInfo> navigationIntentInfo_ = std::nullopt; 332 333 GetSystemColorCallback getSystemColorCallback_; 334 bool isForceSplitSupported_ = false; 335 bool isForceSplitEnable_ = false; 336 std::string homePageName_; 337 std::unordered_map<int32_t, std::function<void()>> forceSplitListeners_; 338 bool ignoreOrientation_ = false; 339 340 //-------force split begin------- 341 int32_t currNestedDepth_ = 0; 342 std::pair<bool, int32_t> existForceSplitNav_ = DEFAULT_EXIST_FORCESPLIT_NAV_VALUE; 343 std::optional<std::string> forceSplitNavigationId_; 344 std::optional<int32_t> forceSplitNavigationDepth_; 345 //-------force split end------- 346 }; 347 } // namespace OHOS::Ace::NG 348 349 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_NAVIGATION_MANAGER_H 350