mirror of
https://github.com/openharmony/graphic_graphic_surface.git
synced 2026-08-25 11:29:33 -04:00
644658da77
Merge branch 'remote_dpy_0403' of gitee.com:ding-panyun/graphic_graphic_surface into local_dpy_0414 Signed-off-by: dingpanyun <dingpanyun1@huawei.com> Change-Id: Ic6bcbc9165c8de9aa3f799028023515c56b5950d
265 lines
8.3 KiB
C++
265 lines
8.3 KiB
C++
/*
|
|
* Copyright (c) 2021 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 <chrono>
|
|
#include <thread>
|
|
#include <unistd.h>
|
|
#include <gtest/gtest.h>
|
|
#include <iservice_registry.h>
|
|
#include <securec.h>
|
|
#include <native_window.h>
|
|
#include "accesstoken_kit.h"
|
|
#include "nativetoken_kit.h"
|
|
#include "token_setproc.h"
|
|
#include "external_window.h"
|
|
#include "iconsumer_surface.h"
|
|
|
|
using namespace testing;
|
|
using namespace testing::ext;
|
|
|
|
namespace OHOS::Rosen {
|
|
class NativeWindowBufferTest : public testing::Test, public IBufferConsumerListenerClazz {
|
|
public:
|
|
static void SetUpTestCase();
|
|
void OnBufferAvailable() override;
|
|
int32_t SetData(NativeWindowBuffer *nativeWindowBuffer, NativeWindow *nativeWindow);
|
|
bool GetData(sptr<SurfaceBuffer> &buffer);
|
|
pid_t ChildProcessMain();
|
|
int32_t InitNativeWindowAndBuffer(sptr<IRemoteObject> robj);
|
|
|
|
static inline sptr<OHOS::IConsumerSurface> cSurface = nullptr;
|
|
static inline int32_t pipeMain[2] = {};
|
|
static inline int32_t pipeChild[2] = {};
|
|
static inline int32_t ipcSystemAbilityID = 34156;
|
|
};
|
|
|
|
void NativeWindowBufferTest::SetUpTestCase() {}
|
|
|
|
void NativeWindowBufferTest::OnBufferAvailable() {}
|
|
|
|
int32_t NativeWindowBufferTest::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");
|
|
|
|
// alloc OHExtDataHandle
|
|
uint32_t reserveInts = 1;
|
|
size_t handleSize = sizeof(OHExtDataHandle) + (sizeof(int32_t) * reserveInts);
|
|
OHExtDataHandle *handle = static_cast<OHExtDataHandle *>(malloc(handleSize));
|
|
if (handle == nullptr) {
|
|
return -1;
|
|
}
|
|
int32_t ret = memset_s(handle, handleSize, 0, handleSize);
|
|
if (ret != EOK) {
|
|
free(handle);
|
|
return -1;
|
|
}
|
|
handle->fd = -1;
|
|
handle->reserveInts = reserveInts;
|
|
for (uint32_t i = 0; i < reserveInts; i++) {
|
|
handle->reserve[i] = 1;
|
|
}
|
|
|
|
ret = OH_NativeWindow_NativeWindowSetTunnelHandle(nativeWindow, handle);
|
|
// free OHExtDataHandle
|
|
if (handle->fd >= 0) {
|
|
close(handle->fd);
|
|
handle->fd = -1;
|
|
}
|
|
free(handle);
|
|
handle = nullptr;
|
|
return ret;
|
|
}
|
|
|
|
bool NativeWindowBufferTest::GetData(sptr<SurfaceBuffer> &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;
|
|
}
|
|
|
|
sptr<SurfaceTunnelHandle> handleGet = nullptr;
|
|
handleGet = cSurface->GetTunnelHandle();
|
|
if ((handleGet == nullptr) || (handleGet->GetHandle()->fd != -1) ||
|
|
(handleGet->GetHandle()->reserveInts != 1) || (handleGet->GetHandle()->reserve[0] != 1)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int32_t NativeWindowBufferTest::InitNativeWindowAndBuffer(sptr<IRemoteObject> robj)
|
|
{
|
|
auto producer = iface_cast<IBufferProducer>(robj);
|
|
sptr<Surface> pSurface = Surface::CreateSurfaceAsProducer(producer);
|
|
|
|
struct NativeWindow *nativeWindow = OH_NativeWindow_CreateNativeWindow(&pSurface);
|
|
struct NativeWindowBuffer *nativeWindowBuffer = nullptr;
|
|
|
|
int code = SET_USAGE;
|
|
uint64_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
|
|
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage);
|
|
|
|
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);
|
|
|
|
code = SET_STRIDE;
|
|
int32_t stride = 0x8;
|
|
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
|
|
|
|
int32_t fenceFd = -1;
|
|
auto ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
|
|
if (ret != OHOS::GSERROR_OK) {
|
|
return ret;
|
|
}
|
|
ret = SetData(nativeWindowBuffer, nativeWindow);
|
|
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;
|
|
}
|
|
|
|
pid_t NativeWindowBufferTest::ChildProcessMain()
|
|
{
|
|
pipe(pipeMain);
|
|
pipe(pipeChild);
|
|
pid_t pid = fork();
|
|
if (pid != 0) {
|
|
return pid;
|
|
}
|
|
|
|
int64_t data;
|
|
read(pipeMain[0], &data, sizeof(data));
|
|
|
|
sptr<IRemoteObject> robj = nullptr;
|
|
while (true) {
|
|
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
|
|
robj = sam->GetSystemAbility(ipcSystemAbilityID);
|
|
if (robj != nullptr) {
|
|
break;
|
|
}
|
|
sleep(0);
|
|
}
|
|
int32_t ret = InitNativeWindowAndBuffer(robj);
|
|
if (ret != OHOS::GSERROR_OK) {
|
|
data = ret;
|
|
write(pipeChild[1], &data, sizeof(data));
|
|
exit(0);
|
|
return -1;
|
|
}
|
|
|
|
data = ret;
|
|
write(pipeChild[1], &data, sizeof(data));
|
|
usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
|
|
read(pipeMain[0], &data, sizeof(data));
|
|
close(pipeMain[0]);
|
|
close(pipeMain[1]);
|
|
close(pipeChild[0]);
|
|
close(pipeChild[1]);
|
|
exit(0);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Function: produce and consumer surface of nativewindow
|
|
* Type: Function
|
|
* Rank: Important(2)
|
|
* EnvConditions: N/A
|
|
* CaseDescription: 1. produce surface by nativewindow interface, fill buffer
|
|
* 2. consume surface and check buffer
|
|
* @tc.require: issueI5GMZN issueI5IWHW
|
|
*/
|
|
HWTEST_F(NativeWindowBufferTest, Surface001, TestSize.Level0)
|
|
{
|
|
auto pid = ChildProcessMain();
|
|
ASSERT_GE(pid, 0);
|
|
|
|
uint64_t tokenId;
|
|
const char *perms[2];
|
|
perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
|
|
perms[1] = "ohos.permission.CAMERA";
|
|
NativeTokenInfoParams infoInstance = {
|
|
.dcapsNum = 0,
|
|
.permsNum = 2,
|
|
.aclsNum = 0,
|
|
.dcaps = NULL,
|
|
.perms = perms,
|
|
.acls = NULL,
|
|
.processName = "dcamera_client_demo",
|
|
.aplStr = "system_basic",
|
|
};
|
|
tokenId = GetAccessTokenId(&infoInstance);
|
|
SetSelfTokenID(tokenId);
|
|
int32_t rett = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
|
|
ASSERT_EQ(rett, Security::AccessToken::RET_SUCCESS);
|
|
|
|
cSurface = IConsumerSurface::Create("test");
|
|
cSurface->RegisterConsumerListener(this);
|
|
auto producer = cSurface->GetProducer();
|
|
auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
|
|
sam->AddSystemAbility(ipcSystemAbilityID, producer->AsObject());
|
|
|
|
int64_t data = 0;
|
|
write(pipeMain[1], &data, sizeof(data));
|
|
usleep(1000); // sleep 1000 microseconds (equals 1 milliseconds)
|
|
read(pipeChild[0], &data, sizeof(data));
|
|
EXPECT_EQ(data, OHOS::GSERROR_OK);
|
|
|
|
OHOS::sptr<SurfaceBuffer> 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(pipeMain[1], &data, sizeof(data));
|
|
close(pipeMain[0]);
|
|
close(pipeMain[1]);
|
|
close(pipeChild[0]);
|
|
close(pipeChild[1]);
|
|
sam->RemoveSystemAbility(ipcSystemAbilityID);
|
|
waitpid(pid, nullptr, 0);
|
|
}
|
|
} |