• 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 <cstdint>
16 #include "gtest/hwext/gtest-tag.h"
17 #include "test/unittest/core/event/focus_hub_test_ng.h"
18 
19 using namespace testing;
20 using namespace testing::ext;
21 
22 namespace OHOS::Ace::NG {
23 struct HomeOrEndKeyInFocusGroupTestCase {
24     int32_t curFocusHub;
25     bool focusGroup1;
26     bool focusGroup2;
27     FocusIntension intension;
28     int32_t expect;
29 };
30 
31 const vector<HomeOrEndKeyInFocusGroupTestCase> HomeOrEndKeyInFocusGroupTestCase001 {
32     { 1, false, false, FocusIntension::HOME, 11 },
33     { 1, true, false, FocusIntension::HOME, 11 },
34     { 1, false, true, FocusIntension::HOME, 14 },
35     { 1, true, true, FocusIntension::HOME, 14 },
36     { 1, false, false, FocusIntension::END, 11 },
37     { 1, true, false, FocusIntension::END, 13 },
38     { 1, false, true, FocusIntension::END, 15 },
39     { 1, true, true, FocusIntension::END, 15 },
40     { 3, false, false, FocusIntension::HOME, 13 },
41     { 3, true, false, FocusIntension::HOME, 11 },
42     { 3, false, true, FocusIntension::HOME, 14 },
43     { 3, true, true, FocusIntension::HOME, 14 },
44     { 3, false, false, FocusIntension::END, 13 },
45     { 3, true, false, FocusIntension::END, 13 },
46     { 3, false, true, FocusIntension::END, 15 },
47     { 3, true, true, FocusIntension::END, 15 },
48 };
49 
50 struct ButtonNodes {
51     RefPtr<FrameNode> button1;
52     RefPtr<FrameNode> button2;
53     RefPtr<FrameNode> button3;
54 };
55 
CreateTestTreeWithDefaultFocus()56 ButtonNodes CreateTestTreeWithDefaultFocus()
57 {
58     /*--page
59         --column1
60             --column2
61             --button4
62              --column3
63                 --button1
64                 --button2
65                 --button3
66             --button5
67     */
68     auto context = MockPipelineContext::GetCurrent();
69     auto focusManager = context->GetOrCreateFocusManager();
70     auto pagePattern = AceType::MakeRefPtr<PagePattern>(AceType::MakeRefPtr<PageInfo>());
71     auto pageNode = FrameNode::CreateFrameNode(V2::PAGE_ETS_TAG, 1, pagePattern);
72     pageNode->onMainTree_ = true;
73     auto pageFocusHub = pageNode->GetOrCreateFocusHub();
74     context->rootNode_->AddChild(pageNode);
75     auto column1 = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, 2, AceType::MakeRefPtr<LinearLayoutPattern>(true));
76     auto column2 = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, 2, AceType::MakeRefPtr<LinearLayoutPattern>(true));
77     auto column3 = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, 2, AceType::MakeRefPtr<LinearLayoutPattern>(true));
78     column1->onMainTree_ = true;
79     column2->onMainTree_ = true;
80     column3->onMainTree_ = true;
81     auto columnFocusHub1 = column1->GetOrCreateFocusHub();
82     auto columnFocusHub2 = column2->GetOrCreateFocusHub();
83     auto columnFocusHub3 = column3->GetOrCreateFocusHub();
84     auto buttonNode1 = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, 11, AceType::MakeRefPtr<ButtonPattern>());
85     auto buttonNode2 = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, 12, AceType::MakeRefPtr<ButtonPattern>());
86     auto buttonNode3 = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, 13, AceType::MakeRefPtr<ButtonPattern>());
87     auto buttonNode4 = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, 14, AceType::MakeRefPtr<ButtonPattern>());
88     auto buttonNode5 = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, 15, AceType::MakeRefPtr<ButtonPattern>());
89     buttonNode1->onMainTree_ = true;
90     buttonNode2->onMainTree_ = true;
91     buttonNode3->onMainTree_ = true;
92     buttonNode5->onMainTree_ = true;
93     buttonNode4->onMainTree_ = true;
94     pageNode->AddChild(column1);
95     column1->AddChild(column2);
96     column2->AddChild(buttonNode4);
97     column2->AddChild(column3);
98     column3->AddChild(buttonNode1);
99     column3->AddChild(buttonNode2);
100     column3->AddChild(buttonNode3);
101     column2->AddChild(buttonNode5);
102     pagePattern->FocusViewShow();
103     context->FlushFocusView();
104     return { buttonNode1, buttonNode2, buttonNode3 };
105 }
106 
107 /**
108  * @tc.name: IsLeafFocusScope001
109  * @tc.desc:
110  * @tc.type: FUNC
111  */
112 HWTEST_F(FocusHubTestNg, IsLeafFocusScope001, TestSize.Level1)
113 {
114     auto frameNode = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
115     RefPtr<EventHub> eventHub = AceType::MakeRefPtr<EventHub>();
116     eventHub->AttachHost(frameNode);
117     auto focusHub = AceType::MakeRefPtr<FocusHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
118 
119     focusHub->tabStop_ = true;
120     focusHub->isSwitchByEnter_ = true;
121     focusHub->focusDepend_ = FocusDependence::SELF;
122     auto ret = focusHub->IsLeafFocusScope();
123     EXPECT_EQ(ret, false);
124 
125     focusHub->tabStop_ = true;
126     focusHub->isSwitchByEnter_ = false;
127     ret = focusHub->IsLeafFocusScope();
128     EXPECT_EQ(ret, true);
129 }
130 
131 /**
132  * @tc.name: PaintAllFocusState001
133  * @tc.desc:
134  * @tc.type: FUNC
135  */
136 HWTEST_F(FocusHubTestNg, PaintAllFocusState001, TestSize.Level1)
137 {
138     auto frameNode = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1,
139         AceType::MakeRefPtr<Pattern>());
140     auto frameNode1 = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1,
141         AceType::MakeRefPtr<Pattern>());
142     auto eventHub = AceType::MakeRefPtr<EventHub>();
143     auto eventHub1 = AceType::MakeRefPtr<EventHub>();
144     eventHub->AttachHost(frameNode);
145     eventHub1->AttachHost(frameNode1);
146     auto focusHub = frameNode->GetOrCreateFocusHub();
147     auto focusHub1 = frameNode1->GetOrCreateFocusHub();
148     OnPaintFocusStateFunc onPaintFocusCallback;
__anone5b8ad720102() 149     std::function<bool()> lambdaFunction = []() {
150         return false;
151     };
152     focusHub->onPaintFocusStateCallback_ = lambdaFunction;
153     focusHub->isFocusActiveWhenFocused_ = true;
154     EXPECT_FALSE(focusHub->PaintAllFocusState());
155 
156     focusHub1->focusStyleType_ = FocusStyleType::INNER_BORDER;
157     focusHub1->isFocusActiveWhenFocused_ = true;
158     EXPECT_FALSE(focusHub1->PaintAllFocusState());
159 }
160 
161 /**
162  * @tc.name: PaintAllFocusState074
163  * @tc.desc:
164  * @tc.type: FUNC
165  */
166 HWTEST_F(FocusHubTestNg, PaintAllFocusState002, TestSize.Level1)
167 {
168     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
169     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
170     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<AppTheme>()));
171     auto frameNode = FrameNodeOnTree::CreateFrameNode("frameNode", 101,
172         AceType::MakeRefPtr<ButtonPattern>());
173     frameNode->GetOrCreateFocusHub();
174     auto focusHub = frameNode->GetFocusHub();
175     ASSERT_NE(focusHub, nullptr);
176     auto context = PipelineContext::GetCurrentContext();
177     ASSERT_NE(context, nullptr);
178     auto focusManager = context->GetOrCreateFocusManager();
179     ASSERT_NE(focusManager, nullptr);
180     focusManager->isFocusActive_ = true;
181 
182     focusHub->focusStyleType_ = FocusStyleType::OUTER_BORDER;
183     OnPaintFocusStateFunc onPaintFocusCallback;
184     focusHub->onPaintFocusStateCallback_ = onPaintFocusCallback;
185     FocusBoxStyle focusBoxStyle;
186     CalcDimension strokeWidth(100);
187     CalcDimension margin(100);
188     Color color;
189 
190     focusBoxStyle.strokeColor = color;
191     focusBoxStyle.strokeWidth = strokeWidth;
192     focusBoxStyle.margin = margin;
193     focusHub->box_.SetStyle(focusBoxStyle);
194     auto ret = focusHub->PaintAllFocusState();
195     EXPECT_TRUE(ret);
196 
197     FocusBoxStyle focusBoxStyle1;
198     focusBoxStyle1.strokeColor = color;
199     focusBoxStyle1.margin = margin;
200     focusHub->box_.SetStyle(focusBoxStyle1);
201     ret = focusHub->PaintAllFocusState();
202     EXPECT_TRUE(ret);
203 }
204 
205 /**
206  * @tc.name: PaintAllFocusState003
207  * @tc.desc:
208  * @tc.type: FUNC
209  */
210 HWTEST_F(FocusHubTestNg, PaintAllFocusState003, TestSize.Level1)
211 {
212     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
213     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
214     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<AppTheme>()));
215     auto frameNode = FrameNodeOnTree::CreateFrameNode("frameNode", 101,
216         AceType::MakeRefPtr<ButtonPattern>());
217     frameNode->GetOrCreateFocusHub();
218     auto focusHub = frameNode->GetFocusHub();
219     ASSERT_NE(focusHub, nullptr);
220     auto context = PipelineContext::GetCurrentContext();
221     ASSERT_NE(context, nullptr);
222     auto focusManager = context->GetOrCreateFocusManager();
223     ASSERT_NE(focusManager, nullptr);
224     focusManager->isFocusActive_ = true;
225 
226     focusHub->focusStyleType_ = FocusStyleType::OUTER_BORDER;
227     OnPaintFocusStateFunc onPaintFocusCallback;
228     focusHub->onPaintFocusStateCallback_ = onPaintFocusCallback;
229     FocusBoxStyle focusBoxStyle;
230     CalcDimension strokeWidth(100);
231     CalcDimension margin(100);
232     Color color;
233 
234     FocusBoxStyle focusBoxStyle2;
235     focusBoxStyle2.strokeColor = color;
236     focusBoxStyle2.strokeWidth = strokeWidth;
237     focusHub->box_.SetStyle(focusBoxStyle2);
238     auto ret = focusHub->PaintAllFocusState();
239     EXPECT_TRUE(ret);
240 
__anone5b8ad720202() 241     std::function<bool()> lambdaFunction = []() {
242         return false;
243     };
244     focusHub->onPaintFocusStateCallback_ = lambdaFunction;
245     FocusBoxStyle focusBoxStyle3;
246     focusBoxStyle3.margin = margin;
247     focusBoxStyle3.strokeWidth = strokeWidth;
248     focusHub->box_.SetStyle(focusBoxStyle3);
249     ret = focusHub->PaintAllFocusState();
250     EXPECT_FALSE(ret);
251 }
252 
253 /**
254  * @tc.name: PaintInnerFocusState0048
255  * @tc.desc:
256  * @tc.type: FUNC
257  */
258 HWTEST_F(FocusHubTestNg, PaintInnerFocusState001, TestSize.Level1)
259 {
260     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
261     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
262     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<AppTheme>()));
263     auto frameNode = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1,
264         AceType::MakeRefPtr<Pattern>());
265     auto child = AceType::MakeRefPtr<FrameNodeOnTree>(V2::BUTTON_ETS_TAG, -1,
266         AceType::MakeRefPtr<ButtonPattern>());
267     auto child2 = AceType::MakeRefPtr<FrameNodeOnTree>(V2::BUTTON_ETS_TAG, -1,
268         AceType::MakeRefPtr<ButtonPattern>());
269     child->GetOrCreateFocusHub();
270     child2->GetOrCreateFocusHub();
271     frameNode->AddChild(child);
272     frameNode->AddChild(child2);
273     RefPtr<EventHub> eventHub = AceType::MakeRefPtr<EventHub>();
274     eventHub->AttachHost(frameNode);
275     auto focusHub = AceType::MakeRefPtr<FocusHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
276     auto context = PipelineContext::GetCurrentContext();
277     ASSERT_NE(context, nullptr);
278     FocusBoxStyle focusBoxStyle;
279     CalcDimension strokeWidth(100);
280     CalcDimension margin(100);
281     Color color;
282     focusBoxStyle.strokeColor = color;
283     focusBoxStyle.strokeWidth = strokeWidth;
284     focusBoxStyle.margin = margin;
285     focusHub->box_.SetStyle(focusBoxStyle);
286     RoundRect focusRectInner;
287     auto focusManager = context->GetOrCreateFocusManager();
288     ASSERT_NE(focusManager, nullptr);
289     focusManager->isFocusActive_ = true;
290     focusHub->focusType_ = FocusType::NODE;
291     EXPECT_TRUE(focusHub->PaintInnerFocusState(focusRectInner));
292 
293     FocusBoxStyle focusBoxStyle1;
294     focusBoxStyle1.strokeColor = color;
295     focusBoxStyle1.margin = margin;
296     focusHub->box_.SetStyle(focusBoxStyle1);
297     EXPECT_TRUE(focusHub->PaintInnerFocusState(focusRectInner));
298 
299     FocusBoxStyle focusBoxStyle2;
300     focusBoxStyle2.strokeColor = color;
301     focusBoxStyle2.strokeWidth = strokeWidth;
302     focusHub->box_.SetStyle(focusBoxStyle2);
303     EXPECT_TRUE(focusHub->PaintInnerFocusState(focusRectInner));
304 }
305 
306 /**
307  * @tc.name: PaintInnerFocusState0048
308  * @tc.desc:
309  * @tc.type: FUNC
310  */
311 HWTEST_F(FocusHubTestNg, PaintInnerFocusState002, TestSize.Level1)
312 {
313     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
314     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
315     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<AppTheme>()));
316     auto frameNode = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1,
317         AceType::MakeRefPtr<Pattern>());
318     auto child = AceType::MakeRefPtr<FrameNodeOnTree>(V2::BUTTON_ETS_TAG, -1,
319         AceType::MakeRefPtr<ButtonPattern>());
320     auto child2 = AceType::MakeRefPtr<FrameNodeOnTree>(V2::BUTTON_ETS_TAG, -1,
321         AceType::MakeRefPtr<ButtonPattern>());
322     child->GetOrCreateFocusHub();
323     child2->GetOrCreateFocusHub();
324     frameNode->AddChild(child);
325     frameNode->AddChild(child2);
326     RefPtr<EventHub> eventHub = AceType::MakeRefPtr<EventHub>();
327     eventHub->AttachHost(frameNode);
328     auto focusHub = AceType::MakeRefPtr<FocusHub>(AceType::WeakClaim(AceType::RawPtr(eventHub)));
329     auto context = PipelineContext::GetCurrentContext();
330     ASSERT_NE(context, nullptr);
331     FocusBoxStyle focusBoxStyle;
332     CalcDimension strokeWidth(100);
333     CalcDimension strokeWidth1("100");
334     CalcDimension margin(100);
335     Color color;
336     RoundRect focusRectInner;
337     auto focusManager = context->GetOrCreateFocusManager();
338     ASSERT_NE(focusManager, nullptr);
339     focusManager->isFocusActive_ = true;
340     focusHub->focusType_ = FocusType::NODE;
341 
342     FocusBoxStyle focusBoxStyle3;
343     focusBoxStyle3.margin = margin;
344     focusBoxStyle3.strokeWidth = strokeWidth;
345     focusHub->box_.SetStyle(focusBoxStyle3);
346     EXPECT_TRUE(focusHub->PaintInnerFocusState(focusRectInner));
347 
348     focusBoxStyle.strokeColor = color;
349     focusBoxStyle.strokeWidth = strokeWidth1;
350     focusBoxStyle.margin = margin;
351     focusHub->box_.SetStyle(focusBoxStyle);
352     EXPECT_TRUE(focusHub->PaintInnerFocusState(focusRectInner));
353 }
354 
355 /**
356  * @tc.name: ChangeFocusByHomeorEndTest001
357  * @tc.desc:
358  * @tc.type: FUNC
359  */
360 HWTEST_F(FocusHubTestNg, ChangeFocusByHomeorEndTest001, TestSize.Level1)
361 {
362     ButtonNodes buttonNodes = CreateTestTreeWithDefaultFocus();
363     RefPtr<FrameNode> button1 = buttonNodes.button1;
364     RefPtr<FrameNode> button3 = buttonNodes.button3;
365     EXPECT_NE(button1, nullptr);
366     EXPECT_NE(button3, nullptr);
367     NonPointerEvent nonPointerEvent;
368     FocusEvent event { nonPointerEvent };
369     auto buttonFocusHub1 = button1->GetOrCreateFocusHub();
370     auto buttonFocusHub3 = button3->GetOrCreateFocusHub();
371     auto parent = buttonFocusHub1->GetParentFocusHub();
372     auto parent2 = parent->GetParentFocusHub();
373     auto parent3 = parent2->GetParentFocusHub();
374     auto page = parent3->GetParentFocusHub();
375     auto context = MockPipelineContext::GetCurrent();
376     auto focusManager = context->GetOrCreateFocusManager();
377     focusManager->isFocusActive_ = true;
378     for (auto& testcase : HomeOrEndKeyInFocusGroupTestCase001) {
379         if (testcase.focusGroup1) {
380             parent->SetFocusScopeId("2", true, true);
381         }
382         if (testcase.focusGroup2) {
383             parent2->SetFocusScopeId("3", true, true);
384         }
385         buttonFocusHub1->RequestFocusImmediately();
386         EXPECT_EQ(buttonFocusHub1->IsCurrentFocus(), true);
387         context->eventManager_->isTabJustTriggerOnKeyEvent_ = false;
388         event.intension = testcase.intension;
389         if (testcase.curFocusHub == 3) {
390             buttonFocusHub3->RequestFocusImmediately();
391             EXPECT_EQ(buttonFocusHub3->IsCurrentFocus(), true);
392         }
393         page->OnFocusEventScope(event);
394         auto currentFocusNode = focusManager->switchingFocus_;
395         auto nodeId = currentFocusNode->GetFrameId();
396         EXPECT_EQ(nodeId, testcase.expect);
397         parent->SetFocusScopeId("", true, true);
398         parent2->SetFocusScopeId("", true, true);
399     }
400 }
401 } // namespace OHOS::Ace::NG