• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "mock_navigation_stack.h"
17 
18 namespace OHOS::Ace::NG {
19 
20 namespace {
CheckIndexValid(int32_t index,size_t maxSize)21 bool CheckIndexValid(int32_t index, size_t maxSize)
22 {
23     return index >= 0 && index < static_cast<int32_t>(maxSize);
24 }
25 } // namespace
26 
FindInPopArray(const std::string & name)27 std::pair<int32_t, std::string> MockNavigationStack::FindInPopArray(const std::string& name)
28 {
29     for (int32_t index = int(mockPopArray_.size()) - 1; index >= 0; --index) {
30         auto info = mockPopArray_[index];
31         if (info->GetName() == name) {
32             auto ret = std::make_pair(info->index, info->GetNavDestinationId());
33             auto iter = mockPopArray_.begin();
34             std::advance(iter, index);
35             mockPopArray_.erase(iter);
36             return ret;
37         }
38     }
39     return std::make_pair(-1, UNDEFINED_ID);
40 }
41 
FireNavigationInterception(bool isBefore,const RefPtr<NavDestinationContext> & from,const RefPtr<NavDestinationContext> & to,NavigationOperation operation,bool isAnimated)42 void MockNavigationStack::FireNavigationInterception(bool isBefore, const RefPtr<NavDestinationContext>& from,
43     const RefPtr<NavDestinationContext>& to, NavigationOperation operation, bool isAnimated)
44 {
45     if (isBefore) {
46         if (beforeCallback_) {
47             beforeCallback_(from, to, operation, isAnimated);
48         }
49     } else {
50         if (afterCallback_) {
51             afterCallback_(from, to, operation, isAnimated);
52         }
53     }
54 }
55 
CreateNodeByIndex(int32_t index,const OHOS::Ace::WeakPtr<OHOS::Ace::NG::UINode> & customNode,OHOS::Ace::RefPtr<OHOS::Ace::NG::UINode> & node)56 bool MockNavigationStack::CreateNodeByIndex(int32_t index, const OHOS::Ace::WeakPtr<OHOS::Ace::NG::UINode>& customNode,
57     OHOS::Ace::RefPtr<OHOS::Ace::NG::UINode>& node)
58 {
59     auto* stack = ViewStackProcessor::GetInstance();
60     // navDestination node
61     int32_t nodeId = stack->ClaimNodeId();
62     auto frameNode = NavDestinationGroupNode::GetOrCreateGroupNode(
63         V2::NAVDESTINATION_VIEW_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<NavDestinationPattern>(); });
64     EXPECT_NE(frameNode, nullptr);
65     auto name = mockPathArray_[index]->GetName();
66     auto container = MockContainer::Current();
67     auto navigationRoute = container->GetNavigationRoute();
68     if (!navigationRoute) {
69         return false;
70     }
71     if (!navigationRoute->HasLoaded(name)) {
72         int32_t res = navigationRoute->LoadPage(name);
73         if (res != 0) {
74             node = frameNode;
75             return true;
76         }
77     }
78     node = frameNode;
79     auto pattern = AceType::DynamicCast<NavDestinationPattern>(frameNode->GetPattern());
80     EXPECT_NE(pattern, nullptr);
81     pattern->SetName(name);
82     auto navDestinationId = std::to_string(pattern->GetNavDestinationId());
83     mockPathArray_[index]->SetNavDestinationId(navDestinationId);
84     return true;
85 }
86 
Push(const std::string & name,const RefPtr<RouteInfo> & routeInfo)87 void MockNavigationStack::Push(const std::string& name, const RefPtr<RouteInfo>& routeInfo)
88 {
89     MockPushPath(AceType::MakeRefPtr<MockNavPathInfo>(name));
90 }
91 
Push(const std::string & name,int32_t index)92 void MockNavigationStack::Push(const std::string& name, int32_t index)
93 {
94     MockPushPath(AceType::MakeRefPtr<MockNavPathInfo>(name));
95 }
96 
GetAllPathName()97 std::vector<std::string> MockNavigationStack::GetAllPathName()
98 {
99     std::vector<std::string> pathNames;
100     for (int32_t i = 0; i < static_cast<int32_t>(mockPathArray_.size()); i++) {
101         pathNames.emplace_back(mockPathArray_[i]->GetName());
102     }
103     return pathNames;
104 }
105 
GetAllPathIndex()106 std::vector<int32_t> MockNavigationStack::GetAllPathIndex()
107 {
108     if (mockPathArray_.empty()) {
109         return {};
110     }
111     std::vector<int32_t> pathIndex;
112     for (int32_t i = 0; i < static_cast<int32_t>(mockPathArray_.size()); i++) {
113         pathIndex.emplace_back(i);
114     }
115     return pathIndex;
116 }
117 
Clear()118 void MockNavigationStack::Clear()
119 {
120     NavigationStack::Clear();
121     mockPathArray_.clear();
122 }
123 
Pop()124 void MockNavigationStack::Pop()
125 {
126     mockPopArray_.emplace_back(mockPathArray_.back());
127     auto info = mockPopArray_.back();
128     mockPathArray_.pop_back();
129     if (info->GetOnPop()) {
130         info->GetOnPop();
131     }
132 }
133 
PopToIndex(int32_t index)134 void MockNavigationStack::PopToIndex(int32_t index)
135 {
136     auto iter = mockPathArray_.begin();
137     std::advance(iter, index + 1);
138     mockPathArray_.erase(iter, mockPathArray_.end());
139 }
140 
InitNavPathIndex(const std::vector<std::string> & pathNames)141 void MockNavigationStack::InitNavPathIndex(const std::vector<std::string>& pathNames)
142 {
143     mockPopArray_.clear();
144     for (size_t index = 0; index < mockPathArray_.size() && index < pathNames.size(); index++) {
145         if (pathNames[index] == mockPathArray_[index]->GetName() && GetReplaceValue() != 1) {
146             mockPathArray_[index]->index = index;
147         }
148     }
149 }
150 
SetDestinationIdToJsStack(int32_t index,const std::string & navDestinationId)151 void MockNavigationStack::SetDestinationIdToJsStack(int32_t index, const std::string& navDestinationId)
152 {
153     if (index < 0 || index >= static_cast<int32_t>(mockPathArray_.size())) {
154         return;
155     }
156     mockPathArray_[index]->SetNavDestinationId(navDestinationId);
157 }
158 
MockPushPath(const RefPtr<MockNavPathInfo> & info,bool animated,LaunchMode launchmode)159 void MockNavigationStack::MockPushPath(const RefPtr<MockNavPathInfo>& info, bool animated, LaunchMode launchmode)
160 {
161     if (launchmode == LaunchMode::NEW_INSTANCE) {
162         info->needBuildNewInstance = true;
163     }
164     auto indexAndId = FindInPopArray(info->GetName());
165     if (indexAndId.first != -1 && indexAndId.second != UNDEFINED_ID) {
166         info->index = indexAndId.first;
167         info->SetNavDestinationId(indexAndId.second);
168     }
169     animated_ = animated;
170     mockPathArray_.push_back(info);
171 }
172 
NeedBuildNewInstance(int32_t index)173 bool MockNavigationStack::NeedBuildNewInstance(int32_t index)
174 {
175     if (!CheckIndexValid(index, mockPathArray_.size())) {
176         return false;
177     }
178     return mockPathArray_[index]->needBuildNewInstance;
179 }
180 
SetNeedBuildNewInstance(int32_t index,bool need)181 void MockNavigationStack::SetNeedBuildNewInstance(int32_t index, bool need)
182 {
183     if (!CheckIndexValid(index, mockPathArray_.size())) {
184         return;
185     }
186     mockPathArray_[index]->needBuildNewInstance = need;
187 }
188 
SetPathArray(const std::vector<NavdestinationRecoveryInfo> & navdestinationsInfo)189 void MockNavigationStack::SetPathArray(const std::vector<NavdestinationRecoveryInfo>& navdestinationsInfo)
190 {
191     std::vector<RefPtr<MockNavPathInfo>> newPathArray;
192     for (auto recoveryInfo : navdestinationsInfo) {
193         auto navPathInfo = AceType::MakeRefPtr<MockNavPathInfo>(recoveryInfo.name);
194         navPathInfo->mode = recoveryInfo.mode;
195         navPathInfo->fromRecovery = true;
196         newPathArray.push_back(navPathInfo);
197     }
198     mockPathArray_ = newPathArray;
199 }
200 
SetFromRecovery(int32_t index,bool fromRecovery)201 void MockNavigationStack::SetFromRecovery(int32_t index, bool fromRecovery)
202 {
203     if (!CheckIndexValid(index, mockPathArray_.size())) {
204         return;
205     }
206     mockPathArray_[index]->fromRecovery = fromRecovery;
207 }
208 
IsFromRecovery(int32_t index)209 bool MockNavigationStack::IsFromRecovery(int32_t index)
210 {
211     if (!CheckIndexValid(index, mockPathArray_.size())) {
212         return false;
213     }
214     return mockPathArray_[index]->fromRecovery;
215 }
216 
MockRemoveByNavDestinationId(const std::string & navDestinationId)217 bool MockNavigationStack::MockRemoveByNavDestinationId(const std::string& navDestinationId)
218 {
219     for (auto it = mockPathArray_.begin(); it != mockPathArray_.end(); ++ it) {
220         auto info = *it;
221         if (info->GetNavDestinationId() == navDestinationId) {
222             mockPathArray_.erase(it);
223             return true;
224         }
225     }
226     return false;
227 }
228 
MockRemoveByInexes(std::vector<int32_t> indexes)229 int32_t MockNavigationStack::MockRemoveByInexes(std::vector<int32_t> indexes)
230 {
231     int32_t deleteCount = 0;
232     for (auto it = mockPathArray_.begin(); it != mockPathArray_.end();) {
233         auto info = *it;
234         if (std::find(indexes.begin(), indexes.end(), info->index) != indexes.end()) {
235             mockPathArray_.erase(it);
236             deleteCount++;
237             continue;
238         }
239         it++;
240     }
241     return deleteCount;
242 }
243 
MockRemoveByName(const std::string & name)244 int32_t MockNavigationStack::MockRemoveByName(const std::string& name)
245 {
246     int32_t deleteCount = 0;
247     for (auto it = mockPathArray_.begin(); it != mockPathArray_.end();) {
248         auto info = *it;
249         if (info->GetName() == name) {
250             mockPathArray_.erase(it);
251             deleteCount++;
252             continue;
253         }
254         it++;
255     }
256     return deleteCount;
257 }
258 
GetNavDestinationIdByIndex(int32_t index)259 std::string MockNavigationStack::GetNavDestinationIdByIndex(int32_t index)
260 {
261     if (!CheckIndexValid(index, mockPathArray_.size())) {
262         return "";
263     }
264     return mockPathArray_[index]->GetNavDestinationId();
265 }
266 
MockPopToName(const std::string & name)267 int32_t MockNavigationStack::MockPopToName(const std::string& name)
268 {
269     int32_t candidateIndex = -1;
270     for (int32_t index = 0; index < static_cast<int32_t>(mockPathArray_.size()); ++index) {
271         if (mockPathArray_[index]->GetName() == name) {
272             candidateIndex = index;
273             break;
274         }
275     }
276     if (candidateIndex != -1) {
277         auto preStackSize = Size();
278         for (int32_t index = candidateIndex + 1; index < preStackSize; ++index) {
279             mockPathArray_.pop_back();
280         }
281     }
282     return candidateIndex;
283 }
284 
MockPopToIndex(int32_t index)285 void MockNavigationStack::MockPopToIndex(int32_t index)
286 {
287     if (!CheckIndexValid(index, mockPathArray_.size())) {
288         return;
289     }
290     auto preStackSize = Size();
291     for (int32_t removeCount = index + 1; removeCount < preStackSize; ++removeCount) {
292         mockPathArray_.pop_back();
293     }
294 }
295 
MockMoveToTop(const std::string & name)296 int32_t MockNavigationStack::MockMoveToTop(const std::string& name)
297 {
298     int32_t candidateIndex = -1;
299     for (int32_t index = 0; index < static_cast<int32_t>(mockPathArray_.size()); ++index) {
300         if (mockPathArray_[index]->GetName() == name) {
301             candidateIndex = index;
302             break;
303         }
304     }
305     if (candidateIndex != -1) {
306         auto movedInfo = mockPathArray_[candidateIndex];
307         auto it = mockPathArray_.begin();
308         std::advance(it, candidateIndex);
309         mockPathArray_.erase(it);
310         mockPathArray_.push_back(movedInfo);
311     }
312     return candidateIndex;
313 }
314 
SetIsEntryByIndex(int32_t index,bool isEntry)315 void MockNavigationStack::SetIsEntryByIndex(int32_t index, bool isEntry)
316 {
317     mockIsEntryMap_[index] = isEntry;
318 }
319 
MockGetPathStack()320 std::vector<RefPtr<MockNavPathInfo>> MockNavigationStack::MockGetPathStack()
321 {
322     std::vector<RefPtr<MockNavPathInfo>> pathArray;
323     for (int32_t index = 0; index < static_cast<int32_t>(mockPathArray_.size()); ++index) {
324         pathArray.push_back(mockPathArray_[index]);
325     }
326     return pathArray;
327 }
328 
MockSetPathStack(std::vector<RefPtr<MockNavPathInfo>> & setPathArray,bool animated)329 void MockNavigationStack::MockSetPathStack(std::vector<RefPtr<MockNavPathInfo>>& setPathArray, bool animated)
330 {
331     Clear();
332     for (int32_t index = 0; index < static_cast<int32_t>(setPathArray.size()); ++index) {
333         mockPathArray_.push_back(setPathArray[index]);
334     }
335     animated_ = animated;
336 }
337 
GetRecoveredDestinationMode(int32_t index)338 int32_t MockNavigationStack::GetRecoveredDestinationMode(int32_t index)
339 {
340     if (!CheckIndexValid(index, mockPathArray_.size())) {
341         return 0;
342     }
343 
344     return mockPathArray_[index]->mode;
345 }
346 
GetNavDestinationIdInt(int32_t index)347 uint64_t MockNavigationStack::GetNavDestinationIdInt(int32_t index)
348 {
349     if (!CheckIndexValid(index, mockPathArray_.size())) {
350         return -1;
351     }
352 
353     return std::atol(mockPathArray_[index]->GetNavDestinationId().c_str());
354 }
355 
GetIsForceSet(int32_t index)356 bool MockNavigationStack::GetIsForceSet(int32_t index)
357 {
358     if (!CheckIndexValid(index, mockPathArray_.size())) {
359         return false;
360     }
361 
362     return mockPathArray_[index]->isForceSet;
363 }
364 
ResetIsForceSetFlag(int32_t index)365 void MockNavigationStack::ResetIsForceSetFlag(int32_t index)
366 {
367     if (!CheckIndexValid(index, mockPathArray_.size())) {
368         return;
369     }
370 
371     mockPathArray_[index]->isForceSet = false;
372 }
373 
CheckIsReplacedDestination(int32_t index,std::string & replacedName,int32_t & replacedIndex)374 bool MockNavigationStack::CheckIsReplacedDestination(int32_t index, std::string& replacedName, int32_t& replacedIndex)
375 {
376     if (!CheckIndexValid(index, mockPathArray_.size())) {
377         return false;
378     }
379 
380     return mockPathArray_[index]->isReplaced;
381 }
382 
SetRecoveryFromReplaceDestination(int32_t index,bool value)383 void MockNavigationStack::SetRecoveryFromReplaceDestination(int32_t index, bool value)
384 {
385     if (!CheckIndexValid(index, mockPathArray_.size())) {
386         return;
387     }
388 
389     mockPathArray_[index]->isReplaced = value;
390 }
391 } // namespace OHOS::Ace::NG