From 1d87de0aa55d8be315ede00513ebe962b0727e5c Mon Sep 17 00:00:00 2001 From: chen-xiaoxue299 Date: Sat, 26 Jul 2025 18:22:12 +0800 Subject: [PATCH] navigation Signed-off-by: chen-xiaoxue299 --- adapter/ohos/entrance/ui_content_impl.cpp | 24 ++ adapter/ohos/entrance/ui_content_impl.h | 1 + .../common/force_split/force_split_utils.cpp | 43 +++ .../common/force_split/force_split_utils.h | 7 + .../manager/navigation/navigation_manager.cpp | 72 ++++ .../manager/navigation/navigation_manager.h | 40 +++ .../navigation/navigation_group_node.cpp | 2 + .../pattern/navigation/navigation_pattern.cpp | 33 +- .../pattern/navigation/navigation_pattern.h | 3 + frameworks/core/pipeline/pipeline_base.h | 11 + interfaces/inner_api/ace/ui_content.h | 2 + .../navigation/navigation_manager_test_ng.cpp | 314 ++++++++++++++++++ 12 files changed, 548 insertions(+), 4 deletions(-) diff --git a/adapter/ohos/entrance/ui_content_impl.cpp b/adapter/ohos/entrance/ui_content_impl.cpp index 515e8012412..b58ee5a1795 100644 --- a/adapter/ohos/entrance/ui_content_impl.cpp +++ b/adapter/ohos/entrance/ui_content_impl.cpp @@ -50,6 +50,7 @@ #include "base/subwindow/subwindow_manager.h" #include "base/thread/background_task_executor.h" #include "base/utils/utils.h" +#include "core/common/force_split/force_split_utils.h" #include "core/common/multi_thread_build_manager.h" #include "core/components/common/layout/constants.h" #include "core/components_ng/base/frame_node.h" @@ -5458,6 +5459,29 @@ void UIContentImpl::SetForceSplitEnable( isRouter ? "ArkUISetForceSplitEnable" : "ArkUISetNavigationForceSplitEnable"); } +void UIContentImpl::SetForceSplitConfig(const std::string& configJsonStr) +{ + ContainerScope scope(instanceId_); + auto container = Platform::AceContainer::GetContainer(instanceId_); + CHECK_NULL_VOID(container); + auto context = AceType::DynamicCast(container->GetPipelineContext()); + CHECK_NULL_VOID(context); + NG::ForceSplitConfig config; + if (!NG::ForceSplitUtils::ParseForceSplitConfig(configJsonStr, config)) { + TAG_LOGE(AceLogTag::ACE_NAVIGATION, "Failed to parse forceSplit config!"); + return; + } + TAG_LOGI(AceLogTag::ACE_NAVIGATION, "ForceSplitConfig: enableHook:%{public}d, navId:%{public}s," + "navDepth:%{public}s", config.isArkUIHookEnabled, + (config.navigationId.has_value() ? config.navigationId.value().c_str() : "NA"), + (config.navigationDepth.has_value() ? std::to_string(config.navigationDepth.value()).c_str() : "NA")); + context->SetIsArkUIHookEnabled(config.isArkUIHookEnabled); + auto navManager = context->GetNavigationManager(); + CHECK_NULL_VOID(navManager); + navManager->SetForceSplitNavigationId(config.navigationId); + navManager->SetForceSplitNavigationDepth(config.navigationDepth); +} + void UIContentImpl::ProcessDestructCallbacks() { std::vector> tempCallbacks; diff --git a/adapter/ohos/entrance/ui_content_impl.h b/adapter/ohos/entrance/ui_content_impl.h index c4a7e6014f7..adb0d416d1d 100644 --- a/adapter/ohos/entrance/ui_content_impl.h +++ b/adapter/ohos/entrance/ui_content_impl.h @@ -385,6 +385,7 @@ public: void SetForceSplitEnable(bool isForceSplit, const std::string& homePage, bool isRouter = true, bool ignoreOrientation = false) override; + void SetForceSplitConfig(const std::string& configJsonStr) override; void AddDestructCallback(void* key, const std::function& callback) { diff --git a/frameworks/core/common/force_split/force_split_utils.cpp b/frameworks/core/common/force_split/force_split_utils.cpp index 098eedc434f..0a053541b7e 100644 --- a/frameworks/core/common/force_split/force_split_utils.cpp +++ b/frameworks/core/common/force_split/force_split_utils.cpp @@ -19,6 +19,7 @@ #include #include "base/geometry/dimension.h" +#include "base/json/json_util.h" #include "core/common/container.h" #include "core/components_ng/pattern/image/image_pattern.h" #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" @@ -36,6 +37,10 @@ const std::vector PRIMARY_PAGE_PREFIX = {"main", "home", "index", " const std::vector TRANS_PAGE_PREFIX = {"guide", "load", "splash", "login"}; constexpr int32_t PRIMARY_DESTINATION_CHILD_NODE_DEPTH_THRESHOLD = 50; constexpr int32_t PRIMARY_DESTINATION_CHILD_NODE_COUNT_THRESHOLD = 100; +constexpr char ENABLE_HOOK_KEY[] = "enableHook"; +constexpr char NAVIGATION_OPTIONS_KEY[] = "navigationOptions"; +constexpr char NAVIGATION_OPTIONS_ID_KEY[] = "id"; +constexpr char NAVIGATION_OPTIONS_DEPTH_KEY[] = "depth"; } RefPtr ForceSplitUtils::CreatePlaceHolderContent(const RefPtr& context) @@ -208,5 +213,43 @@ RefPtr ForceSplitUtils::CreatePlaceHolderNode() } return phNode; } + +bool ForceSplitUtils::ParseForceSplitConfig(const std::string& configJsonStr, ForceSplitConfig& config) +{ + auto configJson = JsonUtil::ParseJsonString(configJsonStr); + if (!configJson || !configJson->IsObject()) { + TAG_LOGE(AceLogTag::ACE_NAVIGATION, "Error, arkUIOptions is an invalid json object!"); + return false; + } + config.isArkUIHookEnabled = configJson->GetBool(ENABLE_HOOK_KEY, false); + if (!configJson->Contains(NAVIGATION_OPTIONS_KEY)) { + return true; + } + auto navOptions = configJson->GetValue(NAVIGATION_OPTIONS_KEY); + if (!navOptions || !navOptions->IsObject()) { + TAG_LOGE(AceLogTag::ACE_NAVIGATION, "Error, navigationOptions is an invalid json object!"); + return false; + } + if (navOptions->Contains(NAVIGATION_OPTIONS_ID_KEY)) { + auto idJson = navOptions->GetValue(NAVIGATION_OPTIONS_ID_KEY); + if (!idJson->IsString()) { + TAG_LOGE(AceLogTag::ACE_NAVIGATION, "Error, navigationOptions.id is not string!"); + return false; + } + auto idStr = idJson->GetString(); + if (!idStr.empty()) { + config.navigationId = idStr; + } + } + if (navOptions->Contains(NAVIGATION_OPTIONS_DEPTH_KEY)) { + auto depthJson = navOptions->GetValue(NAVIGATION_OPTIONS_DEPTH_KEY); + if (!depthJson->IsNumber()) { + TAG_LOGE(AceLogTag::ACE_NAVIGATION, "Error, navigationOptions.depth is not number!"); + return false; + } + config.navigationDepth = navOptions->GetInt(NAVIGATION_OPTIONS_DEPTH_KEY); + } + return true; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/common/force_split/force_split_utils.h b/frameworks/core/common/force_split/force_split_utils.h index 57f0d83f2a6..a390d9940be 100644 --- a/frameworks/core/common/force_split/force_split_utils.h +++ b/frameworks/core/common/force_split/force_split_utils.h @@ -23,12 +23,19 @@ namespace OHOS::Ace::NG { class NavDestinationGroupNode; +struct ForceSplitConfig { + bool isArkUIHookEnabled = false; + std::optional navigationId; + std::optional navigationDepth; +}; + class ForceSplitUtils { public: static RefPtr CreatePlaceHolderContent(const RefPtr& context); static RefPtr CreatePlaceHolderNavDestination(const RefPtr& context); static bool IsNavDestinationHomePage(const RefPtr& node); static RefPtr CreatePlaceHolderNode(); + static bool ParseForceSplitConfig(const std::string& configJsonStr, ForceSplitConfig& config); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/manager/navigation/navigation_manager.cpp b/frameworks/core/components_ng/manager/navigation/navigation_manager.cpp index 1e3eefe1bf0..bd6c298cc50 100644 --- a/frameworks/core/components_ng/manager/navigation/navigation_manager.cpp +++ b/frameworks/core/components_ng/manager/navigation/navigation_manager.cpp @@ -36,6 +36,43 @@ bool NavigationManager::IsOuterMostNavigation(int32_t nodeId, int32_t depth) return outerMostKey == DumpMapKey(nodeId, depth); } +bool NavigationManager::IsTargetNavigation(int32_t currId) +{ + if (nestedSplitParaMap_.empty()) { + return false; + } + // If there is already a navigation with forced split, the result will be returned directly. + if (procNestedNavSplit_.first == true) { + return procNestedNavSplit_.second == currId; + } + + auto iter = nestedSplitParaMap_.find(currId); + if (iter != nestedSplitParaMap_.end()) { + auto currInspectorId = iter->second.inspectorId; + auto targetInspectorId = GetTargetNavigationId(); + /** + * The targetInspectorId exists, and it is equal to currInspectorId, + * identifies procNestedNavSplit_ as true and return true. + */ + if (targetInspectorId.has_value()) { + bool isTargetNav = targetInspectorId == currInspectorId; + procNestedNavSplit_ = {isTargetNav, isTargetNav ? currId : -1}; + return targetInspectorId == currInspectorId; + } + auto currNestedDepth = iter->second.nestedDepth; + auto targetNestedDepth = GetTargetNavigationDepth(); + /** + * The targetDepth exists, and it is equal to currNestedDepth + * identifies procNestedNavSplit_ as true and return true. + */ + if (targetNestedDepth.has_value() && targetNestedDepth == currNestedDepth) { + procNestedNavSplit_ = {true, currId}; + return true; + } + } + return false; +} + void NavigationManager::AddNavigationDumpCallback(int32_t nodeId, int32_t depth, const DumpCallback& callback) { CHECK_RUN_ON(UI); @@ -712,4 +749,39 @@ RefPtr NavigationManager::GetNavigationByInspectorId(const std::strin } return nullptr; } + +void NavigationManager::AddNavigationForceSplitInfo(int32_t nodeId, int32_t depth, std::string inspectorId) +{ + CHECK_RUN_ON(UI); + /** + * "depth" represents the depth relative to all nodes, + * "nestedDepth" represents the depth of all navigation, and nestedDepth starts at zero. + */ + auto iter = hasProcessedDepth_.find(depth); + if (iter == hasProcessedDepth_.end()) { + auto currNestedDepth = nestedDepth_++; + hasProcessedDepth_.emplace(depth, currNestedDepth); + nestedSplitParaMap_.emplace(nodeId, NestedNavForceSplitPara(inspectorId, currNestedDepth)); + } else { + /** + * When there are multiple navigations at the same level, + * the developer sets the depth of this level, and the first navigation takes effect with forced split. + * The rest of the navigation just stores the id and the depth is not taken into account. + */ + auto currNestedDepth = iter->second; + nestedSplitParaMap_.emplace(nodeId, NestedNavForceSplitPara(inspectorId, currNestedDepth)); + } +} + +void NavigationManager::RemoveNavigationForceSplitInfo(int32_t nodeId) +{ + CHECK_RUN_ON(UI); + auto it = nestedSplitParaMap_.find(nodeId); + if (it != nestedSplitParaMap_.end()) { + nestedSplitParaMap_.erase(it); + } + if (procNestedNavSplit_.second == nodeId) { + procNestedNavSplit_ = {false, -1}; + } +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/manager/navigation/navigation_manager.h b/frameworks/core/components_ng/manager/navigation/navigation_manager.h index 17c0333039c..b5cfca74bbb 100644 --- a/frameworks/core/components_ng/manager/navigation/navigation_manager.h +++ b/frameworks/core/components_ng/manager/navigation/navigation_manager.h @@ -249,6 +249,37 @@ public: std::string GetTopNavDestinationInfo(int32_t pageId, bool onlyFullScreen, bool needParam); void RestoreNavDestinationInfo(const std::string& navDestinationInfo, bool isColdStart); + + // Nested scenes force split to specify the actual effective navigation. + struct NestedNavForceSplitPara { + std::string inspectorId; + int32_t nestedDepth; + NestedNavForceSplitPara(std::string inspectorId, int32_t nestedDepth) + : inspectorId(inspectorId), nestedDepth(nestedDepth) {} + }; + bool IsTargetNavigation(int32_t currId); + bool TargetIdOrDepthExists() const + { + return forceSplitNavigationId_.has_value() || forceSplitNavigationDepth_.has_value(); + } + void SetForceSplitNavigationId(std::optional forceSplitNavigationId) + { + forceSplitNavigationId_ = forceSplitNavigationId; + } + void SetForceSplitNavigationDepth(std::optional forceSplitNavigationDepth) + { + forceSplitNavigationDepth_ = forceSplitNavigationDepth; + } + std::optional GetTargetNavigationId() const + { + return forceSplitNavigationId_; + } + std::optional GetTargetNavigationDepth() const + { + return forceSplitNavigationDepth_; + } + void AddNavigationForceSplitInfo(int32_t nodeId, int32_t depth, std::string inspectorId); + void RemoveNavigationForceSplitInfo(int32_t nodeId); private: struct DumpMapKey { int32_t nodeId; @@ -302,6 +333,15 @@ private: std::string homePageName_; std::unordered_map> forceSplitListeners_; bool ignoreOrientation_ = false; + + // Force split scene, the following are the parameters of nested navigation. + int nestedDepth_ = 0; + std::unordered_map hasProcessedDepth_; + std::unordered_map nestedSplitParaMap_; + + std::pair procNestedNavSplit_ = {false, -1}; + std::optional forceSplitNavigationId_; + std::optional forceSplitNavigationDepth_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp index e5f0f7d218e..215ec8d0f1a 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp @@ -1463,6 +1463,7 @@ void NavigationGroupNode::OnDetachFromMainTree(bool recursive, PipelineContext* if (pattern) { pattern->DetachNavigationStackFromParent(); pattern->RemoveFromDumpManager(); + pattern->RemoveForceSplitInfo(); } GroupNode::OnDetachFromMainTree(recursive, context); CHECK_NULL_VOID(context); @@ -1501,6 +1502,7 @@ void NavigationGroupNode::OnAttachToMainTree(bool recursive) if (pattern) { pattern->AttachNavigationStackToParent(); pattern->AddToDumpManager(); + pattern->AddToForceSplitInfo(); } RefPtr parentCustomNode; bool findParentNode = false; diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp index ba5d59798c9..e9169441bd1 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp @@ -5167,8 +5167,10 @@ void NavigationPattern::TryForceSplitIfNeeded(const SizeF& frameSize) auto windowMode = windowManager->GetWindowMode(); bool isInSplitScreenMode = windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY; - bool isOuterMostNav = navManager->IsOuterMostNavigation(hostNode->GetId(), hostNode->GetDepth()); - forceSplitSuccess = isMainWindow && isInAppMainPage && isOuterMostNav && + bool isTargetNav = navManager->TargetIdOrDepthExists() + ? navManager->IsTargetNavigation(hostNode->GetId()) + : navManager->IsOuterMostNavigation(hostNode->GetId(), hostNode->GetDepth()); + forceSplitSuccess = isMainWindow && isInAppMainPage && isTargetNav && (ignoreOrientation || orientation == DeviceOrientation::LANDSCAPE) && thresholdWidth < frameSize.Width() && !isInSplitScreenMode; /** @@ -5180,10 +5182,10 @@ void NavigationPattern::TryForceSplitIfNeeded(const SizeF& frameSize) (GreatNotEqual(property->GetMaxNavBarWidthValue(DEFAULT_NAV_BAR_WIDTH).Value(), 0)); forceSplitUseNavBar = forceSplitSuccess && navBarHasContent; TAG_LOGI(AceLogTag::ACE_NAVIGATION, "calc splitMode, isMainWindow:%{public}d, isInAppMainPage:%{public}d, " - "isInSplitScreenMode:%{public}d, isOuterMostNav:%{public}d, ignoreOrientation:%{public}d, " + "isInSplitScreenMode:%{public}d, isTargetNav:%{public}d, ignoreOrientation:%{public}d, " "orientation: %{public}s, dipScale: %{public}f, thresholdWidth: %{public}f, curWidth: %{public}f, " "navBarHasContent:%{public}d, forceSplitSuccess:%{public}d, forceSplitUseNavBar:%{public}d", - isMainWindow, isInAppMainPage, isInSplitScreenMode, isOuterMostNav, ignoreOrientation, + isMainWindow, isInAppMainPage, isInSplitScreenMode, isTargetNav, ignoreOrientation, DeviceOrientationToString(orientation), dipScale, thresholdWidth, frameSize.Width(), navBarHasContent, forceSplitSuccess, forceSplitUseNavBar); } @@ -5674,6 +5676,29 @@ void NavigationPattern::UpdateChildLayoutPolicy() } } +void NavigationPattern::AddToForceSplitInfo() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + auto mgr = context->GetNavigationManager(); + CHECK_NULL_VOID(mgr); + mgr->AddNavigationForceSplitInfo(host->GetId(), + host->GetDepth(), host->GetInspectorId().value_or("")); +} + +void NavigationPattern::RemoveForceSplitInfo() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + auto mgr = context->GetNavigationManager(); + CHECK_NULL_VOID(mgr); + mgr->RemoveNavigationForceSplitInfo(host->GetId()); +} + void NavigationPattern::ClearNavigationCustomTransition() { auto currentProxy = GetTopNavigationProxy(); diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h index 83014f12158..626ec9a25f8 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h +++ b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.h @@ -561,6 +561,9 @@ public: // Only used for the toolbar in 'container_modal' component void SetToolbarManagerNavigationMode(NavigationMode mode); + void AddToForceSplitInfo(); + void RemoveForceSplitInfo(); + bool CreateHomeDestination(RefPtr& customNode, RefPtr& homeDest); bool IsHomeDestinationVisible(); void FireHomeDestinationLifeCycleIfNeeded(NavDestinationLifecycle lifecycle, bool isModeChange = false, diff --git a/frameworks/core/pipeline/pipeline_base.h b/frameworks/core/pipeline/pipeline_base.h index 8299dd935d7..c149c832136 100644 --- a/frameworks/core/pipeline/pipeline_base.h +++ b/frameworks/core/pipeline/pipeline_base.h @@ -887,6 +887,16 @@ public: return viewScale_; } + void SetIsArkUIHookEnabled(bool enable) + { + isArkUIHookEnabled_ = enable; + } + + bool IsArkUIHookEnabled() const + { + return isArkUIHookEnabled_; + } + double GetRootWidth() const { return rootWidth_; @@ -1673,6 +1683,7 @@ protected: float viewScale_ = 1.0f; double density_ = 1.0; double dipScale_ = 1.0; + bool isArkUIHookEnabled_ = false; double rootHeight_ = 0.0; double rootWidth_ = 0.0; int32_t width_ = 0; diff --git a/interfaces/inner_api/ace/ui_content.h b/interfaces/inner_api/ace/ui_content.h index e9f3ea713ea..a1a488b6e79 100644 --- a/interfaces/inner_api/ace/ui_content.h +++ b/interfaces/inner_api/ace/ui_content.h @@ -508,6 +508,8 @@ public: virtual void SetForceSplitEnable(bool isForceSplit, const std::string& homePage, bool isRouter = true, bool ignoreOrientation = false) {} + virtual void SetForceSplitConfig(const std::string& configJsonStr) {} + virtual void EnableContainerModalGesture(bool isEnable) {}; virtual bool GetContainerFloatingTitleVisible() diff --git a/test/unittest/core/pattern/navigation/navigation_manager_test_ng.cpp b/test/unittest/core/pattern/navigation/navigation_manager_test_ng.cpp index f00d4c18f4d..b556cce83a5 100644 --- a/test/unittest/core/pattern/navigation/navigation_manager_test_ng.cpp +++ b/test/unittest/core/pattern/navigation/navigation_manager_test_ng.cpp @@ -830,6 +830,320 @@ HWTEST_F(NavigationManagerTestNg, FindNavigationInTargetParentTest002, TestSize. navigationManager->navigationMap_.clear(); } + +/** + * @tc.name: IsTargetIdOrDepthNavigation001 + * @tc.desc: Branch: if (dumpMap_.empty()) { => true; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, IsTargetIdOrDepthNavigation001, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager, and clear nestedSplitParaMap_. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + manager->nestedSplitParaMap_.clear(); + + /** + * @tc.steps: step2. get or create groupNode, and test IsTargetNavigation. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 3, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + EXPECT_FALSE(manager->IsTargetNavigation(node->GetId())); +} + +/** + * @tc.name: IsTargetIdOrDepthNavigation002 + * @tc.desc: Branch: procNestedNavSplit_ = true; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, IsTargetIdOrDepthNavigation002, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test IsTargetNavigation. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 3, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + auto id = node->GetId(); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->procNestedNavSplit_ = {true, -1}; + EXPECT_FALSE(manager->IsTargetNavigation(id)); + manager->procNestedNavSplit_ = {false, id}; + EXPECT_FALSE(manager->IsTargetNavigation(id)); + manager->procNestedNavSplit_ = {true, id}; + EXPECT_TRUE(manager->IsTargetNavigation(id)); + manager->nestedSplitParaMap_.clear(); + manager->procNestedNavSplit_ = {false, -1}; +} + +/** + * @tc.name: IsTargetIdOrDepthNavigation003 + * @tc.desc: Branch: if (iter != nestedSplitParaMap_.end()) => true; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, IsTargetIdOrDepthNavigation003, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test IsTargetNavigation. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->SetForceSplitNavigationDepth(2); + EXPECT_TRUE(manager->IsTargetNavigation(node->GetId())); + manager->nestedSplitParaMap_.clear(); +} + +/** + * @tc.name: IsTargetIdOrDepthNavigation004 + * @tc.desc: Branch: if (iter != nestedSplitParaMap_.end()) => true; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, IsTargetIdOrDepthNavigation004, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test IsTargetNavigation. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("navigation", 0)); + manager->SetForceSplitNavigationDepth(2); + manager->SetForceSplitNavigationId("navigation"); + EXPECT_TRUE(manager->IsTargetNavigation(node->GetId())); + manager->nestedSplitParaMap_.clear(); +} + +/** + * @tc.name: IsTargetIdOrDepthNavigation005 + * @tc.desc: Branch: if (iter != nestedSplitParaMap_.end()) => false; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, IsTargetIdOrDepthNavigation005, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test IsTargetNavigation. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("navigation", 0)); + manager->SetForceSplitNavigationDepth(3); + manager->SetForceSplitNavigationId("navigationThree"); + EXPECT_FALSE(manager->IsTargetNavigation(node->GetId())); + manager->nestedSplitParaMap_.clear(); +} + +/** + * @tc.name: AddNavigationForceSplitInfo001 + * @tc.desc: Branch: if (iter == hasProcessedDepth_.end()) => true; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, AddNavigationForceSplitInfo001, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test AddNavigationForceSplitInfo. + */ + manager->hasProcessedDepth_.clear(); + int32_t nodeId = -7; + int32_t depth = 1; + manager->AddNavigationForceSplitInfo(nodeId, depth, "navigationOne"); + EXPECT_FALSE(manager->hasProcessedDepth_.empty()); + EXPECT_EQ(manager->hasProcessedDepth_.size(), 1); +} + +/** + * @tc.name: AddNavigationForceSplitInfo002 + * @tc.desc: Branch: if (iter == hasProcessedDepth_.end()) => false; + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, AddNavigationForceSplitInfo002, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test AddNavigationForceSplitInfo. + */ + manager->hasProcessedDepth_.clear(); + int32_t nodeOneId = -7; + int32_t nodeTwoId = -3; + int32_t depth = 1; + EXPECT_TRUE(manager->hasProcessedDepth_.empty()); + manager->AddNavigationForceSplitInfo(nodeOneId, depth, "navigationOne"); + manager->AddNavigationForceSplitInfo(nodeTwoId, depth, "navigationTwo"); + EXPECT_FALSE(manager->hasProcessedDepth_.empty()); + EXPECT_EQ(manager->hasProcessedDepth_.size(), 1); +} + +/** + * @tc.name: RemoveNavigationForceSplitInfo001 + * @tc.desc: Branch: 1.if (it != nestedSplitParaMap_.end()) => false; + * 2.if (procNestedNavSplit_.second == nodeId) => false. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, RemoveNavigationForceSplitInfo001, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test RemoveNavigationForceSplitInfo. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->procNestedNavSplit_ = {true, -10}; + manager->RemoveNavigationForceSplitInfo(-1); + EXPECT_FALSE(manager->nestedSplitParaMap_.empty()); + EXPECT_EQ(manager->procNestedNavSplit_.first, true); + EXPECT_EQ(manager->procNestedNavSplit_.second, -10); + manager->nestedSplitParaMap_.clear(); + manager->procNestedNavSplit_ = {false, -1}; +} + +/** + * @tc.name: RemoveNavigationForceSplitInfo002 + * @tc.desc: Branch: 1.if (it != nestedSplitParaMap_.end()) => true; + * 2.if (procNestedNavSplit_.second == nodeId) => false. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, RemoveNavigationForceSplitInfo002, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test RemoveNavigationForceSplitInfo. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->procNestedNavSplit_ = {true, -1}; + manager->RemoveNavigationForceSplitInfo(node->GetId()); + EXPECT_TRUE(manager->nestedSplitParaMap_.empty()); + EXPECT_EQ(manager->procNestedNavSplit_.first, true); + EXPECT_EQ(manager->procNestedNavSplit_.second, -1); + manager->nestedSplitParaMap_.clear(); + manager->procNestedNavSplit_ = {false, -1}; +} + +/** + * @tc.name: RemoveNavigationForceSplitInfo003 + * @tc.desc: Branch: 1.if (it != nestedSplitParaMap_.end()) => false; + * 2.if (procNestedNavSplit_.second == nodeId) => true. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, RemoveNavigationForceSplitInfo003, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test RemoveNavigationForceSplitInfo. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->procNestedNavSplit_ = {true, -10}; + manager->RemoveNavigationForceSplitInfo(-10); + EXPECT_FALSE(manager->nestedSplitParaMap_.empty()); + EXPECT_EQ(manager->procNestedNavSplit_.first, false); + EXPECT_EQ(manager->procNestedNavSplit_.second, -1); + manager->nestedSplitParaMap_.clear(); + manager->procNestedNavSplit_ = {false, -1}; +} + +/** + * @tc.name: RemoveNavigationForceSplitInfo004 + * @tc.desc: Branch: 1.if (it != nestedSplitParaMap_.end()) => true; + * 2.if (procNestedNavSplit_.second == nodeId) => true. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(NavigationManagerTestNg, RemoveNavigationForceSplitInfo004, TestSize.Level1) +{ + /** + * @tc.steps: step1. get navigation manager. + */ + auto manager = GetNavigationManager(); + ASSERT_NE(manager, nullptr); + + /** + * @tc.steps: step2. get or create groupNode, and test RemoveNavigationForceSplitInfo. + */ + auto node = NavDestinationGroupNode::GetOrCreateGroupNode( + V2::NAVDESTINATION_VIEW_ETS_TAG, 1, []() { return AceType::MakeRefPtr(); }); + ASSERT_NE(node, nullptr); + manager->nestedSplitParaMap_.emplace(node->GetId(), NavigationManager::NestedNavForceSplitPara("", 2)); + manager->procNestedNavSplit_ = {true, node->GetId()}; + manager->RemoveNavigationForceSplitInfo(node->GetId()); + EXPECT_TRUE(manager->nestedSplitParaMap_.empty()); + EXPECT_EQ(manager->procNestedNavSplit_.first, false); + EXPECT_EQ(manager->procNestedNavSplit_.second, -1); + manager->nestedSplitParaMap_.clear(); + manager->procNestedNavSplit_ = {false, -1}; +} + /** * @tc.name: AddNavigationTest001 * @tc.desc: Branch: if iter == navigationMaps_.end() == true when find pageId -- Gitee