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 #include "core/components_ng/manager/navigation/navigation_manager.h"
17
18 #include <string>
19
20 #include "base/log/dump_log.h"
21 #include "base/thread/task_executor.h"
22 #include "core/common/thread_checker.h"
23 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
24 #include "core/components_ng/pattern/navigation/navigation_stack.h"
25
26
27 namespace OHOS::Ace::NG {
AddNavigationDumpCallback(int32_t nodeId,int32_t depth,const DumpCallback & callback)28 void NavigationManager::AddNavigationDumpCallback(int32_t nodeId, int32_t depth, const DumpCallback& callback)
29 {
30 CHECK_RUN_ON(UI);
31 dumpMap_.emplace(DumpMapKey(nodeId, depth), callback);
32 }
33
RemoveNavigationDumpCallback(int32_t nodeId,int32_t depth)34 void NavigationManager::RemoveNavigationDumpCallback(int32_t nodeId, int32_t depth)
35 {
36 CHECK_RUN_ON(UI);
37 auto it = dumpMap_.find(DumpMapKey(nodeId, depth));
38 if (it != dumpMap_.end()) {
39 dumpMap_.erase(it);
40 }
41 }
42
OnDumpInfo()43 void NavigationManager::OnDumpInfo()
44 {
45 constexpr int NAVIGATION_DUMP_DEPTH = 2;
46 CHECK_RUN_ON(UI);
47 DumpLog::GetInstance().Print("Navigation number: " + std::to_string(dumpMap_.size()));
48 int navIdx = 0;
49 for (auto it = dumpMap_.begin(); it != dumpMap_.end(); ++it) {
50 DumpLog::GetInstance().Print(1, "Navigation[" + std::to_string(navIdx) + "] ID: " +
51 std::to_string(it->first.nodeId) + ", Depth: " + std::to_string(it->first.depth) + ", NavPathStack:");
52 if (it->second) {
53 it->second(NAVIGATION_DUMP_DEPTH);
54 }
55 navIdx++;
56 }
57 }
58
FireNavigationUpdateCallback()59 void NavigationManager::FireNavigationUpdateCallback()
60 {
61 for (const auto& func : updateCallbacks_) {
62 func();
63 }
64 updateCallbacks_.clear();
65 }
66
GetNavigationInfo(const RefPtr<AceType> & node)67 std::shared_ptr<NavigationInfo> NavigationManager::GetNavigationInfo(const RefPtr<AceType>& node)
68 {
69 RefPtr<UINode> current = nullptr;
70 auto customNode = AceType::DynamicCast<CustomNode>(node);
71 if (customNode) {
72 current = customNode->GetNavigationNode().Upgrade();
73 }
74
75 if (!current) {
76 current = AceType::DynamicCast<UINode>(node);
77 while (current) {
78 if (current->GetTag() == V2::NAVIGATION_VIEW_ETS_TAG) {
79 break;
80 }
81 current = current->GetParent();
82 }
83 }
84
85 if (!current) {
86 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "find parent navigation node failed");
87 return nullptr;
88 }
89
90 auto navigation = AceType::DynamicCast<NavigationGroupNode>(current);
91 CHECK_NULL_RETURN(navigation, nullptr);
92 auto pattern = navigation->GetPattern<NavigationPattern>();
93 CHECK_NULL_RETURN(pattern, nullptr);
94 auto stack = pattern->GetNavigationStack();
95 CHECK_NULL_RETURN(stack, nullptr);
96 return std::make_shared<NavigationInfo>(navigation->GetInspectorId().value_or(""), stack);
97 }
98
AddInteractiveAnimation(const std::function<void ()> & addCallback)99 bool NavigationManager::AddInteractiveAnimation(const std::function<void()>& addCallback)
100 {
101 if (!isInteractive_) {
102 return false;
103 }
104 auto navigationGroupNode = AceType::DynamicCast<NavigationGroupNode>(
105 FrameNode::GetFrameNode(V2::NAVIGATION_VIEW_ETS_TAG, interactiveAnimationId_));
106 CHECK_NULL_RETURN(navigationGroupNode, false);
107 auto pattern = navigationGroupNode->GetPattern<NavigationPattern>();
108 CHECK_NULL_RETURN(pattern, false);
109 auto proxy = pattern->GetTopNavigationProxy();
110 CHECK_NULL_RETURN(proxy, false);
111 proxy->AddInteractiveAnimation(addCallback);
112 return true;
113 }
114
AddRecoverableNavigation(std::string id,RefPtr<AceType> navigationNode)115 bool NavigationManager::AddRecoverableNavigation(std::string id, RefPtr<AceType> navigationNode)
116 {
117 auto navigation = AceType::DynamicCast<NavigationGroupNode>(navigationNode);
118 CHECK_NULL_RETURN(navigation, false);
119 if (!navigation->CanRecovery() || id != navigation->GetCurId()) {
120 return false;
121 }
122 recoverableNavigationMap_[id] = navigationNode;
123 return true;
124 }
125
GetNavigationJsonInfo()126 std::unique_ptr<JsonValue> NavigationManager::GetNavigationJsonInfo()
127 {
128 auto allNavigationInfo = JsonUtil::CreateArray(true);
129 for (auto iter : recoverableNavigationMap_) {
130 auto node = iter.second.Upgrade();
131 if (!node) {
132 continue;
133 }
134 auto navigation = AceType::DynamicCast<NavigationGroupNode>(node);
135 if (!navigation->CanRecovery()) {
136 continue;
137 }
138 auto navigationPattern = navigation->GetPattern<NavigationPattern>();
139 if (!navigationPattern) {
140 continue;
141 }
142 auto navigationInfo = JsonUtil::Create(true);
143 navigationInfo->Put("id", iter.first.c_str());
144 navigationInfo->Put("stack", navigationPattern->GetNavdestinationJsonArray());
145 allNavigationInfo->Put(navigationInfo);
146 }
147 return allNavigationInfo;
148 }
149
StorageNavigationRecoveryInfo(std::unique_ptr<JsonValue> navigationRecoveryInfo)150 void NavigationManager::StorageNavigationRecoveryInfo(std::unique_ptr<JsonValue> navigationRecoveryInfo)
151 {
152 auto allNavigationInfo = std::move(navigationRecoveryInfo);
153 if (!allNavigationInfo || !allNavigationInfo->IsArray()) {
154 TAG_LOGW(AceLogTag::ACE_NAVIGATION, "Navigation recovery info invalid, can not restore!");
155 return;
156 }
157 auto arraySize = allNavigationInfo->GetArraySize();
158 for (int32_t i = 0; i < arraySize; ++ i) {
159 auto navigationInfo = allNavigationInfo->GetArrayItem(i);
160 auto navigationId = navigationInfo->GetString("id");
161 auto stackInfo = navigationInfo->GetValue("stack");
162 if (!stackInfo->IsArray()) {
163 continue;
164 }
165 std::vector<NavdestinationRecoveryInfo> navdestinationsInfo;
166 auto stackSize = stackInfo->GetArraySize();
167 for (int32_t j = 0; j < stackSize; ++ j) {
168 auto navdestinationInfo = stackInfo->GetArrayItem(j);
169 auto name = navdestinationInfo->GetString("name");
170 auto param = navdestinationInfo->GetString("param");
171 auto mode = navdestinationInfo->GetInt("mode");
172 navdestinationsInfo.emplace_back(NavdestinationRecoveryInfo(name, param, mode));
173 }
174 navigationRecoveryInfo_[navigationId] = navdestinationsInfo;
175 }
176 }
177
GetNavigationRecoveryInfo(std::string navigationId)178 const std::vector<NavdestinationRecoveryInfo> NavigationManager::GetNavigationRecoveryInfo(std::string navigationId)
179 {
180 if (navigationRecoveryInfo_.find(navigationId) == navigationRecoveryInfo_.end()) {
181 return {};
182 }
183 auto ret = navigationRecoveryInfo_[navigationId];
184 navigationRecoveryInfo_.erase(navigationId);
185 return ret;
186 }
187 } // namespace OHOS::Ace::NG
188