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