• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "gtest/gtest.h"
16 
17 #define private public
18 #define protected public
19 #include "test/mock/core/common/mock_resource_adapter.h"
20 #include "test/mock/core/common/mock_theme_manager.h"
21 #include "test/mock/core/pipeline/mock_pipeline_context.h"
22 #include "test/mock/core/render/mock_render_context.h"
23 #include "test/unittest/core/event/focus_core/focus_test_base.h"
24 #include "test/unittest/core/event/focus_core/page_focus_switch_test.h"
25 #include "test/unittest/core/pattern/test_ng.h"
26 
27 #include "base/log/log_wrapper.h"
28 #include "core/components/container_modal/container_modal_constants.h"
29 #include "core/components/flex/flex_element.h"
30 #include "core/components/theme/theme_constants.h"
31 #include "core/components_ng/base/ui_node.h"
32 #include "core/components_ng/base/view_stack_processor.h"
33 #include "core/components_ng/event/focus_hub.h"
34 #include "core/components_ng/pattern/bubble/bubble_pattern.h"
35 #include "core/components_ng/pattern/button/button_pattern.h"
36 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
37 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
38 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
39 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
40 #include "core/components_ng/pattern/image/image_layout_property.h"
41 #include "core/components_ng/pattern/image/image_pattern.h"
42 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
43 #include "core/components_ng/pattern/menu/menu_pattern.h"
44 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
45 #include "core/components_ng/pattern/pattern.h"
46 #include "core/components_ng/pattern/root/root_pattern.h"
47 #include "core/components_ng/pattern/stack/stack_pattern.h"
48 #include "core/components_ng/pattern/text/text_pattern.h"
49 #include "core/components_ng/pattern/text_picker/textpicker_column_pattern.h"
50 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
51 #include "core/event/focus_axis_event.h"
52 #include "core/event/key_event.h"
53 #include "core/pipeline/base/composed_element.h"
54 #include "core/pipeline_ng/pipeline_context.h"
55 #include "frameworks/bridge/common/utils/engine_helper.h"
56 
57 using namespace testing;
58 using namespace testing::ext;
59 namespace OHOS::Ace::NG {
60 
61 struct PageFocusSwitchCase {
62     std::string newPageType;
63     bool isAutoFocusTransfer;
64     bool isHasDefaultFocus;
65     bool expectResults;
PageFocusSwitchCaseOHOS::Ace::NG::PageFocusSwitchCase66     PageFocusSwitchCase(
67         const std::string& newPageType, bool isAutoFocusTransfer, bool isHasDefaultFocus, bool expectResults)
68         : newPageType(newPageType), isAutoFocusTransfer(isAutoFocusTransfer), isHasDefaultFocus(isHasDefaultFocus),
69           expectResults(expectResults)
70     {}
71 };
72 
73 const std::vector<PageFocusSwitchCase> PAGE_FOCUS_SWITCH_CASE = { PageFocusSwitchCase("page", true, true, true),
74     PageFocusSwitchCase("page", true, false, true), PageFocusSwitchCase("dialog", true, true, true),
75     PageFocusSwitchCase("menu", true, true, true), PageFocusSwitchCase("popup", true, true, true),
76     PageFocusSwitchCase("modalpage", true, true, true), PageFocusSwitchCase("sheetpag", true, true, true),
77     PageFocusSwitchCase("navigation", true, true, true), PageFocusSwitchCase("navbar", true, true, true),
78     PageFocusSwitchCase("navdestination", true, true, true), PageFocusSwitchCase("windowscene", true, true, true) };
79 
SetUpTestSuite()80 void PageFocusSwitchTestNG::SetUpTestSuite()
81 {
82     MockPipelineContext::SetUp();
83     GTEST_LOG_(INFO) << "PageFocusSwitchTestNG SetUpTestCase";
84 }
85 
TearDownTestSuite()86 void PageFocusSwitchTestNG::TearDownTestSuite()
87 {
88     MockPipelineContext::TearDown();
89     GTEST_LOG_(INFO) << "PageFocusSwitchTestNG TearDownTestCase";
90 }
91 
92 HWTEST_F(PageFocusSwitchTestNG, FocusWindowTestNG001, TestSize.Level1)
93 {
94     int32_t caseNum = 1;
95     bool initResult = InitFocusTestBaseNG();
96     EXPECT_TRUE(initResult);
97     for (const auto& testCase : PAGE_FOCUS_SWITCH_CASE) {
98         // get newPageType and creat node tree
99         if (testCase.newPageType == "Page") {
100             // creat root node
101             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
102             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
103             // creat node
104             auto oldpagePattern = AceType::MakeRefPtr<PagePattern>(AceType::MakeRefPtr<PageInfo>());
105             auto oldPageNode = FrameNodeOnTree::CreateFrameNode(V2::PAGE_ETS_TAG, -1, oldpagePattern);
106             auto oldFocusHub = oldPageNode->GetOrCreateFocusHub();
107             rootNode->AddChild(oldPageNode);
108             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
109             if (testCase.isAutoFocusTransfer) {
110                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
111                 CHECK_NULL_VOID(delegate);
112                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
113             }
114             auto newpagePattern = AceType::MakeRefPtr<PagePattern>(AceType::MakeRefPtr<PageInfo>());
115             auto newPageNode = FrameNodeOnTree::CreateFrameNode(V2::PAGE_ETS_TAG, -1, newpagePattern);
116             auto newFocusHub = newPageNode->GetOrCreateFocusHub();
117             oldPageNode->AddChild(newPageNode);
118             // set default focus
119             if (testCase.isHasDefaultFocus) {
120                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
121             }
122             // check old node lost focus ,new node get focus
123             auto currentFocusNode = focusManager_->GetFocusManager(newPageNode);
124             EXPECT_EQ(oldPageNode, currentFocusNode);
125             EXPECT_NE(newPageNode, currentFocusNode);
126         } else if (testCase.newPageType == "dialog") {
127             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
128             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
129             auto dialogPattern = AceType::MakeRefPtr<DialogPattern>(nullptr, nullptr);
130             auto oldDialogNode = FrameNodeOnTree::CreateFrameNode(V2::DIALOG_ETS_TAG, -1, dialogPattern);
131             auto oldFocusHub = oldDialogNode->GetOrCreateFocusHub();
132             rootNode->AddChild(oldDialogNode);
133             if (testCase.isAutoFocusTransfer) {
134                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
135                 CHECK_NULL_VOID(delegate);
136                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
137             }
138             auto newdialogPattern = AceType::MakeRefPtr<DialogPattern>(nullptr, nullptr);
139             auto newDialogNode = FrameNodeOnTree::CreateFrameNode(V2::DIALOG_ETS_TAG, -1, newdialogPattern);
140             auto newFocusHub = newDialogNode->GetOrCreateFocusHub();
141             oldDialogNode->AddChild(newDialogNode);
142 
143             if (testCase.isHasDefaultFocus) {
144                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
145             }
146             auto currentFocusNode = focusManager_->GetFocusManager(newDialogNode);
147             CHECK_NULL_VOID(currentFocusNode);
148             EXPECT_EQ(oldDialogNode, currentFocusNode);
149             EXPECT_NE(newDialogNode, currentFocusNode);
150 
151         } else if (testCase.newPageType == "menu") {
152             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
153             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
154             auto menuPattern = AceType::MakeRefPtr<MenuPattern>(-1, "Menu", MenuType::MENU);
155             auto oldMenuNode = FrameNodeOnTree::CreateFrameNode(V2::MENU_ETS_TAG, -1, menuPattern);
156             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
157             auto oldFocusHub = oldMenuNode->GetOrCreateFocusHub();
158             rootNode->AddChild(oldMenuNode);
159             if (testCase.isAutoFocusTransfer) {
160                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
161                 CHECK_NULL_VOID(delegate);
162                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
163             }
164             auto newMenuNode = FrameNodeOnTree::CreateFrameNode(V2::MENU_ETS_TAG, -1, menuPattern);
165             auto newFocusHub = newMenuNode->GetOrCreateFocusHub();
166             oldMenuNode->AddChild(newMenuNode);
167             if (testCase.isHasDefaultFocus) {
168                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
169             }
170             auto currentFocusNode = focusManager_->GetFocusManager(newMenuNode);
171             CHECK_NULL_VOID(currentFocusNode);
172             EXPECT_EQ(oldMenuNode, currentFocusNode);
173             EXPECT_NE(newMenuNode, currentFocusNode);
174         } else if (testCase.newPageType == "popup") {
175             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
176             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
177             auto bubblePattern = AceType::MakeRefPtr<BubblePattern>();
178             auto oldPopupNode = FrameNodeOnTree::CreateFrameNode(V2::POPUP_ETS_TAG, -1, bubblePattern);
179             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
180             auto oldFocusHub = oldPopupNode->GetOrCreateFocusHub();
181             rootNode->AddChild(oldPopupNode);
182             if (testCase.isAutoFocusTransfer) {
183                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
184                 CHECK_NULL_VOID(delegate);
185                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
186             }
187             auto newPopupNode = FrameNodeOnTree::CreateFrameNode(V2::POPUP_ETS_TAG, -1, bubblePattern);
188             auto newFocusHub = newPopupNode->GetOrCreateFocusHub();
189             oldPopupNode->AddChild(newPopupNode);
190             if (testCase.isHasDefaultFocus) {
191                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
192             }
193             auto currentFocusNode = focusManager_->GetFocusManager(newPopupNode);
194             CHECK_NULL_VOID(currentFocusNode);
195             EXPECT_EQ(oldPopupNode, currentFocusNode);
196             EXPECT_NE(newPopupNode, currentFocusNode);
197         } else if (testCase.newPageType == "modalpage") {
198             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
199             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
200             auto modalPattern = AceType::MakeRefPtr<ModalPresentationPattern>(-1, ModalTransition::DEFAULT, nullptr);
201             auto oldModelpageNode = FrameNodeOnTree::CreateFrameNode(V2::MODAL_PAGE_TAG, -1, modalPattern);
202             rootNode->AddChild(oldModelpageNode);
203             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
204             auto oldFocusHub = oldModelpageNode->GetOrCreateFocusHub();
205             if (testCase.isAutoFocusTransfer) {
206                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
207                 CHECK_NULL_VOID(delegate);
208                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
209             }
210             auto newModelpageNode = FrameNodeOnTree::CreateFrameNode(V2::MODAL_PAGE_TAG, -1, modalPattern);
211             oldModelpageNode->AddChild(newModelpageNode);
212             auto newFocusHub = newModelpageNode->GetOrCreateFocusHub();
213             if (testCase.isHasDefaultFocus) {
214                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
215             }
216             auto currentFocusNode = focusManager_->GetFocusManager(newModelpageNode);
217             CHECK_NULL_VOID(currentFocusNode);
218             EXPECT_EQ(oldModelpageNode, currentFocusNode);
219             EXPECT_NE(newModelpageNode, currentFocusNode);
220         } else if (testCase.newPageType == "sheetpag") {
221             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
222             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
223             auto sheetPattern = AceType::MakeRefPtr<SheetPresentationPattern>(-1, "", nullptr);
224             auto oldSheetpageNode = FrameNodeOnTree::CreateFrameNode(V2::SHEET_PAGE_TAG, -1, sheetPattern);
225             rootNode->AddChild(oldSheetpageNode);
226             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
227             auto oldFocusHub = oldSheetpageNode->GetOrCreateFocusHub();
228             if (testCase.isAutoFocusTransfer) {
229                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
230                 CHECK_NULL_VOID(delegate);
231                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
232             }
233             auto newSheetpageNode = FrameNodeOnTree::CreateFrameNode(V2::SHEET_PAGE_TAG, -1, sheetPattern);
234             oldSheetpageNode->AddChild(newSheetpageNode);
235             auto newFocusHub = newSheetpageNode->GetOrCreateFocusHub();
236             if (testCase.isHasDefaultFocus) {
237                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
238             }
239             auto currentFocusNode = focusManager_->GetFocusManager(newSheetpageNode);
240             CHECK_NULL_VOID(currentFocusNode);
241             EXPECT_EQ(oldSheetpageNode, currentFocusNode);
242             EXPECT_NE(newSheetpageNode, currentFocusNode);
243         } else if (testCase.newPageType == "navigation") {
244             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
245             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
246             auto navigationPattern = AceType::MakeRefPtr<NavigationPattern>();
247             auto oldNavigationNode =
248                 FrameNodeOnTree::CreateFrameNode(V2::NAVIGATION_VIEW_ETS_TAG, -1, navigationPattern);
249             rootNode->AddChild(oldNavigationNode);
250             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
251             auto oldFocusHub = oldNavigationNode->GetOrCreateFocusHub();
252             if (testCase.isAutoFocusTransfer) {
253                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
254                 CHECK_NULL_VOID(delegate);
255                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
256             }
257             auto newNavigationNode =
258                 FrameNodeOnTree::CreateFrameNode(V2::NAVIGATION_VIEW_ETS_TAG, -1, navigationPattern);
259             oldNavigationNode->AddChild(newNavigationNode);
260             auto newFocusHub = newNavigationNode->GetOrCreateFocusHub();
261             if (testCase.isHasDefaultFocus) {
262                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
263             }
264             auto currentFocusNode = focusManager_->GetFocusManager(newNavigationNode);
265             CHECK_NULL_VOID(currentFocusNode);
266             EXPECT_EQ(oldNavigationNode, currentFocusNode);
267             EXPECT_NE(newNavigationNode, currentFocusNode);
268 
269         } else if (testCase.newPageType == "navbar") {
270             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
271             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
272             auto navbarPattern = AceType::MakeRefPtr<NavBarPattern>();
273             auto oldNavbarNode = FrameNodeOnTree::CreateFrameNode(V2::NAVBAR_ETS_TAG, -1, navbarPattern);
274             rootNode->AddChild(oldNavbarNode);
275             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
276             auto oldFocusHub = oldNavbarNode->GetOrCreateFocusHub();
277             if (testCase.isAutoFocusTransfer) {
278                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
279                 CHECK_NULL_VOID(delegate);
280                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
281             }
282             auto newNavbarNode = FrameNodeOnTree::CreateFrameNode(V2::NAVBAR_ETS_TAG, -1, navbarPattern);
283             oldNavbarNode->AddChild(newNavbarNode);
284             auto newFocusHub = newNavbarNode->GetOrCreateFocusHub();
285             if (testCase.isHasDefaultFocus) {
286                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
287             }
288             auto currentFocusNode = focusManager_->GetFocusManager(newNavbarNode);
289             CHECK_NULL_VOID(currentFocusNode);
290             EXPECT_EQ(oldNavbarNode, currentFocusNode);
291             EXPECT_NE(newNavbarNode, currentFocusNode);
292         } else if (testCase.newPageType == "navdestination") {
293             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
294             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
295             auto navdestinationPattern = AceType::MakeRefPtr<NavDestinationPattern>(nullptr);
296             auto oldNavdestinationNode =
297                 FrameNodeOnTree::CreateFrameNode(V2::NAVDESTINATION_VIEW_ETS_TAG, -1, navdestinationPattern);
298             rootNode->AddChild(oldNavdestinationNode);
299             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
300             auto oldFocusHub = oldNavdestinationNode->GetOrCreateFocusHub();
301             if (testCase.isAutoFocusTransfer) {
302                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
303                 CHECK_NULL_VOID(delegate);
304                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
305             }
306             auto newNavdestinationNode =
307                 FrameNodeOnTree::CreateFrameNode(V2::NAVDESTINATION_VIEW_ETS_TAG, -1, navdestinationPattern);
308             oldNavdestinationNode->AddChild(newNavdestinationNode);
309             auto newFocusHub = newNavdestinationNode->GetOrCreateFocusHub();
310             if (testCase.isHasDefaultFocus) {
311                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
312             }
313             auto currentFocusNode = focusManager_->GetFocusManager(newNavdestinationNode);
314             CHECK_NULL_VOID(currentFocusNode);
315             EXPECT_EQ(oldNavdestinationNode, currentFocusNode);
316             EXPECT_NE(newNavdestinationNode, currentFocusNode);
317 
318         } else if (testCase.newPageType == "windowscene") {
319             auto rootNode = FrameNodeOnTree::CreateFrameNode(V2::ROOT_ETS_TAG, -1, AceType::MakeRefPtr<RootPattern>());
320             auto rootFocusHub = rootNode->GetOrCreateFocusHub();
321             auto windowscenePattern = AceType::MakeRefPtr<Pattern>();
322             auto oldWindowscene = FrameNodeOnTree::CreateFrameNode(V2::WINDOW_SCENE_ETS_TAG, -1, windowscenePattern);
323             rootNode->AddChild(oldWindowscene);
324             auto focusManager = PipelineContext::GetCurrentContext()->GetFocusManager();
325             auto oldFocusHub = oldWindowscene->GetOrCreateFocusHub();
326             if (testCase.isAutoFocusTransfer) {
327                 auto delegate = EngineHelper::GetCurrentDelegateSafely();
328                 CHECK_NULL_VOID(delegate);
329                 delegate->SetAutoFocusTransfer(testCase.isAutoFocusTransfer);
330             }
331             auto newWindowscene = FrameNodeOnTree::CreateFrameNode(V2::WINDOW_SCENE_ETS_TAG, -1, windowscenePattern);
332             auto newFocusHub = newWindowscene->GetOrCreateFocusHub();
333             oldWindowscene->AddChild(newWindowscene);
334             if (testCase.isHasDefaultFocus) {
335                 oldFocusHub->SetDefaultFocusNode(newFocusHub);
336             }
337             auto currentFocusNode = focusManager_->GetFocusManager(newWindowscene);
338             CHECK_NULL_VOID(currentFocusNode);
339             EXPECT_EQ(oldWindowscene, currentFocusNode);
340             EXPECT_NE(newWindowscene, currentFocusNode);
341         }
342         ++caseNum;
343     }
344 }
345 } // namespace OHOS::Ace::NG
346