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 <optional>
17
18 #include "gtest/gtest.h"
19
20 #define private public
21 #define protected public
22
23 #include "base/utils/system_properties.h"
24 #include "test/mock/base/mock_system_properties.h"
25 #include "test/mock/core/pipeline/mock_pipeline_context.h"
26 #include "test/mock/core/common/mock_container.h"
27 #include "test/mock/core/common/mock_theme_manager.h"
28
29 using namespace testing;
30 using namespace testing::ext;
31
32 namespace OHOS::Ace::NG {
33 namespace {
34 constexpr Dimension TEST_WIDTH = 605.0_vp;
35
GetForceSplitManager()36 RefPtr<ForceSplitManager> GetForceSplitManager()
37 {
38 auto pipeline = MockPipelineContext::GetCurrent();
39 return pipeline ? pipeline->GetForceSplitManager() : nullptr;
40 }
41 } // namespace
42
43 class ForceSplitManagerTestNg : public testing::Test {
44 public:
45 static void SetUpTestSuite();
46 static void TearDownTestSuite();
47 };
48
SetUpTestSuite()49 void ForceSplitManagerTestNg::SetUpTestSuite()
50 {
51 MockPipelineContext::SetUp();
52 MockContainer::SetUp();
53 auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
54 MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
55 }
56
TearDownTestSuite()57 void ForceSplitManagerTestNg::TearDownTestSuite()
58 {
59 MockPipelineContext::TearDown();
60 MockContainer::TearDown();
61 }
62
63 /**
64 * @tc.name: UpdateIsInForceSplitMode001
65 * @tc.desc: Branch: if (!isForceSplitSupported_) { => true
66 * @tc.type: FUNC
67 * @tc.author:
68 */
69 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitMode001, TestSize.Level1)
70 {
71 auto context = MockPipelineContext::GetCurrent();
72 ASSERT_NE(context, nullptr);
73 auto manager = GetForceSplitManager();
74 ASSERT_NE(manager, nullptr);
75
76 context->SetIsCurrentInForceSplitMode(false);
77 manager->isForceSplitSupported_ = false;
78 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
79 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
80 }
81
82 /**
83 * @tc.name: UpdateIsInForceSplitMode002
84 * @tc.desc: Branch: if (!isForceSplitSupported_) { => false
85 * if (isForceSplitEnable_) { => true
86 * @tc.type: FUNC
87 * @tc.author:
88 */
89 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitMode002, TestSize.Level1)
90 {
91 auto context = MockPipelineContext::GetCurrent();
92 ASSERT_NE(context, nullptr);
93 auto manager = GetForceSplitManager();
94 ASSERT_NE(manager, nullptr);
95 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
96 ASSERT_NE(container, nullptr);
97 auto windowManager = context->GetWindowManager();
98 ASSERT_NE(windowManager, nullptr);
99
100 EXPECT_CALL(*container, IsMainWindow).Times(::testing::AtLeast(1)).WillRepeatedly(Return(true));
101 SystemProperties::orientation_ = DeviceOrientation::LANDSCAPE;
102 auto backupCallback = std::move(windowManager->windowGetModeCallback_);
__anon6ec4ffc10202() 103 windowManager->windowGetModeCallback_ = []() { return WindowMode::WINDOW_MODE_UNDEFINED; };
104 context->SetIsCurrentInForceSplitMode(false);
105 manager->isForceSplitSupported_ = true;
106 manager->isForceSplitEnable_ = true;
107 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
108 EXPECT_TRUE(context->IsCurrentInForceSplitMode());
109 windowManager->windowGetModeCallback_ = std::move(backupCallback);
110 }
111
112 /**
113 * @tc.name: UpdateIsInForceSplitMode003
114 * @tc.desc: Branch: if (!isForceSplitSupported_) { => false
115 * if (isForceSplitEnable_) { => false
116 * @tc.type: FUNC
117 * @tc.author:
118 */
119 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitMode003, TestSize.Level1)
120 {
121 auto context = MockPipelineContext::GetCurrent();
122 ASSERT_NE(context, nullptr);
123 auto manager = GetForceSplitManager();
124 ASSERT_NE(manager, nullptr);
125
126 context->SetIsCurrentInForceSplitMode(false);
127 manager->isForceSplitSupported_ = true;
128 manager->isForceSplitEnable_ = false;
129 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
130 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
131 }
132
133 /**
134 * @tc.name: GetIgnoreOrientation001
135 * @tc.desc: Branch: if (SystemProperties::GetForceSplitIgnoreOrientationEnabled()) { => true
136 * @tc.type: FUNC
137 * @tc.author:
138 */
139 HWTEST_F(ForceSplitManagerTestNg, GetIgnoreOrientation001, TestSize.Level1)
140 {
141 auto context = MockPipelineContext::GetCurrent();
142 ASSERT_NE(context, nullptr);
143 auto manager = GetForceSplitManager();
144 ASSERT_NE(manager, nullptr);
145
146 auto backupProperty = SystemProperties::forceSplitIgnoreOrientationEnabled_;
147 SystemProperties::forceSplitIgnoreOrientationEnabled_ = true;
148 auto ignore = manager->GetIgnoreOrientation();
149 EXPECT_TRUE(ignore);
150 SystemProperties::forceSplitIgnoreOrientationEnabled_ = backupProperty;
151 }
152
153 /**
154 * @tc.name: GetIgnoreOrientation002
155 * @tc.desc: Branch: if (SystemProperties::GetForceSplitIgnoreOrientationEnabled()) { => false
156 * @tc.type: FUNC
157 * @tc.author:
158 */
159 HWTEST_F(ForceSplitManagerTestNg, GetIgnoreOrientation002, TestSize.Level1)
160 {
161 auto context = MockPipelineContext::GetCurrent();
162 ASSERT_NE(context, nullptr);
163 auto manager = GetForceSplitManager();
164 ASSERT_NE(manager, nullptr);
165
166 auto backupProperty = SystemProperties::forceSplitIgnoreOrientationEnabled_;
167 SystemProperties::forceSplitIgnoreOrientationEnabled_ = false;
168 manager->ignoreOrientation_ = false;
169 auto ignore = manager->GetIgnoreOrientation();
170 EXPECT_FALSE(ignore);
171
172 manager->ignoreOrientation_ = true;
173 ignore = manager->GetIgnoreOrientation();
174 EXPECT_TRUE(ignore);
175
176 SystemProperties::forceSplitIgnoreOrientationEnabled_ = backupProperty;
177 }
178
179 /**
180 * @tc.name: SetForceSplitEnable001
181 * @tc.desc: Test SetForceSplitEnable with various parameter combinations
182 * @tc.type: FUNC
183 * @tc.author:
184 */
185 HWTEST_F(ForceSplitManagerTestNg, SetForceSplitEnable001, TestSize.Level1)
186 {
187 auto context = MockPipelineContext::GetCurrent();
188 ASSERT_NE(context, nullptr);
189 auto manager = GetForceSplitManager();
190 ASSERT_NE(manager, nullptr);
191
192 // Test enabling force split without ignoring orientation
193 manager->SetForceSplitEnable(true, false);
194 EXPECT_TRUE(manager->IsForceSplitSupported());
195 EXPECT_TRUE(manager->IsForceSplitEnable());
196 EXPECT_FALSE(manager->GetIgnoreOrientation());
197
198 // Test enabling force split with ignoring orientation
199 manager->SetForceSplitEnable(true, true);
200 EXPECT_TRUE(manager->IsForceSplitSupported());
201 EXPECT_TRUE(manager->IsForceSplitEnable());
202 EXPECT_TRUE(manager->GetIgnoreOrientation());
203
204 // Test disabling force split without ignoring orientation
205 manager->SetForceSplitEnable(false, false);
206 EXPECT_TRUE(manager->IsForceSplitSupported());
207 EXPECT_FALSE(manager->IsForceSplitEnable());
208 EXPECT_FALSE(manager->GetIgnoreOrientation());
209
210 // Test disabling force split with ignoring orientation
211 manager->SetForceSplitEnable(false, true);
212 EXPECT_TRUE(manager->IsForceSplitSupported());
213 EXPECT_FALSE(manager->IsForceSplitEnable());
214 EXPECT_TRUE(manager->GetIgnoreOrientation());
215 }
216
217 /**
218 * @tc.name: UpdateIsInForceSplitModeWithMainWindow001
219 * @tc.desc: Test force split mode when not in main window
220 * @tc.type: FUNC
221 * @tc.author:
222 */
223 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitModeWithMainWindow001, TestSize.Level1)
224 {
225 auto context = MockPipelineContext::GetCurrent();
226 ASSERT_NE(context, nullptr);
227 auto manager = GetForceSplitManager();
228 ASSERT_NE(manager, nullptr);
229 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
230 ASSERT_NE(container, nullptr);
231 auto windowManager = context->GetWindowManager();
232 ASSERT_NE(windowManager, nullptr);
233
234 // Setup: not main window, should not enable force split
235 EXPECT_CALL(*container, IsMainWindow).Times(
236 ::testing::AtLeast(1)).WillRepeatedly(Return(false));
237 SystemProperties::orientation_ = DeviceOrientation::LANDSCAPE;
__anon6ec4ffc10302() 238 windowManager->windowGetModeCallback_ = []() { return WindowMode::WINDOW_MODE_UNDEFINED; };
239
240 context->SetIsCurrentInForceSplitMode(false);
241 manager->isForceSplitSupported_ = true;
242 manager->isForceSplitEnable_ = true;
243 manager->ignoreOrientation_ = false;
244 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
245
246 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
247 }
248
249 /**
250 * @tc.name: UpdateIsInForceSplitModeWithOrientation001
251 * @tc.desc: Test force split mode with portrait orientation
252 * @tc.type: FUNC
253 * @tc.author:
254 */
255 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitModeWithOrientation001, TestSize.Level1)
256 {
257 auto context = MockPipelineContext::GetCurrent();
258 ASSERT_NE(context, nullptr);
259 auto manager = GetForceSplitManager();
260 ASSERT_NE(manager, nullptr);
261 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
262 ASSERT_NE(container, nullptr);
263 auto windowManager = context->GetWindowManager();
264 ASSERT_NE(windowManager, nullptr);
265
266 // Setup: portrait orientation, should not enable force split
267 EXPECT_CALL(*container, IsMainWindow).Times(
268 ::testing::AtLeast(1)).WillRepeatedly(Return(true));
269 SystemProperties::orientation_ = DeviceOrientation::PORTRAIT;
__anon6ec4ffc10402() 270 windowManager->windowGetModeCallback_ = []() {
271 return WindowMode::WINDOW_MODE_UNDEFINED; };
272
273 context->SetIsCurrentInForceSplitMode(false);
274 manager->isForceSplitSupported_ = true;
275 manager->isForceSplitEnable_ = true;
276 manager->ignoreOrientation_ = false;
277 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
278
279 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
280 }
281
282 /**
283 * @tc.name: UpdateIsInForceSplitModeWithOrientationIgnored001
284 * @tc.desc: Test force split mode with portrait orientation but ignoring orientation
285 * @tc.type: FUNC
286 * @tc.author:
287 */
288 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitModeWithOrientationIgnored001, TestSize.Level1)
289 {
290 auto context = MockPipelineContext::GetCurrent();
291 ASSERT_NE(context, nullptr);
292 auto manager = GetForceSplitManager();
293 ASSERT_NE(manager, nullptr);
294 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
295 ASSERT_NE(container, nullptr);
296 auto windowManager = context->GetWindowManager();
297 ASSERT_NE(windowManager, nullptr);
298
299 // Setup: portrait orientation but ignoring orientation, should enable force split
300 EXPECT_CALL(*container, IsMainWindow).Times(
301 ::testing::AtLeast(1)).WillRepeatedly(Return(true));
302 SystemProperties::orientation_ = DeviceOrientation::PORTRAIT;
__anon6ec4ffc10502() 303 windowManager->windowGetModeCallback_ = []() { return WindowMode::WINDOW_MODE_UNDEFINED; };
304 context->SetIsCurrentInForceSplitMode(false);
305 manager->isForceSplitSupported_ = true;
306 manager->isForceSplitEnable_ = true;
307 manager->ignoreOrientation_ = true;
308 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
309 EXPECT_TRUE(context->IsCurrentInForceSplitMode());
310 }
311
312 /**
313 * @tc.name: UpdateIsInForceSplitModeWithUndefinedOrientation001
314 * @tc.desc: Test force split mode with undefined orientation
315 * @tc.type: FUNC
316 * @tc.author:
317 */
318 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitModeWithUndefinedOrientation001, TestSize.Level1)
319 {
320 auto context = MockPipelineContext::GetCurrent();
321 ASSERT_NE(context, nullptr);
322 auto manager = GetForceSplitManager();
323 ASSERT_NE(manager, nullptr);
324 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
325 ASSERT_NE(container, nullptr);
326 auto windowManager = context->GetWindowManager();
327 ASSERT_NE(windowManager, nullptr);
328
329 // Setup: undefined orientation, should not enable force split
330 EXPECT_CALL(*container, IsMainWindow).Times(
331 ::testing::AtLeast(1)).WillRepeatedly(Return(true));
332 SystemProperties::orientation_ = DeviceOrientation::ORIENTATION_UNDEFINED;
__anon6ec4ffc10602() 333 windowManager->windowGetModeCallback_ = []() { return WindowMode::WINDOW_MODE_UNDEFINED; };
334 context->SetIsCurrentInForceSplitMode(false);
335 manager->isForceSplitSupported_ = true;
336 manager->isForceSplitEnable_ = true;
337 manager->ignoreOrientation_ = false;
338 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(TEST_WIDTH.ConvertToPx()));
339 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
340 }
341
342 /**
343 * @tc.name: UpdateIsInForceSplitModeWithWidthThreshold001
344 * @tc.desc: Test force split mode with width below threshold
345 * @tc.type: FUNC
346 * @tc.author:
347 */
348 HWTEST_F(ForceSplitManagerTestNg, UpdateIsInForceSplitModeWithWidthThreshold001, TestSize.Level1)
349 {
350 auto context = MockPipelineContext::GetCurrent();
351 ASSERT_NE(context, nullptr);
352 auto manager = GetForceSplitManager();
353 ASSERT_NE(manager, nullptr);
354 auto container = AceType::DynamicCast<MockContainer>(Container::Current());
355 ASSERT_NE(container, nullptr);
356 auto windowManager = context->GetWindowManager();
357 ASSERT_NE(windowManager, nullptr);
358
359 // Setup: width below 600vp threshold, should not enable force split
360 constexpr Dimension SMALL_WIDTH = 500.0_vp;
361 EXPECT_CALL(*container, IsMainWindow).Times(
362 ::testing::AtLeast(1)).WillRepeatedly(Return(true));
363 SystemProperties::orientation_ = DeviceOrientation::LANDSCAPE;
__anon6ec4ffc10702() 364 windowManager->windowGetModeCallback_ = []() { return WindowMode::WINDOW_MODE_UNDEFINED; };
365 context->SetIsCurrentInForceSplitMode(false);
366 manager->isForceSplitSupported_ = true;
367 manager->isForceSplitEnable_ = true;
368 manager->ignoreOrientation_ = false;
369 manager->UpdateIsInForceSplitMode(static_cast<int32_t>(SMALL_WIDTH.ConvertToPx()));
370 EXPECT_FALSE(context->IsCurrentInForceSplitMode());
371 }
372 } // namespace OHOS::Ace::NG
373