/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "external_window.h" #include "iconsumer_surface.h" #include "event_handler.h" using namespace testing; using namespace testing::ext; namespace OHOS::Rosen { constexpr uint32_t QUEUE_SIZE = 5; class NativeWindowTest : public testing::Test, public IBufferConsumerListenerClazz { public: static void SetUpTestCase(); void OnBufferAvailable() override; void SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow); bool GetData(sptr &buffer); // OH_NativeWindow_CreateNativeWindow001 int32_t ThreadNativeWindowProcess001(int32_t *pipeFd, sptr producer); int32_t CreateNativeWindowAndRequestBuffer001(sptr producer, NativeWindow **nativeWindow); // OH_NativeWindow_CreateNativeWindow002 int32_t ThreadNativeWindowProcess002(int32_t *pipeFd, sptr producer); int32_t CreateNativeWindowAndRequestBuffer002(sptr producer, NativeWindow **nativeWindow); // OH_NativeWindow_CreateNativeWindowFromSurfaceId001 int32_t ThreadNativeWindowProcess003(int32_t *pipeFd, uint64_t uniqueId); int32_t CreateNativeWindowAndRequestBuffer003(uint64_t uniqueId, NativeWindow **nativeWindow); // OH_NativeWindow_CreateNativeWindowFromSurfaceId002 int32_t ThreadNativeWindowProcess004(int32_t *pipeFd, uint64_t uniqueId); int32_t CreateNativeWindowAndRequestBuffer004(uint64_t uniqueId, NativeWindow **nativeWindow); int32_t RequestBuffer001(NativeWindow *nativeWindow); // OH_NativeWindow_GetLastFlushedBufferV2001 int32_t ThreadNativeWindowProcess005(int32_t *pipeFd, uint64_t uniqueId); int32_t CreateNativeWindowAndRequestBuffer005(uint64_t uniqueId, NativeWindow **nativeWindow); // OH_NativeWindow_NativeObjectReference001 int32_t ThreadNativeWindowProcess006(int32_t *pipeFd, uint64_t uniqueId); // OH_NativeWindow_GetSurfaceId001 int32_t ThreadNativeWindowProcess007(int32_t *pipeFd, sptr producer, uint64_t *uniqueId); int32_t CreateNativeWindowAndRequestBuffer007(sptr producer, NativeWindow **nativeWindow); // OH_NativeWindow_NativeWindowAttachBuffer001 int32_t ThreadNativeWindowProcess008(int32_t *pipeFd, uint64_t uniqueId); int32_t CreateNativeWindowAndRequestBuffer008(uint64_t uniqueId, NativeWindow **nativeWindow); int32_t CreateNativeWindowAndAttachBuffer001(NativeWindow *nativeWindow); int32_t g_onBufferAvailable_ = 0; }; class OnBufferAvailableTest : public IBufferConsumerListenerClazz, public RefBase { public: void OnBufferAvailable() override; }; void OnBufferAvailableTest::OnBufferAvailable() {}; void NativeWindowTest::SetUpTestCase() {} void NativeWindowTest::OnBufferAvailable() { g_onBufferAvailable_++; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer001(sptr producer, NativeWindow **nativeWindow) { sptr pSurface = Surface::CreateSurfaceAsProducer(producer); *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface); struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); int32_t fenceFd = -1; auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { return ret; } struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess001(int32_t *pipeFd, sptr producer) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer001(producer, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindow001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow001"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); std::thread thread([this, pipeFd, producer]() { int32_t ret = this->ThreadNativeWindowProcess001((int32_t*)(pipeFd), producer); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); write(pipeFd[1], &data, sizeof(data)); close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } void NativeWindowTest::SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow) { nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("123", 0x123); nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("345", (int64_t)0x345); nativeWindowBuffer->sfbuffer->GetExtraData()->ExtraSet("567", "567"); } bool NativeWindowTest::GetData(sptr &buffer) { int32_t int32; int64_t int64; std::string str; buffer->GetExtraData()->ExtraGet("123", int32); buffer->GetExtraData()->ExtraGet("345", int64); buffer->GetExtraData()->ExtraGet("567", str); if ((int32 != 0x123) || (int64 != 0x345) || (str != "567")) { return false; } return true; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer002(sptr producer, NativeWindow **nativeWindow) { sptr pSurface = Surface::CreateSurfaceAsProducer(producer); *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface); struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); int32_t fenceFd = -1; auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { return ret; } SetData(nativeWindowBuffer, *nativeWindow); struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess002(int32_t *pipeFd, sptr producer) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer002(producer, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindow002, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow002"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); std::thread thread([this, pipeFd, producer]() { int32_t ret = this->ThreadNativeWindowProcess002((int32_t*)(pipeFd), producer); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); write(pipeFd[1], &data, sizeof(data)); close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer003(uint64_t uniqueId, NativeWindow **nativeWindow) { int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow); if (ret != OHOS::GSERROR_OK) { return ret; } struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); int32_t fenceFd = -1; struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; for (int32_t i = 0; i < QUEUE_SIZE; i++) { ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } SetData(nativeWindowBuffer, *nativeWindow); ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess003(int32_t *pipeFd, uint64_t uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer003(uniqueId, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindowFromSurfaceId001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindowFromSurfaceId001"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); EXPECT_NE(pSurface, nullptr); EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK); uint64_t uniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, uniqueId]() { int32_t ret = this->ThreadNativeWindowProcess003((int32_t*)(pipeFd), uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); while (g_onBufferAvailable_ > 0) { auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); g_onBufferAvailable_--; } g_onBufferAvailable_ = 0; write(pipeFd[1], &data, sizeof(data)); close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::RequestBuffer001(NativeWindow *nativeWindow) { int32_t fenceFd = -1; struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t ret; for (int32_t i = 0; i < QUEUE_SIZE; i++) { ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } SetData(nativeWindowBuffer, nativeWindow); ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer004(uint64_t uniqueId, NativeWindow **nativeWindow) { int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow); if (ret != OHOS::GSERROR_OK) { return ret; } struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); int32_t fenceFd = -1; struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; for (int32_t i = 0; i < QUEUE_SIZE; i++) { ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } SetData(nativeWindowBuffer, *nativeWindow); ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess004(int32_t *pipeFd, uint64_t uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer004(uniqueId, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); ret = RequestBuffer001(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_CreateNativeWindowFromSurfaceId002, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindowFromSurfaceId002"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); EXPECT_NE(pSurface, nullptr); EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK); uint64_t uniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, uniqueId]() { int32_t ret = this->ThreadNativeWindowProcess004((int32_t*)(pipeFd), uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); while (g_onBufferAvailable_ > 0) { auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); g_onBufferAvailable_--; } write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); g_onBufferAvailable_ = 0; close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer005(uint64_t uniqueId, NativeWindow **nativeWindow) { int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow); if (ret != OHOS::GSERROR_OK) { return ret; } struct NativeWindowBuffer *nativeWindowBuffer = nullptr; struct NativeWindowBuffer *lastNativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); int32_t fenceFd = -1; struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; float matrix[16] = {0}; for (int32_t i = 0; i < QUEUE_SIZE; i++) { ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } SetData(nativeWindowBuffer, *nativeWindow); ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } ret = OH_NativeWindow_GetLastFlushedBufferV2(*nativeWindow, &lastNativeWindowBuffer, &fenceFd, matrix); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } if (!GetData(lastNativeWindowBuffer->sfbuffer)) { delete rect; delete region; return -1; } } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess005(int32_t *pipeFd, uint64_t uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer005(uniqueId, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); ret = RequestBuffer001(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_GetLastFlushedBufferV2001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_GetLastFlushedBufferV2001"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); EXPECT_NE(pSurface, nullptr); EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK); uint64_t uniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, uniqueId]() { int32_t ret = this->ThreadNativeWindowProcess005((int32_t*)(pipeFd), uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); while (g_onBufferAvailable_ > 0) { auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); g_onBufferAvailable_--; } write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); g_onBufferAvailable_ = 0; close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::ThreadNativeWindowProcess006(int32_t *pipeFd, uint64_t uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer005(uniqueId, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } ret = OH_NativeWindow_NativeObjectReference(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } OH_NativeWindow_DestroyNativeWindow(nativeWindow); data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); ret = RequestBuffer001(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); ret = OH_NativeWindow_NativeObjectUnreference(nativeWindow); if (ret != OHOS::GSERROR_OK) { return -1; } return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_NativeObjectReference001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_NativeObjectReference001"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); EXPECT_NE(pSurface, nullptr); EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK); uint64_t uniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, uniqueId]() { int32_t ret = this->ThreadNativeWindowProcess006((int32_t*)(pipeFd), uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); while (g_onBufferAvailable_ > 0) { auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); g_onBufferAvailable_--; } write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); g_onBufferAvailable_ = 0; close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer007(sptr producer, NativeWindow **nativeWindow) { sptr pSurface = Surface::CreateSurfaceAsProducer(producer); *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface); struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); int32_t fenceFd = -1; auto ret = OH_NativeWindow_NativeWindowRequestBuffer(*nativeWindow, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { return ret; } SetData(nativeWindowBuffer, *nativeWindow); struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; ret = OH_NativeWindow_NativeWindowFlushBuffer(*nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } delete rect; delete region; return OHOS::GSERROR_OK; } int32_t NativeWindowTest::ThreadNativeWindowProcess007(int32_t *pipeFd, sptr producer, uint64_t *uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer007(producer, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } ret = OH_NativeWindow_GetSurfaceId(nativeWindow, uniqueId); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); OH_NativeWindow_DestroyNativeWindow(nativeWindow); return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_GetSurfaceId001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_CreateNativeWindow002"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); uint64_t cUniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, producer, cUniqueId]() { uint64_t uniqueId = 0; int32_t ret = this->ThreadNativeWindowProcess007((int32_t*)(pipeFd), producer, &uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_EQ(uniqueId, cUniqueId); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); write(pipeFd[1], &data, sizeof(data)); close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } int32_t NativeWindowTest::CreateNativeWindowAndAttachBuffer001(NativeWindow *nativeWindow) { sptr onBufferAvailableTest = new OnBufferAvailableTest(); sptr cSurface = IConsumerSurface::Create("CreateNativeWindowAndAttachBuffer001"); cSurface->RegisterConsumerListener(onBufferAvailableTest); auto producer = cSurface->GetProducer(); cSurface->SetQueueSize(QUEUE_SIZE); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); if (pSurface == nullptr) { return -1; } NativeWindow *nativeWindowNew = OH_NativeWindow_CreateNativeWindow(&pSurface); if (nativeWindowNew == nullptr) { return -1; } int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(nativeWindowNew, code, height, width); int32_t fenceFd = -1; struct Region *region = new Region(); struct Region::Rect *rect = new Region::Rect(); rect->w = 0x100; rect->h = 0x100; region->rects = rect; region->rectNumber = 1; struct NativeWindowBuffer *nativeWindowBuffer = nullptr; int32_t ret; for (int32_t i = 0; i < QUEUE_SIZE; i++) { ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindowNew, &nativeWindowBuffer, &fenceFd); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } SetData(nativeWindowBuffer, nativeWindowNew); ret = OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowNew, nativeWindowBuffer); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } ret = OH_NativeWindow_NativeWindowAttachBuffer(nativeWindow, nativeWindowBuffer); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, -1, *region); if (ret != OHOS::GSERROR_OK) { delete rect; delete region; return ret; } } delete rect; delete region; OH_NativeWindow_DestroyNativeWindow(nativeWindowNew); return OHOS::GSERROR_OK; } int32_t NativeWindowTest::CreateNativeWindowAndRequestBuffer008(uint64_t uniqueId, NativeWindow **nativeWindow) { int32_t ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(uniqueId, nativeWindow); if (ret != OHOS::GSERROR_OK) { return ret; } int32_t code = SET_BUFFER_GEOMETRY; int32_t height = 0x100; int32_t width = 0x100; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, height, width); code = SET_FORMAT; int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888; OH_NativeWindow_NativeWindowHandleOpt(*nativeWindow, code, format); return CreateNativeWindowAndAttachBuffer001(*nativeWindow); } int32_t NativeWindowTest::ThreadNativeWindowProcess008(int32_t *pipeFd, uint64_t uniqueId) { int64_t data; NativeWindow *nativeWindow = nullptr; int32_t ret = CreateNativeWindowAndRequestBuffer008(uniqueId, &nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } ret = OH_NativeWindow_NativeObjectReference(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } OH_NativeWindow_DestroyNativeWindow(nativeWindow); data = ret; write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); ret = RequestBuffer001(nativeWindow); if (ret != OHOS::GSERROR_OK) { data = ret; write(pipeFd[1], &data, sizeof(data)); return -1; } data = ret; write(pipeFd[1], &data, sizeof(data)); ret = OH_NativeWindow_NativeObjectUnreference(nativeWindow); if (ret != OHOS::GSERROR_OK) { return -1; } return 0; } HWTEST_F(NativeWindowTest, OH_NativeWindow_NativeWindowAttachBuffer001, Function | MediumTest | Level2) { int32_t pipeFd[2] = {}; pipe(pipeFd); sptr cSurface = IConsumerSurface::Create("OH_NativeWindow_NativeWindowAttachBuffer001"); cSurface->RegisterConsumerListener(this); auto producer = cSurface->GetProducer(); sptr pSurface = Surface::CreateSurfaceAsProducer(producer); EXPECT_NE(pSurface, nullptr); EXPECT_EQ(cSurface->SetQueueSize(QUEUE_SIZE), OHOS::GSERROR_OK); uint64_t uniqueId = cSurface->GetUniqueId(); std::thread thread([this, pipeFd, uniqueId]() { int32_t ret = this->ThreadNativeWindowProcess008((int32_t*)(pipeFd), uniqueId); EXPECT_EQ(ret, OHOS::GSERROR_OK); }); int64_t data = 0; read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); OHOS::sptr buffer = nullptr; int32_t fence = -1; int64_t timestamp; Rect damage; EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); while (g_onBufferAvailable_ > 0) { auto ret = cSurface->AcquireBuffer(buffer, fence, timestamp, damage); EXPECT_EQ(ret, OHOS::GSERROR_OK); EXPECT_NE(buffer, nullptr); EXPECT_EQ(GetData(buffer), true); ret = cSurface->ReleaseBuffer(buffer, -1); EXPECT_EQ(ret, OHOS::GSERROR_OK); g_onBufferAvailable_--; } write(pipeFd[1], &data, sizeof(data)); usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds) read(pipeFd[0], &data, sizeof(data)); EXPECT_EQ(data, OHOS::GSERROR_OK); EXPECT_EQ(g_onBufferAvailable_, QUEUE_SIZE); g_onBufferAvailable_ = 0; close(pipeFd[0]); close(pipeFd[1]); if (thread.joinable()) { thread.join(); } producer = nullptr; cSurface = nullptr; } }