• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
__anon07e799eb0102() 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 }