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 "test/unittest/core/layout/safe_area/expand_safe_area_test_ng.h"
17
18 #include <cstdint>
19 #include <cstdlib>
20 #include <map>
21 #include <memory>
22
23 #include "test/mock/core/pipeline/mock_pipeline_context.h"
24
25 #include "core/components/common/layout/constants.h"
26 #include "core/components_ng/base/view_stack_processor.h"
27 #include "core/components_ng/pattern/linear_layout/column_model_ng.h"
28 #include "core/components_ng/pattern/relative_container/relative_container_model_ng.h"
29 #include "core/components_ng/pattern/stack/stack_pattern.h"
30 #include "core/components_ng/property/measure_property.h"
31 #include "core/components_ng/property/property.h"
32 #include "core/components_ng/property/safe_area_insets.h"
33 #include "core/components_v2/inspector/inspector_constants.h"
34 #undef private
35 #undef protected
36 namespace OHOS::Ace::NG {
37 namespace {
38 constexpr float WINDOW_WIDTH = 720.0f;
39 constexpr float WINDOW_HEIGHT = 1280.0f;
40 constexpr int32_t CHILD_COUNT_1 = 1;
41 constexpr float ITEM_HEIGHT_100 = 100.0f;
42 constexpr float ITEM_HEIGHT_50 = 50.0f;
43 constexpr float SAFE_AREA_LENGTH_TOP = 80.0f;
44 constexpr float SAFE_AREA_LENGTH_BOTTOM = 100.0f;
45 constexpr float SAFE_AREA_LENGTH_LEFT = 20.0f;
46 constexpr float SAFE_AREA_LENGTH_RIGHT = 20.0f;
47 constexpr float SAFE_AREA_KEYBOARD = 500.0f;
48 } // namespace
49
SetUpTestSuite()50 void ExpandSafeAreaTestNg::SetUpTestSuite()
51 {
52 TestNG::SetUpTestSuite();
53 }
54
TearDownTestSuite()55 void ExpandSafeAreaTestNg::TearDownTestSuite()
56 {
57 TestNG::TearDownTestSuite();
58 }
59
SetUp()60 void ExpandSafeAreaTestNg::SetUp() {}
61
InitSafeAreaManager(AvoidConfig config)62 void ExpandSafeAreaTestNg::InitSafeAreaManager(AvoidConfig config)
63 {
64 auto pipeline = MockPipelineContext::GetCurrent();
65 CHECK_NULL_VOID(pipeline);
66 auto safeAreaManager = pipeline->GetSafeAreaManager();
67 CHECK_NULL_VOID(safeAreaManager);
68 safeAreaManager->SetIsFullScreen(config.isFullScreen);
69 safeAreaManager->SetIsNeedAvoidWindow(config.isNeedAvoidWindow);
70 safeAreaManager->SetIgnoreSafeArea(config.ignoreSafeArea);
71 safeAreaManager->SetKeyBoardAvoidMode(KeyBoardAvoidMode::OFFSET);
72 }
73
TearDown()74 void ExpandSafeAreaTestNg::TearDown()
75 {
76 frameNode_ = nullptr;
77 pagePattern_ = nullptr;
78 }
79
GetInstance()80 void ExpandSafeAreaTestNg::GetInstance()
81 {
82 RefPtr<UINode> element = ViewStackProcessor::GetInstance()->Finish();
83 frameNode_ = AceType::DynamicCast<FrameNode>(element);
84 frameNode_->isConstraintNotChanged_ = true;
85 pagePattern_ = frameNode_->GetPattern();
86 }
87
Create(const std::function<void ()> & callback,bool flushLayout)88 void ExpandSafeAreaTestNg::Create(const std::function<void()>& callback, bool flushLayout)
89 {
90 auto pageNode = FrameNode::CreateFrameNode(
91 V2::PAGE_ETS_TAG, -1, AceType::MakeRefPtr<PagePattern>(AceType::MakeRefPtr<PageInfo>()));
92 ViewStackProcessor::GetInstance()->Push(pageNode);
93 ViewAbstract::SetWidth(CalcLength(WINDOW_WIDTH));
94 ViewAbstract::SetHeight(CalcLength(WINDOW_HEIGHT));
95 if (callback) {
96 callback();
97 }
98 GetInstance();
99 if (flushLayout) {
100 FlushLayoutTask(frameNode_);
101 }
102 }
103
CreateWithItem(const std::function<void ()> & callback)104 void ExpandSafeAreaTestNg::CreateWithItem(const std::function<void()>& callback)
105 {
106 Create([callback]() {
107 if (callback) {
108 callback();
109 }
110 CreateItem(CHILD_COUNT_1);
111 });
112 }
113
CreateItem(int32_t number,bool defineSize)114 void ExpandSafeAreaTestNg::CreateItem(int32_t number, bool defineSize)
115 {
116 for (int32_t i = 0; i < number; i++) {
117 RelativeContainerModelNG relativeContainerModel;
118 relativeContainerModel.Create();
119 if (defineSize) {
120 ViewAbstract::SetHeight(CalcLength(FILL_LENGTH));
121 }
122 ViewStackProcessor::GetInstance()->Pop();
123 }
124 }
125
AddItems(int32_t number)126 void ExpandSafeAreaTestNg::AddItems(int32_t number)
127 {
128 for (int i = 0; i < number; ++i) {
129 auto child = FrameNode::GetOrCreateFrameNode(
130 V2::STACK_ETS_TAG, -1, []() { return AceType::MakeRefPtr<StackPattern>(); });
131 if (i & 1) {
132 child->GetLayoutProperty()->UpdateUserDefinedIdealSize(
133 CalcSize(CalcLength(FILL_LENGTH), CalcLength(Dimension(ITEM_HEIGHT_100))));
134 } else {
135 child->GetLayoutProperty()->UpdateUserDefinedIdealSize(
136 CalcSize(CalcLength(FILL_LENGTH), CalcLength(Dimension(ITEM_HEIGHT_50))));
137 }
138 frameNode_->AddChild(child);
139 }
140 }
141
CreateItemWithHeight(float height)142 void ExpandSafeAreaTestNg::CreateItemWithHeight(float height)
143 {
144 RelativeContainerModelNG relativeContainerModelNG;
145 relativeContainerModelNG.Create();
146 ViewAbstract::SetWidth(CalcLength(FILL_LENGTH));
147 ViewAbstract::SetHeight(CalcLength(Dimension(height)));
148 ViewStackProcessor::GetInstance()->Pop();
149 }
150
InitSafeArea(SafeAreaExpandOpts opts)151 void ExpandSafeAreaTestNg::InitSafeArea(SafeAreaExpandOpts opts)
152 {
153 auto pipeline = MockPipelineContext::GetCurrent();
154 CHECK_NULL_VOID(pipeline);
155 SafeAreaInsets insets;
156 if (opts.edges & SAFE_AREA_EDGE_TOP) {
157 insets.top_ = { 0.0f, SAFE_AREA_LENGTH_TOP };
158 }
159 if (opts.edges & SAFE_AREA_EDGE_START) {
160 insets.left_ = { 0.0f, SAFE_AREA_LENGTH_LEFT };
161 }
162 if (opts.edges & SAFE_AREA_EDGE_END) {
163 insets.right_ = { WINDOW_WIDTH, WINDOW_WIDTH - SAFE_AREA_LENGTH_RIGHT };
164 }
165 if (opts.edges & SAFE_AREA_EDGE_BOTTOM) {
166 insets.bottom_ = { WINDOW_HEIGHT - SAFE_AREA_LENGTH_BOTTOM, WINDOW_HEIGHT };
167 }
168 auto safeAreaManager = pipeline->GetSafeAreaManager();
169 CHECK_NULL_VOID(safeAreaManager);
170 // for tdd, we assume opt type in this function is used to update one specific type
171 switch (opts.type) {
172 case SAFE_AREA_TYPE_SYSTEM:
173 pipeline->UpdateSystemSafeArea(insets);
174 break;
175 case SAFE_AREA_TYPE_CUTOUT:
176 pipeline->UpdateCutoutSafeArea(insets);
177 break;
178 case SAFE_AREA_TYPE_KEYBOARD:
179 safeAreaManager->UpdateKeyboardOffset(SAFE_AREA_KEYBOARD);
180 break;
181 default:
182 break;
183 }
184 }
185
GetSafeAreaInsets()186 SafeAreaInsets ExpandSafeAreaTestNg::GetSafeAreaInsets()
187 {
188 SafeAreaInsets insets;
189 auto pipeline = MockPipelineContext::GetCurrent();
190 CHECK_NULL_RETURN(pipeline, insets);
191 auto safeAreaManager = pipeline->GetSafeAreaManager();
192 CHECK_NULL_RETURN(safeAreaManager, insets);
193 insets = safeAreaManager->GetSafeArea();
194 return insets;
195 }
196
197 /**
198 * @tc.name: Manager001
199 * @tc.desc: Test SafeAreaManager top & bottom system safeArea.
200 * @tc.type: FUNC
201 */
202 HWTEST_F(ExpandSafeAreaTestNg, Manager001, TestSize.Level1)
203 {
204 AvoidConfig config { .isFullScreen = true };
205 InitSafeAreaManager(config);
206 SafeAreaExpandOpts opts { .type = SAFE_AREA_TYPE_SYSTEM, .edges = SAFE_AREA_EDGE_TOP | SAFE_AREA_EDGE_BOTTOM };
207 InitSafeArea(opts);
208 auto safeAreaInsets = GetSafeAreaInsets();
209 EXPECT_TRUE(safeAreaInsets.left_.Length() == 0);
210 EXPECT_FALSE(safeAreaInsets.top_.Length() == 0);
211 EXPECT_TRUE(safeAreaInsets.top_.start == 0);
212 EXPECT_TRUE(safeAreaInsets.top_.end == SAFE_AREA_LENGTH_TOP);
213 EXPECT_TRUE(safeAreaInsets.right_.Length() == 0);
214 EXPECT_FALSE(safeAreaInsets.bottom_.Length() == 0);
215 EXPECT_EQ(safeAreaInsets.bottom_.start, (WINDOW_HEIGHT - SAFE_AREA_LENGTH_BOTTOM));
216 EXPECT_EQ(safeAreaInsets.bottom_.end, WINDOW_HEIGHT);
217 }
218 } // namespace OHOS::Ace::NG
219