1 /*
2 * Copyright (c) 2023 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 #include "core/components_ng/pattern/navigation/inner_navigation_controller.h"
17
18 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
19
20 namespace OHOS {
21 namespace Ace {
22 namespace {
23 constexpr int32_t INVALID_HANDLE = 0;
24 }
InnerNavigationController(const WeakPtr<NG::NavigationPattern> & pattern)25 InnerNavigationController::InnerNavigationController(const WeakPtr<NG::NavigationPattern>& pattern)
26 : weakNavigationPattern_(pattern) {}
27
IsNavDestinationInTopStack()28 bool InnerNavigationController::IsNavDestinationInTopStack()
29 {
30 return GetTopHandle() != INVALID_HANDLE;
31 }
32
GetTopHandle()33 int32_t InnerNavigationController::GetTopHandle()
34 {
35 auto navigationPattern = weakNavigationPattern_.Upgrade();
36 CHECK_NULL_RETURN(navigationPattern, INVALID_HANDLE);
37 auto navigationStack = navigationPattern->GetNavigationStack();
38 CHECK_NULL_RETURN(navigationStack, INVALID_HANDLE);
39 auto topNavDestinationNode = navigationStack->GetTopNavPath();
40 if (!topNavDestinationNode.has_value()) {
41 return INVALID_HANDLE;
42 }
43
44 auto navDestinationNode = AceType::DynamicCast<NG::NavDestinationGroupNode>(
45 NG::NavigationGroupNode::GetNavDestinationNode(topNavDestinationNode->second));
46 CHECK_NULL_RETURN(navDestinationNode, INVALID_HANDLE);
47 return topNavDestinationNode->second->GetId();
48 }
49
SetInPIPMode(int32_t handle)50 void InnerNavigationController::SetInPIPMode(int32_t handle)
51 {
52 auto navigationPattern = weakNavigationPattern_.Upgrade();
53 CHECK_NULL_VOID(navigationPattern);
54 auto navigationStack = navigationPattern->GetNavigationStack();
55 CHECK_NULL_VOID(navigationStack);
56 auto cacheNode = navigationStack->GetFromCacheNode(handle);
57 if (cacheNode.has_value()) {
58 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "The node has in cache");
59 return;
60 }
61
62 const auto& navDestinationNodes = navigationStack->GetAllNavDestinationNodes();
63 for (size_t i = 0; i != navDestinationNodes.size(); ++i) {
64 const auto& childNode = navDestinationNodes[i];
65 const auto& uiNode = childNode.second;
66 if (uiNode && uiNode->GetId() == handle) {
67 auto navDestination = AceType::DynamicCast<NG::NavDestinationGroupNode>(
68 NG::NavigationGroupNode::GetNavDestinationNode(uiNode));
69 if (navDestination == nullptr) {
70 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "The node is not navDestination node");
71 return;
72 }
73
74 navigationStack->AddCacheNode(childNode.first, uiNode);
75 return;
76 }
77 }
78 }
79
PopInPIP(bool destroy)80 void InnerNavigationController::PopInPIP(bool destroy)
81 {
82 auto navigationPattern = weakNavigationPattern_.Upgrade();
83 CHECK_NULL_VOID(navigationPattern);
84 auto navigationStack = navigationPattern->GetNavigationStack();
85 CHECK_NULL_VOID(navigationStack);
86 auto topNavDestinationNode = navigationStack->GetTopNavPath();
87 if (!topNavDestinationNode.has_value()) {
88 return;
89 }
90
91 if (destroy && topNavDestinationNode->second) {
92 navigationStack->RemoveCacheNode(topNavDestinationNode->second->GetId());
93 }
94
95 navigationStack->Pop();
96 }
97
PushInPIP(int32_t handle)98 void InnerNavigationController::PushInPIP(int32_t handle)
99 {
100 auto navigationPattern = weakNavigationPattern_.Upgrade();
101 CHECK_NULL_VOID(navigationPattern);
102 auto navigationStack = navigationPattern->GetNavigationStack();
103 CHECK_NULL_VOID(navigationStack);
104 auto topNavDestinationNode = navigationStack->GetTopNavPath();
105 if (topNavDestinationNode.has_value()) {
106 if (topNavDestinationNode->second && topNavDestinationNode->second->GetId() == handle) {
107 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "The node has in top stack");
108 return;
109 }
110 }
111 auto cacheNode = navigationStack->GetFromCacheNode(handle);
112 if (!cacheNode.has_value()) {
113 return;
114 }
115
116 navigationStack->ReOrderCache(cacheNode->first, cacheNode->second);
117 auto context = PipelineContext::GetCurrentContext();
118 CHECK_NULL_VOID(context);
119 context->GetTaskExecutor()->PostTask(
120 [weakStack = AceType::WeakClaim(AceType::RawPtr(navigationStack)), name = cacheNode->first] {
121 auto stack = weakStack.Upgrade();
122 CHECK_NULL_VOID(stack);
123 stack->Push(name);
124 }, TaskExecutor::TaskType::UI);
125 }
126
DeletePIPMode(int32_t handle)127 void InnerNavigationController::DeletePIPMode(int32_t handle)
128 {
129 auto navigationPattern = weakNavigationPattern_.Upgrade();
130 CHECK_NULL_VOID(navigationPattern);
131 auto navigationStack = navigationPattern->GetNavigationStack();
132 CHECK_NULL_VOID(navigationStack);
133 navigationStack->RemoveCacheNode(handle);
134 }
135 } // namespace Ace
136 } // namespace OHOS
137