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 <chrono>
16#include <thread>
17#include <unistd.h>
18#include <gtest/gtest.h>
19#include <securec.h>
20#include <native_window.h>
21#include "external_window.h"
22#include "iconsumer_surface.h"
23#include "event_handler.h"
24
25using namespace testing;
26using namespace testing::ext;
27
28namespace OHOS::Rosen {
29constexpr uint32_t QUEUE_SIZE = 5;
30class NativeWindowTest : public testing::Test, public IBufferConsumerListenerClazz {
31public:
32    static void SetUpTestCase();
33    void OnBufferAvailable() override;
34    void SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow);
35    bool GetData(sptr<SurfaceBuffer> &buffer);
36
37    // OH_NativeWindow_CreateNativeWindow001
38    int32_t ThreadNativeWindowProcess001(int32_t *pipeFd, sptr<IBufferProducer> producer);
39    int32_t CreateNativeWindowAndRequestBuffer001(sptr<IBufferProducer> producer, NativeWindow **nativeWindow);
40
41    // OH_NativeWindow_CreateNativeWindow002
42    int32_t ThreadNativeWindowProcess002(int32_t *pipeFd, sptr<IBufferProducer> producer);
43    int32_t CreateNativeWindowAndRequestBuffer002(sptr<IBufferProducer> producer, NativeWindow **nativeWindow);
44
45    // OH_NativeWindow_CreateNativeWindowFromSurfaceId001
46    int32_t ThreadNativeWindowProcess003(int32_t *pipeFd, uint64_t uniqueId);
47    int32_t CreateNativeWindowAndRequestBuffer003(uint64_t uniqueId, NativeWindow **nativeWindow);
48
49    // OH_NativeWindow_CreateNativeWindowFromSurfaceId002
50    int32_t ThreadNativeWindowProcess004(int32_t *pipeFd, uint64_t uniqueId);
51    int32_t CreateNativeWindowAndRequestBuffer004(uint64_t uniqueId, NativeWindow **nativeWindow);
52    int32_t RequestBuffer001(NativeWindow *nativeWindow);
53
54    // OH_NativeWindow_GetLastFlushedBufferV2001
55    int32_t ThreadNativeWindowProcess005(int32_t *pipeFd, uint64_t uniqueId);
56    int32_t CreateNativeWindowAndRequestBuffer005(uint64_t uniqueId, NativeWindow **nativeWindow);
57
58    // OH_NativeWindow_NativeObjectReference001
59    int32_t ThreadNativeWindowProcess006(int32_t *pipeFd, uint64_t uniqueId);
60
61    // OH_NativeWindow_GetSurfaceId001
62    int32_t ThreadNativeWindowProcess007(int32_t *pipeFd, sptr<IBufferProducer> producer, uint64_t *uniqueId);
63    int32_t CreateNativeWindowAndRequestBuffer007(sptr<IBufferProducer> producer, NativeWindow **nativeWindow);
64
65    // OH_NativeWindow_NativeWindowAttachBuffer001
66    int32_t ThreadNativeWindowProcess008(int32_t *pipeFd, uint64_t uniqueId);
67    int32_t CreateNativeWindowAndRequestBuffer008(uint64_t uniqueId, NativeWindow **nativeWindow);
68    int32_t CreateNativeWindowAndAttachBuffer001(NativeWindow *nativeWindow);
69
70    int32_t g_onBufferAvailable_ = 0;
71};
72
73class OnBufferAvailableTest : public IBufferConsumerListenerClazz, public RefBase {
74public:
75    void OnBufferAvailable() override;
76};
77
78void OnBufferAvailableTest::OnBufferAvailable() {};
79
80void NativeWindowTest::SetUpTestCase() {}
81
82void NativeWindowTest::OnBufferAvailable()
83{
84    g_onBufferAvailable_++;
85}
86
87int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer001(sptr<IBufferProducer> producer,
88    NativeWindow **nativeWindow)
89{
90    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
91    *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
92    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
93
94    int32_t code = SET_BUFFER_GEOMETRY;
95    int32_t height = 0x100;
96    int32_t width = 0x100;
97    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
98
99    int32_t fenceFd = -1;
100    auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
101    if (ret != OHOS::GSERROR_OK) {
102        return ret;
103    }
104
105    struct Region *region = new Region();
106    struct Region::Rect *rect = new Region::Rect();
107    rect->w = 0x100;
108    rect->h = 0x100;
109    region->rects = rect;
110    region->rectNumber = 1;
111    ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
112    if (ret != OHOS::GSERROR_OK) {
113        delete rect;
114        delete region;
115        return ret;
116    }
117    delete rect;
118    delete region;
119    return OHOS::GSERROR_OK;
120}
121
122int32_t NativeWindowTest::ThreadNativeWindowProcess001(int32_t *pipeFd, sptr<IBufferProducer> producer)
123{
124    int64_t data;
125    NativeWindow *nativeWindow = nullptr;
126    int32_t ret = CreateNativeWindowAndRequestBuffer001(producer, &nativeWindow);
127    if (ret != OHOS::GSERROR_OK) {
128        data = ret;
129        write(pipeFd[1], &data, sizeof(data));
130        return -1;
131    }
132
133    data = ret;
134    write(pipeFd[1], &data, sizeof(data));
135    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
136    read(pipeFd[0], &data, sizeof(data));
137    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
138    return 0;
139}
140
141HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindow001, Function | MediumTest | Level2)
142{
143    int32_t pipeFd[2] = {};
144    pipe(pipeFd);
145
146    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow001");
147    cSurface->RegisterConsumerListener(this);
148    auto producer = cSurface->GetProducer();
149
150    std::thread thread([this, pipeFd, producer]() {
151        int32_t ret = this->ThreadNativeWindowProcess001((int32_t*)(pipeFd), producer);
152        EXPECT_EQ(ret, OHOS::GSERROR_OK);
153    });
154
155    int64_t data = 0;
156    read(pipeFd[0], &data, sizeof(data));
157    EXPECT_EQ(data, OHOS::GSERROR_OK);
158
159    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
160    int32_t fence = -1;
161    int64_t timestamp;
162    Rect damage;
163    auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
164    EXPECT_EQ(ret, OHOS::GSERROR_OK);
165    EXPECT_NE(buffer, nullptr);
166
167    ret = cSurface->ReleaseBuffer(buffer, -1);
168    EXPECT_EQ(ret, OHOS::GSERROR_OK);
169
170    write(pipeFd[1], &data, sizeof(data));
171    close(pipeFd[0]);
172    close(pipeFd[1]);
173    if (thread.joinable()) {
174        thread.join();
175    }
176    producer = nullptr;
177    cSurface = nullptr;
178}
179
180void NativeWindowTest::SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow)
181{
182    nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("123", 0x123);
183    nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("345", (int64_t)0x345);
184    nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("567", "567");
185}
186
187bool NativeWindowTest::GetData(sptr<SurfaceBuffer> &buffer)
188{
189    int32_t int32;
190    int64_t int64;
191    std::string str;
192    buffer->GetExtraData()->ExtraGet("123", int32);
193    buffer->GetExtraData()->ExtraGet("345", int64);
194    buffer->GetExtraData()->ExtraGet("567", str);
195    if ((int32 != 0x123) || (int64 != 0x345) || (str != "567")) {
196        return false;
197    }
198
199    return true;
200}
201
202int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer002(sptr<IBufferProducer> producer,
203    NativeWindow **nativeWindow)
204{
205    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
206    *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
207    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
208
209    int32_t code = SET_BUFFER_GEOMETRY;
210    int32_t height = 0x100;
211    int32_t width = 0x100;
212    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
213    code = SET_FORMAT;
214    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
215    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
216
217    int32_t fenceFd = -1;
218    auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
219    if (ret != OHOS::GSERROR_OK) {
220        return ret;
221    }
222    SetData(nativeWindowBuffer, *nativeWindow);
223
224    struct Region *region = new Region();
225    struct Region::Rect *rect = new Region::Rect();
226    rect->w = 0x100;
227    rect->h = 0x100;
228    region->rects = rect;
229    region->rectNumber = 1;
230    ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
231    if (ret != OHOS::GSERROR_OK) {
232        delete rect;
233        delete region;
234        return ret;
235    }
236    delete rect;
237    delete region;
238    return OHOS::GSERROR_OK;
239}
240
241int32_t NativeWindowTest::ThreadNativeWindowProcess002(int32_t *pipeFd, sptr<IBufferProducer> producer)
242{
243    int64_t data;
244    NativeWindow *nativeWindow = nullptr;
245    int32_t ret = CreateNativeWindowAndRequestBuffer002(producer, &nativeWindow);
246    if (ret != OHOS::GSERROR_OK) {
247        data = ret;
248        write(pipeFd[1], &data, sizeof(data));
249        return -1;
250    }
251
252    data = ret;
253    write(pipeFd[1], &data, sizeof(data));
254    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
255    read(pipeFd[0], &data, sizeof(data));
256    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
257    return 0;
258}
259
260HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindow002, Function | MediumTest | Level2)
261{
262    int32_t pipeFd[2] = {};
263    pipe(pipeFd);
264
265    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow002");
266    cSurface->RegisterConsumerListener(this);
267    auto producer = cSurface->GetProducer();
268
269    std::thread thread([this, pipeFd, producer]() {
270        int32_t ret = this->ThreadNativeWindowProcess002((int32_t*)(pipeFd), producer);
271        EXPECT_EQ(ret, OHOS::GSERROR_OK);
272    });
273
274    int64_t data = 0;
275    read(pipeFd[0], &data, sizeof(data));
276    EXPECT_EQ(data, OHOS::GSERROR_OK);
277
278    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
279    int32_t fence = -1;
280    int64_t timestamp;
281    Rect damage;
282    auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
283    EXPECT_EQ(ret, OHOS::GSERROR_OK);
284    EXPECT_NE(buffer, nullptr);
285    EXPECT_EQ(GetData(buffer), true);
286
287    ret = cSurface->ReleaseBuffer(buffer, -1);
288    EXPECT_EQ(ret, OHOS::GSERROR_OK);
289
290    write(pipeFd[1], &data, sizeof(data));
291    close(pipeFd[0]);
292    close(pipeFd[1]);
293    if (thread.joinable()) {
294        thread.join();
295    }
296    producer = nullptr;
297    cSurface = nullptr;
298}
299
300int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer003(uint64_t uniqueId, NativeWindow **nativeWindow)
301{
302    int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow);
303    if (ret != OHOS::GSERROR_OK) {
304        return ret;
305    }
306    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
307
308    int32_t code = SET_BUFFER_GEOMETRY;
309    int32_t height = 0x100;
310    int32_t width = 0x100;
311    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
312    code = SET_FORMAT;
313    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
314    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
315
316    int32_t fenceFd = -1;
317    struct Region *region = new Region();
318    struct Region::Rect *rect = new Region::Rect();
319    rect->w = 0x100;
320    rect->h = 0x100;
321    region->rects = rect;
322    region->rectNumber = 1;
323    for (int32_t i = 0; i < QUEUE_SIZE; i++) {
324        ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
325        if (ret != OHOS::GSERROR_OK) {
326            delete rect;
327            delete region;
328            return ret;
329        }
330        SetData(nativeWindowBuffer, *nativeWindow);
331
332        ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
333        if (ret != OHOS::GSERROR_OK) {
334            delete rect;
335            delete region;
336            return ret;
337        }
338    }
339    delete rect;
340    delete region;
341    return OHOS::GSERROR_OK;
342}
343
344int32_t NativeWindowTest::ThreadNativeWindowProcess003(int32_t *pipeFd, uint64_t uniqueId)
345{
346    int64_t data;
347    NativeWindow *nativeWindow = nullptr;
348    int32_t ret = CreateNativeWindowAndRequestBuffer003(uniqueId, &nativeWindow);
349    if (ret != OHOS::GSERROR_OK) {
350        data = ret;
351        write(pipeFd[1], &data, sizeof(data));
352        return -1;
353    }
354
355    data = ret;
356    write(pipeFd[1], &data, sizeof(data));
357    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
358    read(pipeFd[0], &data, sizeof(data));
359    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
360    return 0;
361}
362
363HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindowFromSurfaceId001, Function | MediumTest | Level2)
364{
365    int32_t pipeFd[2] = {};
366    pipe(pipeFd);
367
368    sptr<OHOS::IConsumerSurface> cSurface =
369        IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindowFromSurfaceId001");
370    cSurface->RegisterConsumerListener(this);
371    auto producer = cSurface->GetProducer();
372    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
373    EXPECT_NE(pSurface, nullptr);
374    EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK);
375
376    uint64_t uniqueId = cSurface->GetUniqueId();
377    std::thread thread([this, pipeFd, uniqueId]() {
378        int32_t ret = this->ThreadNativeWindowProcess003((int32_t*)(pipeFd), uniqueId);
379        EXPECT_EQ(ret, OHOS::GSERROR_OK);
380    });
381
382    int64_t data = 0;
383    read(pipeFd[0], &data, sizeof(data));
384    EXPECT_EQ(data, OHOS::GSERROR_OK);
385
386    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
387    int32_t fence = -1;
388    int64_t timestamp;
389    Rect damage;
390    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
391    while (g_onBufferAvailable_ > 0) {
392        auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
393        EXPECT_EQ(ret, OHOS::GSERROR_OK);
394        EXPECT_NE(buffer, nullptr);
395        EXPECT_EQ(GetData(buffer), true);
396
397        ret = cSurface->ReleaseBuffer(buffer, -1);
398        EXPECT_EQ(ret, OHOS::GSERROR_OK);
399        g_onBufferAvailable_--;
400    }
401
402    g_onBufferAvailable_ = 0;
403    write(pipeFd[1], &data, sizeof(data));
404    close(pipeFd[0]);
405    close(pipeFd[1]);
406    if (thread.joinable()) {
407        thread.join();
408    }
409    producer = nullptr;
410    cSurface = nullptr;
411}
412
413int32_t NativeWindowTest::RequestBuffer001(NativeWindow *nativeWindow)
414{
415    int32_t fenceFd = -1;
416    struct Region *region = new Region();
417    struct Region::Rect *rect = new Region::Rect();
418    rect->w = 0x100;
419    rect->h = 0x100;
420    region->rects = rect;
421    region->rectNumber = 1;
422    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
423    int32_t ret;
424    for (int32_t i = 0; i < QUEUE_SIZE; i++) {
425        ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
426        if (ret != OHOS::GSERROR_OK) {
427            delete rect;
428            delete region;
429            return ret;
430        }
431        SetData(nativeWindowBuffer, nativeWindow);
432
433        ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region);
434        if (ret != OHOS::GSERROR_OK) {
435            delete rect;
436            delete region;
437            return ret;
438        }
439    }
440    delete rect;
441    delete region;
442    return OHOS::GSERROR_OK;
443}
444
445int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer004(uint64_t uniqueId, NativeWindow **nativeWindow)
446{
447    int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow);
448    if (ret != OHOS::GSERROR_OK) {
449        return ret;
450    }
451    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
452
453    int32_t code = SET_BUFFER_GEOMETRY;
454    int32_t height = 0x100;
455    int32_t width = 0x100;
456    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
457    code = SET_FORMAT;
458    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
459    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
460
461    int32_t fenceFd = -1;
462    struct Region *region = new Region();
463    struct Region::Rect *rect = new Region::Rect();
464    rect->w = 0x100;
465    rect->h = 0x100;
466    region->rects = rect;
467    region->rectNumber = 1;
468    for (int32_t i = 0; i < QUEUE_SIZE; i++) {
469        ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
470        if (ret != OHOS::GSERROR_OK) {
471            delete rect;
472            delete region;
473            return ret;
474        }
475        SetData(nativeWindowBuffer, *nativeWindow);
476
477        ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
478        if (ret != OHOS::GSERROR_OK) {
479            delete rect;
480            delete region;
481            return ret;
482        }
483    }
484    delete rect;
485    delete region;
486    return OHOS::GSERROR_OK;
487}
488
489int32_t NativeWindowTest::ThreadNativeWindowProcess004(int32_t *pipeFd, uint64_t uniqueId)
490{
491    int64_t data;
492    NativeWindow *nativeWindow = nullptr;
493    int32_t ret = CreateNativeWindowAndRequestBuffer004(uniqueId, &nativeWindow);
494    if (ret != OHOS::GSERROR_OK) {
495        data = ret;
496        write(pipeFd[1], &data, sizeof(data));
497        return -1;
498    }
499
500    data = ret;
501    write(pipeFd[1], &data, sizeof(data));
502    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
503    read(pipeFd[0], &data, sizeof(data));
504    ret = RequestBuffer001(nativeWindow);
505    if (ret != OHOS::GSERROR_OK) {
506        data = ret;
507        write(pipeFd[1], &data, sizeof(data));
508        return -1;
509    }
510    data = ret;
511    write(pipeFd[1], &data, sizeof(data));
512    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
513    return 0;
514}
515
516HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindowFromSurfaceId002, Function | MediumTest | Level2)
517{
518    int32_t pipeFd[2] = {};
519    pipe(pipeFd);
520
521    sptr<OHOS::IConsumerSurface> cSurface =
522        IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindowFromSurfaceId002");
523    cSurface->RegisterConsumerListener(this);
524    auto producer = cSurface->GetProducer();
525    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
526    EXPECT_NE(pSurface, nullptr);
527    EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK);
528
529    uint64_t uniqueId = cSurface->GetUniqueId();
530    std::thread thread([this, pipeFd, uniqueId]() {
531        int32_t ret = this->ThreadNativeWindowProcess004((int32_t*)(pipeFd), uniqueId);
532        EXPECT_EQ(ret, OHOS::GSERROR_OK);
533    });
534
535    int64_t data = 0;
536    read(pipeFd[0], &data, sizeof(data));
537    EXPECT_EQ(data, OHOS::GSERROR_OK);
538
539    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
540    int32_t fence = -1;
541    int64_t timestamp;
542    Rect damage;
543    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
544    while (g_onBufferAvailable_ > 0) {
545        auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
546        EXPECT_EQ(ret, OHOS::GSERROR_OK);
547        EXPECT_NE(buffer, nullptr);
548        EXPECT_EQ(GetData(buffer), true);
549
550        ret = cSurface->ReleaseBuffer(buffer, -1);
551        EXPECT_EQ(ret, OHOS::GSERROR_OK);
552        g_onBufferAvailable_--;
553    }
554
555    write(pipeFd[1], &data, sizeof(data));
556    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
557    read(pipeFd[0], &data, sizeof(data));
558    EXPECT_EQ(data, OHOS::GSERROR_OK);
559    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
560    g_onBufferAvailable_ = 0;
561    close(pipeFd[0]);
562    close(pipeFd[1]);
563    if (thread.joinable()) {
564        thread.join();
565    }
566    producer = nullptr;
567    cSurface = nullptr;
568}
569
570int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer005(uint64_t uniqueId, NativeWindow **nativeWindow)
571{
572    int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow);
573    if (ret != OHOS::GSERROR_OK) {
574        return ret;
575    }
576
577    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
578    struct NativeWindowBuffer *lastNativeWindowBuffer = nullptr;
579
580    int32_t code = SET_BUFFER_GEOMETRY;
581    int32_t height = 0x100;
582    int32_t width = 0x100;
583    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
584    code = SET_FORMAT;
585    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
586    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
587
588    int32_t fenceFd = -1;
589    struct Region *region = new Region();
590    struct Region::Rect *rect = new Region::Rect();
591    rect->w = 0x100;
592    rect->h = 0x100;
593    region->rects = rect;
594    region->rectNumber = 1;
595    float matrix[16] = {0};
596    for (int32_t i = 0; i < QUEUE_SIZE; i++) {
597        ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
598        if (ret != OHOS::GSERROR_OK) {
599            delete rect;
600            delete region;
601            return ret;
602        }
603        SetData(nativeWindowBuffer, *nativeWindow);
604
605        ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
606        if (ret != OHOS::GSERROR_OK) {
607            delete rect;
608            delete region;
609            return ret;
610        }
611        ret = OH_NativeWindow_GetLastFlushedBufferV2(*nativeWindow, &lastNativeWindowBuffer, &fenceFd, matrix);
612        if (ret != OHOS::GSERROR_OK) {
613            delete rect;
614            delete region;
615            return ret;
616        }
617        if (!GetData(lastNativeWindowBuffer->sfbuffer)) {
618            delete rect;
619            delete region;
620            return -1;
621        }
622    }
623    delete rect;
624    delete region;
625    return OHOS::GSERROR_OK;
626}
627
628int32_t NativeWindowTest::ThreadNativeWindowProcess005(int32_t *pipeFd, uint64_t uniqueId)
629{
630    int64_t data;
631    NativeWindow *nativeWindow = nullptr;
632    int32_t ret = CreateNativeWindowAndRequestBuffer005(uniqueId, &nativeWindow);
633    if (ret != OHOS::GSERROR_OK) {
634        data = ret;
635        write(pipeFd[1], &data, sizeof(data));
636        return -1;
637    }
638
639    data = ret;
640    write(pipeFd[1], &data, sizeof(data));
641    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
642    read(pipeFd[0], &data, sizeof(data));
643    ret = RequestBuffer001(nativeWindow);
644    if (ret != OHOS::GSERROR_OK) {
645        data = ret;
646        write(pipeFd[1], &data, sizeof(data));
647        return -1;
648    }
649    data = ret;
650    write(pipeFd[1], &data, sizeof(data));
651    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
652    return 0;
653}
654
655HWTEST_F(NativeWindowTest, OH_NativeWindow_GetLastFlushedBufferV2001, Function | MediumTest | Level2)
656{
657    int32_t pipeFd[2] = {};
658    pipe(pipeFd);
659
660    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_GetLastFlushedBufferV2001");
661    cSurface->RegisterConsumerListener(this);
662    auto producer = cSurface->GetProducer();
663    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
664    EXPECT_NE(pSurface, nullptr);
665    EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK);
666
667    uint64_t uniqueId = cSurface->GetUniqueId();
668    std::thread thread([this, pipeFd, uniqueId]() {
669        int32_t ret = this->ThreadNativeWindowProcess005((int32_t*)(pipeFd), uniqueId);
670        EXPECT_EQ(ret, OHOS::GSERROR_OK);
671    });
672
673    int64_t data = 0;
674    read(pipeFd[0], &data, sizeof(data));
675    EXPECT_EQ(data, OHOS::GSERROR_OK);
676
677    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
678    int32_t fence = -1;
679    int64_t timestamp;
680    Rect damage;
681    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
682    while (g_onBufferAvailable_ > 0) {
683        auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
684        EXPECT_EQ(ret, OHOS::GSERROR_OK);
685        EXPECT_NE(buffer, nullptr);
686        EXPECT_EQ(GetData(buffer), true);
687
688        ret = cSurface->ReleaseBuffer(buffer, -1);
689        EXPECT_EQ(ret, OHOS::GSERROR_OK);
690        g_onBufferAvailable_--;
691    }
692
693    write(pipeFd[1], &data, sizeof(data));
694    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
695    read(pipeFd[0], &data, sizeof(data));
696    EXPECT_EQ(data, OHOS::GSERROR_OK);
697    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
698    g_onBufferAvailable_ = 0;
699    close(pipeFd[0]);
700    close(pipeFd[1]);
701    if (thread.joinable()) {
702        thread.join();
703    }
704    producer = nullptr;
705    cSurface = nullptr;
706}
707
708int32_t NativeWindowTest::ThreadNativeWindowProcess006(int32_t *pipeFd, uint64_t uniqueId)
709{
710    int64_t data;
711    NativeWindow *nativeWindow = nullptr;
712    int32_t ret = CreateNativeWindowAndRequestBuffer005(uniqueId, &nativeWindow);
713    if (ret != OHOS::GSERROR_OK) {
714        data = ret;
715        write(pipeFd[1], &data, sizeof(data));
716        return -1;
717    }
718    ret = OH_NativeWindow_NativeObjectReference(nativeWindow);
719    if (ret != OHOS::GSERROR_OK) {
720        data = ret;
721        write(pipeFd[1], &data, sizeof(data));
722        return -1;
723    }
724    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
725
726    data = ret;
727    write(pipeFd[1], &data, sizeof(data));
728    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
729    read(pipeFd[0], &data, sizeof(data));
730    ret = RequestBuffer001(nativeWindow);
731    if (ret != OHOS::GSERROR_OK) {
732        data = ret;
733        write(pipeFd[1], &data, sizeof(data));
734        return -1;
735    }
736    data = ret;
737    write(pipeFd[1], &data, sizeof(data));
738    ret = OH_NativeWindow_NativeObjectUnreference(nativeWindow);
739    if (ret != OHOS::GSERROR_OK) {
740        return -1;
741    }
742    return 0;
743}
744
745HWTEST_F(NativeWindowTest, OH_NativeWindow_NativeObjectReference001, Function | MediumTest | Level2)
746{
747    int32_t pipeFd[2] = {};
748    pipe(pipeFd);
749
750    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_NativeObjectReference001");
751    cSurface->RegisterConsumerListener(this);
752    auto producer = cSurface->GetProducer();
753    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
754    EXPECT_NE(pSurface, nullptr);
755    EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK);
756
757    uint64_t uniqueId = cSurface->GetUniqueId();
758    std::thread thread([this, pipeFd, uniqueId]() {
759        int32_t ret = this->ThreadNativeWindowProcess006((int32_t*)(pipeFd), uniqueId);
760        EXPECT_EQ(ret, OHOS::GSERROR_OK);
761    });
762
763    int64_t data = 0;
764    read(pipeFd[0], &data, sizeof(data));
765    EXPECT_EQ(data, OHOS::GSERROR_OK);
766
767    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
768    int32_t fence = -1;
769    int64_t timestamp;
770    Rect damage;
771    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
772    while (g_onBufferAvailable_ > 0) {
773        auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
774        EXPECT_EQ(ret, OHOS::GSERROR_OK);
775        EXPECT_NE(buffer, nullptr);
776        EXPECT_EQ(GetData(buffer), true);
777
778        ret = cSurface->ReleaseBuffer(buffer, -1);
779        EXPECT_EQ(ret, OHOS::GSERROR_OK);
780        g_onBufferAvailable_--;
781    }
782
783    write(pipeFd[1], &data, sizeof(data));
784    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
785    read(pipeFd[0], &data, sizeof(data));
786    EXPECT_EQ(data, OHOS::GSERROR_OK);
787    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
788    g_onBufferAvailable_ = 0;
789    close(pipeFd[0]);
790    close(pipeFd[1]);
791    if (thread.joinable()) {
792        thread.join();
793    }
794    producer = nullptr;
795    cSurface = nullptr;
796}
797
798int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer007(sptr<IBufferProducer> producer,
799    NativeWindow **nativeWindow)
800{
801    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
802    *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
803    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
804
805    int32_t code = SET_BUFFER_GEOMETRY;
806    int32_t height = 0x100;
807    int32_t width = 0x100;
808    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
809    code = SET_FORMAT;
810    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
811    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
812
813    int32_t fenceFd = -1;
814    auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd);
815    if (ret != OHOS::GSERROR_OK) {
816        return ret;
817    }
818    SetData(nativeWindowBuffer, *nativeWindow);
819
820    struct Region *region = new Region();
821    struct Region::Rect *rect = new Region::Rect();
822    rect->w = 0x100;
823    rect->h = 0x100;
824    region->rects = rect;
825    region->rectNumber = 1;
826    ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region);
827    if (ret != OHOS::GSERROR_OK) {
828        delete rect;
829        delete region;
830        return ret;
831    }
832    delete rect;
833    delete region;
834    return OHOS::GSERROR_OK;
835}
836
837int32_t NativeWindowTest::ThreadNativeWindowProcess007(int32_t *pipeFd,
838    sptr<IBufferProducer> producer, uint64_t *uniqueId)
839{
840    int64_t data;
841    NativeWindow *nativeWindow = nullptr;
842    int32_t ret = CreateNativeWindowAndRequestBuffer007(producer, &nativeWindow);
843    if (ret != OHOS::GSERROR_OK) {
844        data = ret;
845        write(pipeFd[1], &data, sizeof(data));
846        return -1;
847    }
848    ret = OH_NativeWindow_GetSurfaceId(nativeWindow, uniqueId);
849    if (ret != OHOS::GSERROR_OK) {
850        data = ret;
851        write(pipeFd[1], &data, sizeof(data));
852        return -1;
853    }
854
855    data = ret;
856    write(pipeFd[1], &data, sizeof(data));
857    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
858    read(pipeFd[0], &data, sizeof(data));
859    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
860    return 0;
861}
862
863HWTEST_F(NativeWindowTest, OH_NativeWindow_GetSurfaceId001, Function | MediumTest | Level2)
864{
865    int32_t pipeFd[2] = {};
866    pipe(pipeFd);
867
868    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow002");
869    cSurface->RegisterConsumerListener(this);
870    auto producer = cSurface->GetProducer();
871    uint64_t cUniqueId = cSurface->GetUniqueId();
872
873    std::thread thread([this, pipeFd, producer, cUniqueId]() {
874        uint64_t uniqueId = 0;
875        int32_t ret = this->ThreadNativeWindowProcess007((int32_t*)(pipeFd), producer, &uniqueId);
876        EXPECT_EQ(ret, OHOS::GSERROR_OK);
877        EXPECT_EQ(uniqueId, cUniqueId);
878    });
879
880    int64_t data = 0;
881    read(pipeFd[0], &data, sizeof(data));
882    EXPECT_EQ(data, OHOS::GSERROR_OK);
883
884    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
885    int32_t fence = -1;
886    int64_t timestamp;
887    Rect damage;
888    auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
889    EXPECT_EQ(ret, OHOS::GSERROR_OK);
890    EXPECT_NE(buffer, nullptr);
891    EXPECT_EQ(GetData(buffer), true);
892
893    ret = cSurface->ReleaseBuffer(buffer, -1);
894    EXPECT_EQ(ret, OHOS::GSERROR_OK);
895
896    write(pipeFd[1], &data, sizeof(data));
897    close(pipeFd[0]);
898    close(pipeFd[1]);
899    if (thread.joinable()) {
900        thread.join();
901    }
902    producer = nullptr;
903    cSurface = nullptr;
904}
905
906int32_t NativeWindowTest::CreateNativeWindowAndAttachBuffer001(NativeWindow *nativeWindow)
907{
908    sptr<OnBufferAvailableTest> onBufferAvailableTest = new OnBufferAvailableTest();
909    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("CreateNativeWindowAndAttachBuffer001");
910    cSurface->RegisterConsumerListener(onBufferAvailableTest);
911    auto producer = cSurface->GetProducer();
912    cSurface->SetQueueSize(QUEUE_SIZE);
913    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
914    if (pSurface == nullptr) {
915        return -1;
916    }
917
918    NativeWindow *nativeWindowNew = OH_NativeWindow_CreateNativeWindow(&pSurface);
919    if (nativeWindowNew == nullptr) {
920        return -1;
921    }
922    int32_t code = SET_BUFFER_GEOMETRY;
923    int32_t height = 0x100;
924    int32_t width = 0x100;
925    OH_NativeWindow_NativeWindowHandleOpt(nativeWindowNew, code, height, width);
926    int32_t fenceFd = -1;
927    struct Region *region = new Region();
928    struct Region::Rect *rect = new Region::Rect();
929    rect->w = 0x100;
930    rect->h = 0x100;
931    region->rects = rect;
932    region->rectNumber = 1;
933    struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
934    int32_t ret;
935    for (int32_t i = 0; i < QUEUE_SIZE; i++) {
936        ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindowNew, &nativeWindowBuffer, &fenceFd);
937        if (ret != OHOS::GSERROR_OK) {
938            delete rect;
939            delete region;
940            return ret;
941        }
942        SetData(nativeWindowBuffer, nativeWindowNew);
943        ret = OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowNew, nativeWindowBuffer);
944        if (ret != OHOS::GSERROR_OK) {
945            delete rect;
946            delete region;
947            return ret;
948        }
949        ret = OH_NativeWindow_NativeWindowAttachBuffer(nativeWindow, nativeWindowBuffer);
950        if (ret != OHOS::GSERROR_OK) {
951            delete rect;
952            delete region;
953            return ret;
954        }
955        ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region);
956        if (ret != OHOS::GSERROR_OK) {
957            delete rect;
958            delete region;
959            return ret;
960        }
961    }
962    delete rect;
963    delete region;
964
965    OH_NativeWindow_DestroyNativeWindow(nativeWindowNew);
966    return OHOS::GSERROR_OK;
967}
968
969int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer008(uint64_t uniqueId, NativeWindow **nativeWindow)
970{
971    int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow);
972    if (ret != OHOS::GSERROR_OK) {
973        return ret;
974    }
975
976    int32_t code = SET_BUFFER_GEOMETRY;
977    int32_t height = 0x100;
978    int32_t width = 0x100;
979    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width);
980    code = SET_FORMAT;
981    int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
982    OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format);
983
984    return CreateNativeWindowAndAttachBuffer001(*nativeWindow);
985}
986
987int32_t NativeWindowTest::ThreadNativeWindowProcess008(int32_t *pipeFd, uint64_t uniqueId)
988{
989    int64_t data;
990    NativeWindow *nativeWindow = nullptr;
991    int32_t ret = CreateNativeWindowAndRequestBuffer008(uniqueId, &nativeWindow);
992    if (ret != OHOS::GSERROR_OK) {
993        data = ret;
994        write(pipeFd[1], &data, sizeof(data));
995        return -1;
996    }
997    ret = OH_NativeWindow_NativeObjectReference(nativeWindow);
998    if (ret != OHOS::GSERROR_OK) {
999        data = ret;
1000        write(pipeFd[1], &data, sizeof(data));
1001        return -1;
1002    }
1003    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
1004
1005    data = ret;
1006    write(pipeFd[1], &data, sizeof(data));
1007    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
1008    read(pipeFd[0], &data, sizeof(data));
1009    ret = RequestBuffer001(nativeWindow);
1010    if (ret != OHOS::GSERROR_OK) {
1011        data = ret;
1012        write(pipeFd[1], &data, sizeof(data));
1013        return -1;
1014    }
1015    data = ret;
1016    write(pipeFd[1], &data, sizeof(data));
1017    ret = OH_NativeWindow_NativeObjectUnreference(nativeWindow);
1018    if (ret != OHOS::GSERROR_OK) {
1019        return -1;
1020    }
1021    return 0;
1022}
1023
1024HWTEST_F(NativeWindowTest, OH_NativeWindow_NativeWindowAttachBuffer001, Function | MediumTest | Level2)
1025{
1026    int32_t pipeFd[2] = {};
1027    pipe(pipeFd);
1028
1029    sptr<OHOS::IConsumerSurface> cSurface = IConsumerSurface::Create("OH_NativeWindow_NativeWindowAttachBuffer001");
1030    cSurface->RegisterConsumerListener(this);
1031    auto producer = cSurface->GetProducer();
1032    sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
1033    EXPECT_NE(pSurface, nullptr);
1034    EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK);
1035
1036    uint64_t uniqueId = cSurface->GetUniqueId();
1037    std::thread thread([this, pipeFd, uniqueId]() {
1038        int32_t ret = this->ThreadNativeWindowProcess008((int32_t*)(pipeFd), uniqueId);
1039        EXPECT_EQ(ret, OHOS::GSERROR_OK);
1040    });
1041
1042    int64_t data = 0;
1043    read(pipeFd[0], &data, sizeof(data));
1044    EXPECT_EQ(data, OHOS::GSERROR_OK);
1045
1046    OHOS::sptr<SurfaceBuffer> buffer = nullptr;
1047    int32_t fence = -1;
1048    int64_t timestamp;
1049    Rect damage;
1050    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
1051    while (g_onBufferAvailable_ > 0) {
1052        auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage);
1053        EXPECT_EQ(ret, OHOS::GSERROR_OK);
1054        EXPECT_NE(buffer, nullptr);
1055        EXPECT_EQ(GetData(buffer), true);
1056
1057        ret = cSurface->ReleaseBuffer(buffer, -1);
1058        EXPECT_EQ(ret, OHOS::GSERROR_OK);
1059        g_onBufferAvailable_--;
1060    }
1061
1062    write(pipeFd[1], &data, sizeof(data));
1063    usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
1064    read(pipeFd[0], &data, sizeof(data));
1065    EXPECT_EQ(data, OHOS::GSERROR_OK);
1066    EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE);
1067    g_onBufferAvailable_ = 0;
1068    close(pipeFd[0]);
1069    close(pipeFd[1]);
1070    if (thread.joinable()) {
1071        thread.join();
1072    }
1073    producer = nullptr;
1074    cSurface = nullptr;
1075}
1076}
1077