• 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 
16 #include "gtest/gtest.h"
17 #include "ui/base/ace_type.h"
18 
19 #include "core/pipeline/base/element_register.h"
20 #define protected public
21 #define private public
22 
23 #include "test/mock/core/pipeline/mock_pipeline_context.h"
24 
25 #include "core/components_ng/base/node_render_status_monitor.h"
26 
27 #undef private
28 #undef protected
29 
30 namespace OHOS::Ace::NG {
31 
32 class NodeRenderStatusMonitorTestNg : public testing::Test {
33 public:
34     static void SetUpTestSuite();
35     static void TearDownTestSuite();
36     void SetUp();
TearDown()37     void TearDown() {};
38 
39 protected:
40     RefPtr<NodeRenderStatusMonitor> monitor_;
41 };
42 
SetUpTestSuite()43 void NodeRenderStatusMonitorTestNg::SetUpTestSuite()
44 {
45     MockPipelineContext::SetUp();
46 }
47 
TearDownTestSuite()48 void NodeRenderStatusMonitorTestNg::TearDownTestSuite()
49 {
50     MockPipelineContext::TearDown();
51 }
52 
SetUp()53 void NodeRenderStatusMonitorTestNg::SetUp()
54 {
55     auto context = PipelineContext::GetCurrentContext();
56     CHECK_NULL_VOID(context);
57     monitor_ = context->GetNodeRenderStatusMonitor();
58 }
59 
60 /**
61  * @tc.name: NodeRenderStatusMonitorTestNg001
62  * @tc.desc: Test RegisterNodeRenderStatusListener UnRegisterNodeRenderStatusListener
63  * @tc.type: FUNC
64  */
65 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg001, testing::ext::TestSize.Level1)
66 {
67     ASSERT_NE(monitor_, nullptr);
68     auto frameNodeOne = FrameNode::CreateFrameNode(
69         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
70     ASSERT_NE(frameNodeOne, nullptr);
__anon47eae03c0102(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 71     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
72     auto frameNodeOnePtr = AceType::RawPtr(frameNodeOne);
73     auto resultOne = monitor_->RegisterNodeRenderStatusListener(frameNodeOnePtr, func, MonitorSourceType::OBSERVER);
74     auto resultOneId = resultOne.id;
75     EXPECT_NE(resultOne.id, MONITOR_INVALID_ID);
76     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
77 
78     resultOne = monitor_->RegisterNodeRenderStatusListener(frameNodeOnePtr, func, MonitorSourceType::OBSERVER);
79     EXPECT_EQ(resultOne.id, MONITOR_INVALID_ID);
80     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
81 
82     resultOne = monitor_->RegisterNodeRenderStatusListener(nullptr, func, MonitorSourceType::OBSERVER);
83     EXPECT_EQ(resultOne.id, MONITOR_INVALID_ID);
84     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
85 
86     auto frameNodeTwo = FrameNode::CreateFrameNode(
87         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
88     ASSERT_NE(frameNodeTwo, nullptr);
89     auto frameNodeTwoPtr = AceType::RawPtr(frameNodeTwo);
90     auto resultTwo = monitor_->RegisterNodeRenderStatusListener(frameNodeTwoPtr, nullptr, MonitorSourceType::OBSERVER);
91     EXPECT_EQ(resultTwo.id, MONITOR_INVALID_ID);
92     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
93 
94     resultTwo = monitor_->RegisterNodeRenderStatusListener(frameNodeTwoPtr, func, MonitorSourceType::OBSERVER);
95     EXPECT_NE(resultTwo.id, MONITOR_INVALID_ID);
96     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 2);
97     monitor_->UnRegisterNodeRenderStatusListener(frameNodeOnePtr, resultOneId);
98     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
99     monitor_->UnRegisterNodeRenderStatusListener(frameNodeOnePtr, resultOneId);
100     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
101     monitor_->UnRegisterNodeRenderStatusListener(frameNodeTwoPtr, resultTwo.id);
102     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
103 }
104 
105 /**
106  * @tc.name: NodeRenderStatusMonitorTestNg002
107  * @tc.desc: Test WalkThroughAncestorForStateListener
108  * @tc.type: FUNC
109  */
110 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg002, testing::ext::TestSize.Level1)
111 {
112     ASSERT_NE(monitor_, nullptr);
113     auto rootNode = FrameNode::CreateFrameNode(
114         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), true);
115     ASSERT_NE(rootNode, nullptr);
116     rootNode->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
117     rootNode->SetActive(true);
118     auto childNodeOne = FrameNode::CreateFrameNode(
119         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
120     ASSERT_NE(childNodeOne, nullptr);
121     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
122     childNodeOne->SetActive(true);
123     childNodeOne->AttachToMainTree(true);
124     childNodeOne->MountToParent(rootNode);
125     rootNode->AttachToMainTree(true);
126     int32_t listenerCount = 0;
127     auto func = [&listenerCount](
__anon47eae03c0202( FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 128                     FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) { listenerCount++; };
129     auto childNodeOnePtr = AceType::RawPtr(childNodeOne);
130     auto result = monitor_->RegisterNodeRenderStatusListener(childNodeOnePtr, func, MonitorSourceType::OBSERVER);
131     EXPECT_EQ(result.state, NodeRenderState::ABOUT_TO_RENDER_IN);
132 
133     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::INVISIBLE);
134     auto state = monitor_->GetNodeCurrentRenderState(childNodeOnePtr);
135     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_OUT);
136     monitor_->WalkThroughAncestorForStateListener();
137     EXPECT_EQ(listenerCount, 1);
138 
139     auto childNodeTwo = FrameNode::CreateFrameNode(
140         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
141     ASSERT_NE(childNodeTwo, nullptr);
142     childNodeTwo->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
143     childNodeTwo->SetActive(true);
144     childNodeTwo->AttachToMainTree(true);
145     childNodeTwo->MountToParent(childNodeOne);
146     auto childNodeTwoPtr = AceType::RawPtr(childNodeTwo);
147     state = monitor_->GetNodeCurrentRenderState(childNodeTwoPtr);
148     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_OUT);
149     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
150     state = monitor_->GetNodeCurrentRenderState(childNodeTwoPtr);
151     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_IN);
152     monitor_->UnRegisterNodeRenderStatusListener(childNodeOnePtr, result.id);
153     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
154 }
155 
156 /**
157  * @tc.name: NodeRenderStatusMonitorTestNg003
158  * @tc.desc: Test GetNodeCurrentRenderState
159  * @tc.type: FUNC
160  */
161 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg003, testing::ext::TestSize.Level1)
162 {
163     ASSERT_NE(monitor_, nullptr);
164     auto rootNode = FrameNode::CreateFrameNode(
165         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), true);
166     ASSERT_NE(rootNode, nullptr);
167     rootNode->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
168     rootNode->SetActive(true);
__anon47eae03c0302(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 169     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
170     auto childNodeOne = FrameNode::CreateFrameNode(
171         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
172     ASSERT_NE(childNodeOne, nullptr);
173     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
174     childNodeOne->SetActive(true);
175     rootNode->AddChild(childNodeOne);
176     auto childNodeOnePtr = AceType::RawPtr(childNodeOne);
177     rootNode->AttachToMainTree(true);
178     auto result = monitor_->RegisterNodeRenderStatusListener(childNodeOnePtr, func, MonitorSourceType::OBSERVER);
179     auto state = monitor_->GetNodeCurrentRenderState(childNodeOnePtr);
180     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_IN);
181 
182     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::INVISIBLE);
183     state = monitor_->GetNodeCurrentRenderState(childNodeOnePtr);
184     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_OUT);
185 
186     childNodeOne->layoutProperty_->UpdateVisibility(OHOS::Ace::VisibleType::VISIBLE);
187     childNodeOne->SetActive(false);
188     state = monitor_->GetNodeCurrentRenderState(childNodeOnePtr);
189     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_OUT);
190 
191     childNodeOne->SetActive(true);
192     childNodeOne->onMainTree_ = false;
193     state = monitor_->GetNodeCurrentRenderState(childNodeOnePtr);
194     EXPECT_EQ(state, NodeRenderState::ABOUT_TO_RENDER_OUT);
195 
196     monitor_->UnRegisterNodeRenderStatusListener(childNodeOnePtr, result.id);
197     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
198 }
199 
200 /**
201  * @tc.name: NodeRenderStatusMonitorTestNg004
202  * @tc.desc: Test NotifyFrameNodeRelease
203  * @tc.type: FUNC
204  */
205 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg004, testing::ext::TestSize.Level1)
206 {
207     ASSERT_NE(monitor_, nullptr);
__anon47eae03c0402(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 208     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
209     auto childNodeOne = FrameNode::CreateFrameNode(
210         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
211     ASSERT_NE(childNodeOne, nullptr);
212     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(childNodeOne), func, MonitorSourceType::OBSERVER);
213     auto childNodeTwo = FrameNode::CreateFrameNode(
214         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
215     ASSERT_NE(childNodeTwo, nullptr);
216     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(childNodeTwo), func, MonitorSourceType::OBSERVER);
217     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 2);
218     childNodeOne.Reset();
219     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
220     childNodeTwo.Reset();
221     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
222 }
223 
224 /**
225  * @tc.name: NodeRenderStatusMonitorTestNg005
226  * @tc.desc: Test IsRegisterNodeRenderStateChangeCallbackExceedLimit
227  * @tc.type: FUNC
228  */
229 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg005, testing::ext::TestSize.Level1)
230 {
231     ASSERT_NE(monitor_, nullptr);
232     std::vector<RefPtr<FrameNode>> frameNodes;
__anon47eae03c0502(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 233     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
234     for (int i = 0; i < 63; i++) {
235         auto child = FrameNode::CreateFrameNode(
236             V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
237         ASSERT_NE(child, nullptr);
238         frameNodes.emplace_back(child);
239         monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
240     }
241     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 63);
242     bool isLimit = monitor_->IsRegisterNodeRenderStateChangeCallbackExceedLimit();
243     EXPECT_EQ(isLimit, false);
244 
245     auto child = FrameNode::CreateFrameNode(
246         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
247     ASSERT_NE(child, nullptr);
248     auto result = monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
249     EXPECT_NE(result.id, MONITOR_INVALID_ID);
250     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 64);
251     isLimit = monitor_->IsRegisterNodeRenderStateChangeCallbackExceedLimit();
252     EXPECT_EQ(isLimit, true);
253 
254     auto childTwo = FrameNode::CreateFrameNode(
255         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
256     ASSERT_NE(childTwo, nullptr);
257     result = monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(childTwo), func, MonitorSourceType::OBSERVER);
258     EXPECT_EQ(result.id, MONITOR_INVALID_ID);
259     isLimit = monitor_->IsRegisterNodeRenderStateChangeCallbackExceedLimit();
260     EXPECT_EQ(isLimit, true);
261 }
262 
263 /**
264  * @tc.name: NodeRenderStatusMonitorTestNg006
265  * @tc.desc: Test RegisterNodeRenderStatusListener
266  * @tc.type: FUNC
267  */
268 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg006, testing::ext::TestSize.Level1)
269 {
270     ASSERT_NE(monitor_, nullptr);
271     std::vector<RefPtr<FrameNode>> frameNodes;
__anon47eae03c0602(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 272     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
273     auto child = FrameNode::CreateFrameNode(
274         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
275     ASSERT_NE(child, nullptr);
276     frameNodes.emplace_back(child);
277     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
278     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
279     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
280     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
281     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, static_cast<MonitorSourceType>(2));
282     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
283 }
284 
285 /**
286  * @tc.name: NodeRenderStatusMonitorTestNg007
287  * @tc.desc: Test UnRegisterNodeRenderStatusListener
288  * @tc.type: FUNC
289  */
290 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg007, testing::ext::TestSize.Level1)
291 {
292     ASSERT_NE(monitor_, nullptr);
293     std::vector<RefPtr<FrameNode>> frameNodes;
__anon47eae03c0702(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 294     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
295     auto child = FrameNode::CreateFrameNode(
296         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
297     ASSERT_NE(child, nullptr);
298     frameNodes.emplace_back(child);
299     monitor_->UnRegisterNodeRenderStatusListener(AceType::RawPtr(child), 0);
300     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
301     MonitorRegisterResult testResult =
302         monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
303     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
304     monitor_->UnRegisterNodeRenderStatusListener(AceType::RawPtr(child), testResult.id);
305     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
306 }
307 
308 /**
309  * @tc.name: NodeRenderStatusMonitorTestNg008
310  * @tc.desc: Test NotifyFrameNodeRelease
311  * @tc.type: FUNC
312  */
313 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg008, testing::ext::TestSize.Level1)
314 {
315     ASSERT_NE(monitor_, nullptr);
316     std::vector<RefPtr<FrameNode>> frameNodes;
__anon47eae03c0802(FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) 317     auto func = [](FrameNode* frameNode, NodeRenderState state, RenderMonitorReason reason) {};
318     auto child = FrameNode::CreateFrameNode(
319         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
320     ASSERT_NE(child, nullptr);
321     frameNodes.emplace_back(child);
322     monitor_->NotifyFrameNodeRelease(AceType::RawPtr(child));
323     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
324     monitor_->RegisterNodeRenderStatusListener(AceType::RawPtr(child), func, MonitorSourceType::OBSERVER);
325     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 1);
326     monitor_->NotifyFrameNodeRelease(AceType::RawPtr(child));
327     EXPECT_EQ(monitor_->nodeRenderStatusListeners_.size(), 0);
328 }
329 
330 /**
331  * @tc.name: NodeRenderStatusMonitorTestNg009
332  * @tc.desc: Test IsNodeRenderOut
333  * @tc.type: FUNC
334  */
335 HWTEST_F(NodeRenderStatusMonitorTestNg, NodeRenderStatusMonitorTestNg009, testing::ext::TestSize.Level1)
336 {
337     ASSERT_NE(monitor_, nullptr);
338     std::vector<RefPtr<FrameNode>> frameNodes;
339     auto child = FrameNode::CreateFrameNode(
340         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>(), false);
341     ASSERT_NE(child, nullptr);
342     frameNodes.emplace_back(child);
343     child->layoutProperty_->propVisibility_ = VisibleType::VISIBLE;
344     child->isActive_ = true;
345     child->onMainTree_ = true;
346     EXPECT_FALSE(monitor_->IsNodeRenderOut(AceType::RawPtr(child)));
347     child->onMainTree_ = false;
348     EXPECT_TRUE(monitor_->IsNodeRenderOut(AceType::RawPtr(child)));
349     child->isActive_ = false;
350     EXPECT_TRUE(monitor_->IsNodeRenderOut(AceType::RawPtr(child)));
351     child->layoutProperty_->propVisibility_ = VisibleType::INVISIBLE;
352     EXPECT_TRUE(monitor_->IsNodeRenderOut(AceType::RawPtr(child)));
353 }
354 
355 /**
356  * @tc.name: CheckSourceTypeChangeTest
357  * @tc.desc: Test Check input source switching
358  * @tc.type: FUNC
359  */
360 HWTEST_F(NodeRenderStatusMonitorTestNg, CheckSourceTypeChangeTest, testing::ext::TestSize.Level1)
361 {
362     auto context = PipelineContext::GetCurrentContext();
363     CHECK_NULL_VOID(context);
364     context->lastSourceType_ = SourceType::MOUSE;
365     EXPECT_FALSE(context->CheckSourceTypeChange(SourceType::MOUSE));
366 
367     EXPECT_TRUE(context->CheckSourceTypeChange(SourceType::TOUCH));
368 
369     EXPECT_TRUE(context->CheckSourceTypeChange(SourceType::MOUSE));
370     context->lastSourceType_ = SourceType::NONE;
371 }
372 } // namespace OHOS::Ace::NG