1/*
2 * Copyright (c) 2021 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 <securec.h>
16#include <gtest/gtest.h>
17#include <surface.h>
18#include <consumer_surface.h>
19#include <surface_utils.h>
20#include "buffer_consumer_listener.h"
21#include "surface_buffer_impl.h"
22
23using namespace testing;
24using namespace testing::ext;
25
26namespace OHOS::Rosen {
27class SurfaceUtilsTest : public testing::Test {
28public:
29    static void SetUpTestCase();
30    static void TearDownTestCase();
31    static bool IsArrayEmpty(const float arr[16]);
32    static inline sptr<IConsumerSurface> csurface1 = nullptr;
33    static inline sptr<IBufferProducer> producer1 = nullptr;
34    static inline sptr<Surface> psurface1 = nullptr;
35
36    static inline sptr<IConsumerSurface> csurface2 = nullptr;
37    static inline sptr<IBufferProducer> producer2 = nullptr;
38    static inline sptr<Surface> psurface2 = nullptr;
39
40    static inline SurfaceUtils *utils = nullptr;
41    static constexpr const int32_t TRANSFORM_MATRIX_SIZE = 16;
42};
43
44void SurfaceUtilsTest::SetUpTestCase()
45{
46    csurface1 = IConsumerSurface::Create();
47    sptr<IBufferConsumerListener> listener1 = new BufferConsumerListener();
48    csurface1->RegisterConsumerListener(listener1);
49    producer1 = csurface1->GetProducer();
50    psurface1 = Surface::CreateSurfaceAsProducer(producer1);
51
52    csurface2 = IConsumerSurface::Create();
53    sptr<IBufferConsumerListener> listener2 = new BufferConsumerListener();
54    csurface2->RegisterConsumerListener(listener2);
55    producer2 = csurface2->GetProducer();
56    psurface2 = Surface::CreateSurfaceAsProducer(producer2);
57}
58
59void SurfaceUtilsTest::TearDownTestCase()
60{
61    csurface1 = nullptr;
62    producer1 = nullptr;
63    psurface1 = nullptr;
64
65    csurface2 = nullptr;
66    producer2 = nullptr;
67    psurface2 = nullptr;
68    utils = nullptr;
69}
70
71/*
72* Function: GetInstance
73* Type: Function
74* Rank: Important(2)
75* EnvConditions: N/A
76* CaseDescription: 1. call GetInstance
77*                  2. check ret
78 */
79HWTEST_F(SurfaceUtilsTest, GetInstance001, Function | MediumTest | Level2)
80{
81    utils = SurfaceUtils::GetInstance();
82    ASSERT_NE(utils, nullptr);
83}
84
85/*
86* Function: GetInstance
87* Type: Function
88* Rank: Important(2)
89* EnvConditions: N/A
90* CaseDescription: 1. call Add
91*                  2. check ret
92 */
93HWTEST_F(SurfaceUtilsTest, Add001, Function | MediumTest | Level2)
94{
95    GSError ret = utils->Add(psurface1->GetUniqueId(), nullptr);
96    ASSERT_EQ(ret, OHOS::GSERROR_INVALID_ARGUMENTS);
97}
98
99/*
100* Function: GetInstance
101* Type: Function
102* Rank: Important(2)
103* EnvConditions: N/A
104* CaseDescription: 1. call Add 2 times
105*                  2. check ret
106 */
107HWTEST_F(SurfaceUtilsTest, Add002, Function | MediumTest | Level2)
108{
109    GSError ret = utils->Add(psurface1->GetUniqueId(), psurface1);
110    ASSERT_EQ(ret, OHOS::GSERROR_OK);
111
112    ret = utils->Add(psurface1->GetUniqueId(), psurface1);
113    ASSERT_EQ(ret, OHOS::GSERROR_OK);
114}
115
116/*
117* Function: GetSurface
118* Type: Function
119* Rank: Important(2)
120* EnvConditions: N/A
121* CaseDescription: 1. call GetSurface by abnormal uniqueId
122*                  2. check ret
123 */
124HWTEST_F(SurfaceUtilsTest, GetSurface001, Function | MediumTest | Level2)
125{
126    sptr<Surface> surface = utils->GetSurface(0);
127    ASSERT_EQ(surface, nullptr);
128}
129
130/*
131* Function: GetSurface
132* Type: Function
133* Rank: Important(2)
134* EnvConditions: N/A
135* CaseDescription: 1. call GetSurface
136*                  2. check ret
137 */
138HWTEST_F(SurfaceUtilsTest, GetSurface002, Function | MediumTest | Level2)
139{
140    sptr<Surface> surface1 = utils->GetSurface(psurface1->GetUniqueId());
141    ASSERT_NE(surface1, nullptr);
142}
143
144/*
145* Function: GetSurface
146* Type: Function
147* Rank: Important(2)
148* EnvConditions: N/A
149* CaseDescription: 1. call GetSurface
150*                  2. call Add
151*                  3. call GetSurface again
152*                  4. check ret
153 */
154HWTEST_F(SurfaceUtilsTest, GetSurface003, Function | MediumTest | Level2)
155{
156    sptr<Surface> surface2 = utils->GetSurface(psurface2->GetUniqueId());
157    ASSERT_NE(surface2, nullptr);
158
159    GSError ret = utils->Add(psurface2->GetUniqueId(), psurface2);
160    ASSERT_EQ(ret, OHOS::GSERROR_OK);
161
162    surface2 = utils->GetSurface(psurface2->GetUniqueId());
163    ASSERT_NE(surface2, nullptr);
164}
165
166/*
167* Function: Remove
168* Type: Function
169* Rank: Important(2)
170* EnvConditions: N/A
171* CaseDescription: 1. call Remove
172*                  2. check ret
173 */
174HWTEST_F(SurfaceUtilsTest, Remove001, Function | MediumTest | Level2)
175{
176    GSError ret = utils->Remove(0);
177    ASSERT_EQ(ret, GSERROR_INVALID_OPERATING);
178}
179
180/*
181* Function: Remove
182* Type: Function
183* Rank: Important(2)
184* EnvConditions: N/A
185* CaseDescription: 1. call Remove 2 times
186*                  2. check ret
187 */
188HWTEST_F(SurfaceUtilsTest, Remove002, Function | MediumTest | Level2)
189{
190    GSError ret = utils->Remove(psurface1->GetUniqueId());
191    ASSERT_EQ(ret, OHOS::GSERROR_OK);
192
193    ret = utils->Remove(psurface1->GetUniqueId());
194    ASSERT_EQ(ret, SURFACE_ERROR_INVALID_OPERATING);
195}
196
197/*
198* Function: ComputeTransformMatrix
199* Type: Function
200* Rank: Important(2)
201* EnvConditions: N/A
202* CaseDescription: 1. call ComputeTransformMatrix
203*                  2. call ComputeTransformMatrixV2
204 */
205HWTEST_F(SurfaceUtilsTest, ComputeTransformMatrix001, Function | MediumTest | Level2)
206{
207    // Prepare params
208    sptr<SurfaceBuffer> buffer = new SurfaceBufferImpl();
209    buffer->SetSurfaceBufferWidth(1920);
210    buffer->SetSurfaceBufferHeight(1920);
211    float matrix[TRANSFORM_MATRIX_SIZE];
212    Rect crop = {};
213    crop.w = buffer->GetWidth();
214    crop.h = buffer->GetHeight();
215    GraphicTransformType transform = GraphicTransformType::GRAPHIC_FLIP_H;
216    float emptyMatrix[TRANSFORM_MATRIX_SIZE];
217    //invalid parameter
218    sptr<SurfaceBuffer> tmpBuffer = nullptr;
219    utils->ComputeTransformMatrix(matrix, TRANSFORM_MATRIX_SIZE, tmpBuffer, transform, crop);
220    ASSERT_TRUE(IsArrayEmpty(matrix));
221    utils->ComputeTransformMatrixV2(matrix, TRANSFORM_MATRIX_SIZE, tmpBuffer, transform, crop);
222    ASSERT_TRUE(IsArrayEmpty(matrix));
223
224    // Compute matrix with normal crop
225    utils->ComputeTransformMatrix(matrix, 16, buffer, transform, crop);
226    ASSERT_NE(matrix, emptyMatrix);
227    utils->ComputeTransformMatrixV2(matrix, 16, buffer, transform, crop);
228    ASSERT_NE(matrix, emptyMatrix);
229}
230
231bool SurfaceUtilsTest::IsArrayEmpty(const float arr[TRANSFORM_MATRIX_SIZE])
232{
233    return std::all_of(arr, arr + TRANSFORM_MATRIX_SIZE, [](float value) { return value == 0.0f; });
234}
235
236/*
237* Function: ComputeTransformMatrix
238* Type: Function
239* Rank: Important(2)
240* EnvConditions: N/A
241* CaseDescription: 1. call ComputeTransformMatrix with small crop
242*                  2. call ComputeTransformMatrixV2 with small crop
243 */
244HWTEST_F(SurfaceUtilsTest, ComputeTransformMatrix002, Function | MediumTest | Level2)
245{
246    // Prepare params
247    sptr<SurfaceBuffer> buffer = new SurfaceBufferImpl();
248    buffer->SetSurfaceBufferWidth(1920);
249    buffer->SetSurfaceBufferHeight(1920);
250    float matrix[16];
251    Rect crop = {};
252    crop.w = 100;
253    crop.h = 100;
254    GraphicTransformType transform = GraphicTransformType::GRAPHIC_FLIP_H;
255
256    // Compute matrix with normal crop
257    float emptyMatrix[16];
258    utils->ComputeTransformMatrix(matrix, 16, buffer, transform, crop);
259    ASSERT_NE(matrix, emptyMatrix);
260    utils->ComputeTransformMatrixV2(matrix, 16, buffer, transform, crop);
261    ASSERT_NE(matrix, emptyMatrix);
262}
263}