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 #include <gtest/gtest.h>
16 #include <iservice_registry.h>
17 #include <native_image.h>
18 #include <EGL/egl.h>
19 #include <EGL/eglext.h>
20 #include <sys/time.h>
21 #include <securec.h>
22 #include "graphic_common_c.h"
23 #include "surface_type.h"
24 #include "window.h"
25 #include "GLES/gl.h"
26 #include "surface.h"
27 #include "surface_image.h"
28
29 using namespace testing;
30 using namespace testing::ext;
31 using namespace std;
32
33 namespace OHOS::Rosen {
34 struct TEST_IMAGE {
35 int a;
36 bool b;
37 };
38
39 typedef struct OH_NativeImage_Tmp {
40 OHOS::sptr<OHOS::SurfaceImage> consumer;
41 OHOS::sptr<OHOS::IBufferProducer> producer;
42 OHOS::sptr<OHOS::Surface> pSurface = nullptr;
43 struct NativeWindow* nativeWindow = nullptr;
44 } OH_NativeImage_Tmp;
45
46
47 class NativeImageSystemTest : public testing::Test {
48 public:
49 static void SetUpTestCase();
50 static void TearDownTestCase();
51 static void OnFrameAvailable(void *context);
52 static inline bool isOnFrameAvailabled_ = false;
53
54 // OH_ConsumerSurface_Create001
55 void SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow);
56 bool GetData(sptr<SurfaceBuffer> &buffer);
57 int32_t CreateNativeWindowAndRequestBuffer001(uint64_t uniqueId, NativeWindow **nativeWindow);
58 int32_t ThreadNativeWindowProcess001(int32_t *pipeFd, uint64_t uniqueId);
59 static inline int32_t g_onBufferAvailable_ = 0;
60 };
61
OnFrameAvailable(void * context)62 void NativeImageSystemTest::OnFrameAvailable(void *context)
63 {
64 (void) context;
65 isOnFrameAvailabled_ = true;
66 g_onBufferAvailable_++;
67 }
68
SetUpTestCase()69 void NativeImageSystemTest::SetUpTestCase()
70 {
71 }
72
TearDownTestCase()73 void NativeImageSystemTest::TearDownTestCase()
74 {
75 }
76
ProducerThread(OHNativeWindow * nativeWindow)77 void ProducerThread(OHNativeWindow* nativeWindow)
78 {
79 if (nativeWindow == nullptr) {
80 return;
81 }
82 int32_t code = SET_BUFFER_GEOMETRY;
83 int32_t width = 0x100;
84 int32_t height = 0x100;
85 auto ret = NativeWindowHandleOpt(nativeWindow, code, width, height);
86
87 NativeWindowBuffer* nativeWindowBuffer = nullptr;
88 int fenceFd = -1;
89 struct Region *region = new Region();
90 struct Region::Rect *rect = new Region::Rect();
91 rect->x = 0x100;
92 rect->y = 0x100;
93 rect->w = 0x100;
94 rect->h = 0x100;
95 region->rects = rect;
96 ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
97 if (ret != GSERROR_OK) {
98 return;
99 }
100 ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
101 delete rect;
102 delete region;
103 return;
104 }
105
106 /*
107 * Function: NativeImageSystemTestWithAcquireBuffer
108 * Type: Function
109 * Rank: Important(1)
110 * EnvConditions: N/A
111 * CaseDescription: 1. run NativeImageSystemTestWithAcquireBuffer
112 * 2. check ret
113 * @tc.require: issueI5KG61
114 */
115 HWTEST_F(NativeImageSystemTest, NativeImageSystemTestWithAcquireBuffer, Function | MediumTest | Level1)
116 {
117 OH_NativeImage* newImage = OH_NativeImage_Create(0, 0);
118 ASSERT_NE(newImage, nullptr);
119 OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(newImage);
120 std::thread producerThread(ProducerThread, nativeWindow);
121 producerThread.join();
122 NativeWindowBuffer* nativeWindowBuffer = nullptr;
123 int fenceFd = -1;
124 nativeWindowBuffer = nullptr;
125 auto ret = OH_NativeImage_AcquireNativeWindowBuffer(newImage, &nativeWindowBuffer, &fenceFd);
126 ASSERT_EQ(ret, GSERROR_OK);
127 ASSERT_NE(nativeWindowBuffer, nullptr);
128
129 ret = OH_NativeImage_ReleaseNativeWindowBuffer(newImage, nativeWindowBuffer, fenceFd);
130 ASSERT_EQ(ret, GSERROR_OK);
131
132 OH_NativeImage_Destroy(&newImage);
133 }
134
135 /*
136 * Function: NativeImageSystemTestWithListener
137 * Type: Function
138 * Rank: Important(1)
139 * EnvConditions: N/A
140 * CaseDescription: 1. run NativeImageSystemTestWithListener
141 * 2. check ret
142 * @tc.require: issueI5KG61
143 */
144 HWTEST_F(NativeImageSystemTest, NativeImageSystemTestWithListener, Function | MediumTest | Level1)
145 {
146 OH_NativeImage* newImage = OH_NativeImage_Create(0, 0);
147 ASSERT_NE(newImage, nullptr);
148 OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(newImage);
149 OH_OnFrameAvailableListener listener;
150 listener.context = this;
151 listener.onFrameAvailable = NativeImageSystemTest::OnFrameAvailable;
152 auto ret = OH_NativeImage_SetOnFrameAvailableListener(newImage, listener);
153 ASSERT_EQ(ret, GSERROR_OK);
154
155
156 isOnFrameAvailabled_ = false;
157 std::thread producerThread(ProducerThread, nativeWindow);
158 producerThread.join();
159 EXPECT_TRUE(isOnFrameAvailabled_);
160 NativeWindowBuffer* nativeWindowBuffer = nullptr;
161 int fenceFd = -1;
162 nativeWindowBuffer = nullptr;
163 ret = OH_NativeImage_AcquireNativeWindowBuffer(newImage, &nativeWindowBuffer, &fenceFd);
164 ASSERT_EQ(ret, GSERROR_OK);
165 ASSERT_NE(nativeWindowBuffer, nullptr);
166
167 ret = OH_NativeImage_ReleaseNativeWindowBuffer(newImage, nativeWindowBuffer, fenceFd);
168 ASSERT_EQ(ret, GSERROR_OK);
169
170 OH_NativeImage_Destroy(&newImage);
171 }
172
173 /*
174 * Function: NativeImageSystemTestWithGetTimeStamp
175 * Type: Function
176 * Rank: Important(1)
177 * EnvConditions: N/A
178 * CaseDescription: 1. run NativeImageSystemTestWithGetTimeStamp
179 * 2. check ret
180 * @tc.require: issueI5KG61
181 */
182 HWTEST_F(NativeImageSystemTest, NativeImageSystemTestWithGetTimeStamp, Function | MediumTest | Level1)
183 {
184 OH_NativeImage* newImage = OH_NativeImage_Create(0, 0);
185 ASSERT_NE(newImage, nullptr);
186
187 OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(newImage);
188 std::thread producerThread(ProducerThread, nativeWindow);
189 producerThread.join();
190 int64_t timeStamp = OH_NativeImage_GetTimestamp(newImage);
191 ASSERT_NE(timeStamp, SURFACE_ERROR_ERROR);
192 NativeWindowBuffer* nativeWindowBuffer = nullptr;
193 int fenceFd = -1;
194 nativeWindowBuffer = nullptr;
195 auto ret = OH_NativeImage_AcquireNativeWindowBuffer(newImage, &nativeWindowBuffer, &fenceFd);
196 ASSERT_EQ(ret, GSERROR_OK);
197 ASSERT_NE(nativeWindowBuffer, nullptr);
198
199 ret = OH_NativeImage_ReleaseNativeWindowBuffer(newImage, nativeWindowBuffer, fenceFd);
200 ASSERT_EQ(ret, GSERROR_OK);
201
202 OH_NativeImage_Destroy(&newImage);
203 }
204
SetData(NativeWindowBuffer * nativeWindowBuffer,NativeWindow * nativeWindow)205 void NativeImageSystemTest::SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow)
206 {
207 nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("123", 0x123);
208 nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("345", (int64_t)0x345);
209 nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("567", "567");
210 }
211
GetData(sptr<SurfaceBuffer> & buffer)212 bool NativeImageSystemTest::GetData(sptr<SurfaceBuffer> &buffer)
213 {
214 int32_t int32;
215 int64_t int64;
216 std::string str;
217 buffer->GetExtraData()->ExtraGet("123", int32);
218 buffer->GetExtraData()->ExtraGet("345", int64);
219 buffer->GetExtraData()->ExtraGet("567", str);
220 if ((int32 != 0x123) || (int64 != 0x345) || (str != "567")) {
221 return false;
222 }
223
224 return true;
225 }
226
CreateNativeWindowAndRequestBuffer001(uint64_t uniqueId,NativeWindow ** nativeWindow)227 int32_t NativeImageSystemTest::CreateNativeWindowAndRequestBuffer001(uint64_t uniqueId, NativeWindow **nativeWindow)
228 {
229 int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow);
230 if (ret != GSERROR_OK) {
231 return ret;
232 }
233 struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
234
235 int32_t code = SET_BUFFER_GEOMETRY;
236 int32_t height = 0x100;
237 int32_t width = 0x100;
238 OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
239 code = SET_FORMAT;
240 int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
241 OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
242
243 int32_t fenceFd = -1;
244 struct Region *region = new Region();
245 struct Region::Rect *rect = new Region::Rect();
246 rect->w = 0x100;
247 rect->h = 0x100;
248 region->rects = rect;
249 region->rectNumber = 1;
250 for (int32_t i = 0; i < 3; i++) { // 3 : queue size
251 ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
252 if (ret != GSERROR_OK) {
253 delete rect;
254 delete region;
255 return ret;
256 }
257 SetData(nativeWindowBuffer, *nativeWindow);
258
259 ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
260 if (ret != GSERROR_OK) {
261 delete rect;
262 delete region;
263 return ret;
264 }
265 }
266 delete rect;
267 delete region;
268 return GSERROR_OK;
269 }
270
ThreadNativeWindowProcess001(int32_t * pipeFd,uint64_t uniqueId)271 int32_t NativeImageSystemTest::ThreadNativeWindowProcess001(int32_t *pipeFd, uint64_t uniqueId)
272 {
273 int64_t data;
274 NativeWindow *nativeWindow = nullptr;
275 int32_t ret = CreateNativeWindowAndRequestBuffer001(uniqueId, &nativeWindow);
276 if (ret != GSERROR_OK) {
277 data = ret;
278 write(pipeFd[1], &data, sizeof(data));
279 return -1;
280 }
281
282 data = ret;
283 write(pipeFd[1], &data, sizeof(data));
284 usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
285 read(pipeFd[0], &data, sizeof(data));
286 OH_NativeWindow_DestroyNativeWindow(nativeWindow);
287 return 0;
288 }
289
290 HWTEST_F(NativeImageSystemTest, OH_ConsumerSurface_Create001, Function | MediumTest | Level2)
291 {
292 int32_t pipeFd[2] = {};
293 pipe(pipeFd);
294
295 g_onBufferAvailable_ = 0;
296 OH_NativeImage* consumerSurface = OH_ConsumerSurface_Create();
297 ASSERT_NE(consumerSurface, nullptr);
298 OHNativeWindow* newNativeWindow = OH_NativeImage_AcquireNativeWindow(consumerSurface);
299 ASSERT_NE(newNativeWindow, nullptr);
300 uint64_t uniqueId;
301 int32_t ret = OH_NativeImage_GetSurfaceId(consumerSurface, &uniqueId);
302 EXPECT_EQ(ret, GSERROR_OK);
303
304 OH_OnFrameAvailableListener listener;
305 listener.context = this;
306 listener.onFrameAvailable = NativeImageSystemTest::OnFrameAvailable;
307 ret = OH_NativeImage_SetOnFrameAvailableListener(consumerSurface, listener);
308 ASSERT_EQ(ret, GSERROR_OK);
309
__anon69b9e0890102() 310 std::thread thread([this, pipeFd, uniqueId]() {
311 int32_t ret = this->ThreadNativeWindowProcess001((int32_t*)(pipeFd), uniqueId);
312 EXPECT_EQ(ret, GSERROR_OK);
313 });
314
315 int64_t data = 0;
316 read(pipeFd[0], &data, sizeof(data));
317 EXPECT_EQ(data, GSERROR_OK);
318
319 OHNativeWindowBuffer *nativeWindowBuffer = nullptr;
320 int32_t fence = -1;
321 EXPECT_EQ(g_onBufferAvailable_, 3); // 3 : queue size
322 while (g_onBufferAvailable_ > 0) {
323 ret = OH_NativeImage_AcquireNativeWindowBuffer(consumerSurface, &nativeWindowBuffer, &fence);
324 EXPECT_EQ(ret, GSERROR_OK);
325 EXPECT_NE(nativeWindowBuffer, nullptr);
326 EXPECT_EQ(GetData(nativeWindowBuffer->sfbuffer), true);
327
328 ret = OH_NativeImage_ReleaseNativeWindowBuffer(consumerSurface, nativeWindowBuffer, -1);
329 EXPECT_EQ(ret, GSERROR_OK);
330 g_onBufferAvailable_--;
331 }
332
333 g_onBufferAvailable_ = 0;
334 write(pipeFd[1], &data, sizeof(data));
335 close(pipeFd[0]);
336 close(pipeFd[1]);
337 if (thread.joinable()) {
338 thread.join();
339 }
340 OH_NativeImage_Destroy(&consumerSurface);
341 }
342 }