blob: 553ee0be8e1e193f50ac2ec7ca88eb76fc354721 [file] [log] [blame]
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -07001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BufferHubBufferTest"
18
Fan Xuca70b7b2018-10-31 13:20:12 -070019#include <android/frameworks/bufferhub/1.0/IBufferClient.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070020#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
Fan Xu93c94902018-11-01 12:22:05 -070021#include <android/hardware_buffer.h>
Fan Xu467e08f2018-11-09 15:58:51 -080022#include <cutils/native_handle.h>
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070023#include <gtest/gtest.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070024#include <hidl/ServiceManagement.h>
25#include <hwbinder/IPCThreadState.h>
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070026#include <ui/BufferHubBuffer.h>
27
28namespace android {
29
30namespace {
31
32const int kWidth = 640;
33const int kHeight = 480;
34const int kLayerCount = 1;
35const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
36const int kUsage = 0;
37const size_t kUserMetadataSize = 0;
38
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070039using dvr::BufferHubDefs::IsBufferGained;
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070040using dvr::BufferHubDefs::kFirstClientBitMask;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070041using dvr::BufferHubDefs::kMetadataHeaderSize;
Fan Xuca70b7b2018-10-31 13:20:12 -070042using frameworks::bufferhub::V1_0::BufferHubStatus;
43using frameworks::bufferhub::V1_0::IBufferClient;
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070044using frameworks::bufferhub::V1_0::IBufferHub;
45using hardware::hidl_handle;
Fan Xu93c94902018-11-01 12:22:05 -070046using hardware::graphics::common::V1_2::HardwareBufferDescription;
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070047using hidl::base::V1_0::IBase;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070048using pdx::LocalChannelHandle;
49
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070050class BufferHubBufferTest : public ::testing::Test {
51 void SetUp() override { android::hardware::ProcessState::self()->startThreadPool(); }
52};
53
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070054TEST_F(BufferHubBufferTest, CreateBufferHubBufferFails) {
55 // Buffer Creation will fail: BLOB format requires height to be 1.
56 auto b1 = BufferHubBuffer::Create(kWidth, /*height=*/2, kLayerCount,
57 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize);
58
59 EXPECT_FALSE(b1->IsConnected());
60 EXPECT_FALSE(b1->IsValid());
61
62 // Buffer Creation will fail: user metadata size too large.
63 auto b2 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
64 /*userMetadataSize=*/std::numeric_limits<size_t>::max());
65
66 EXPECT_FALSE(b2->IsConnected());
67 EXPECT_FALSE(b2->IsValid());
68
69 // Buffer Creation will fail: user metadata size too large.
70 const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize;
71 auto b3 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
72 userMetadataSize);
73
74 EXPECT_FALSE(b3->IsConnected());
75 EXPECT_FALSE(b3->IsValid());
76}
77
78TEST_F(BufferHubBufferTest, CreateBufferHubBuffer) {
79 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
80 kUserMetadataSize);
81 EXPECT_TRUE(b1->IsConnected());
82 EXPECT_TRUE(b1->IsValid());
83 EXPECT_NE(b1->id(), 0);
84}
85
86TEST_F(BufferHubBufferTest, DuplicateBufferHubBuffer) {
87 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
88 kUserMetadataSize);
89 int id1 = b1->id();
Tianyu Jiang8f10b752018-10-30 17:24:51 -070090 uint64_t bufferStateMask1 = b1->client_state_mask();
91 EXPECT_NE(bufferStateMask1, 0ULL);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070092 EXPECT_TRUE(b1->IsValid());
93 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
94
95 auto statusOrHandle = b1->Duplicate();
96 EXPECT_TRUE(statusOrHandle);
97
98 // The detached buffer should still be valid.
99 EXPECT_TRUE(b1->IsConnected());
100 EXPECT_TRUE(b1->IsValid());
101
102 // Gets the channel handle for the duplicated buffer.
103 LocalChannelHandle h2 = statusOrHandle.take();
104 EXPECT_TRUE(h2.valid());
105
106 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
107 EXPECT_FALSE(h2.valid());
108 ASSERT_TRUE(b2 != nullptr);
109 EXPECT_TRUE(b2->IsValid());
110 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
111
112 int id2 = b2->id();
Tianyu Jiang8f10b752018-10-30 17:24:51 -0700113 uint64_t bufferStateMask2 = b2->client_state_mask();
114 EXPECT_NE(bufferStateMask2, 0ULL);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700115
116 // These two buffer instances are based on the same physical buffer under the
117 // hood, so they should share the same id.
118 EXPECT_EQ(id1, id2);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700119 // We use client_state_mask() to tell those two instances apart.
Tianyu Jiang8f10b752018-10-30 17:24:51 -0700120 EXPECT_NE(bufferStateMask1, bufferStateMask2);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700121
122 // Both buffer instances should be in gained state.
123 EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
124 EXPECT_TRUE(IsBufferGained(b2->buffer_state()));
125
126 // TODO(b/112338294): rewrite test after migration
127 return;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700128}
129
Fan Xu93c94902018-11-01 12:22:05 -0700130TEST_F(BufferHubBufferTest, AllocateBuffer) {
131 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
132 sp<IBufferHub> bufferHub = IBufferHub::getService();
133 ASSERT_NE(nullptr, bufferHub.get());
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700134
Fan Xu93c94902018-11-01 12:22:05 -0700135 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
136 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
137 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
138 HardwareBufferDescription desc;
139 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
140
141 IBufferHub::allocateBuffer_cb callback = [](const auto& client, const auto& status) {
142 EXPECT_EQ(status, BufferHubStatus::NO_ERROR);
143 EXPECT_NE(nullptr, client.get());
144 };
145 EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700146}
147
Fan Xu467e08f2018-11-09 15:58:51 -0800148TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
Fan Xu18d90ea2018-11-06 15:46:44 -0800149 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
150 sp<IBufferHub> bufferhub = IBufferHub::getService();
151 ASSERT_NE(nullptr, bufferhub.get());
152
153 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
154 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
155 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
156 HardwareBufferDescription desc;
157 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
158
159 sp<IBufferClient> client;
Fan Xuc32c1722018-11-16 14:38:29 -0800160 BufferHubStatus ret;
Fan Xu18d90ea2018-11-06 15:46:44 -0800161 IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
Fan Xu18d90ea2018-11-06 15:46:44 -0800162 client = outClient;
Fan Xuc32c1722018-11-16 14:38:29 -0800163 ret = status;
Fan Xu18d90ea2018-11-06 15:46:44 -0800164 };
165 ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
Fan Xuc32c1722018-11-16 14:38:29 -0800166 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
167 ASSERT_NE(nullptr, client.get());
Fan Xu18d90ea2018-11-06 15:46:44 -0800168
Fan Xuc32c1722018-11-16 14:38:29 -0800169 hidl_handle token;
170 IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
171 token = outToken;
172 ret = status;
Fan Xu18d90ea2018-11-06 15:46:44 -0800173 };
Fan Xu467e08f2018-11-09 15:58:51 -0800174 ASSERT_TRUE(client->duplicate(dup_cb).isOk());
Fan Xuc32c1722018-11-16 14:38:29 -0800175 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
176 ASSERT_NE(token.getNativeHandle(), nullptr);
177 EXPECT_EQ(token->numInts, 1);
178 EXPECT_EQ(token->numFds, 0);
Fan Xu467e08f2018-11-09 15:58:51 -0800179
180 sp<IBufferClient> client2;
181 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
182 ret = status;
183 client2 = outClient;
184 };
185 ASSERT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
186 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
187 EXPECT_NE(nullptr, client2.get());
188 // TODO(b/116681016): once BufferNode.id() is exposed via BufferHubBuffer, check origin.id =
189 // improted.id here.
190}
191
192// nullptr must not crash the service
193TEST_F(BufferHubBufferTest, ImportNullToken) {
194 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
195 sp<IBufferHub> bufferhub = IBufferHub::getService();
196 ASSERT_NE(nullptr, bufferhub.get());
197
198 hidl_handle nullToken;
199 sp<IBufferClient> client;
200 BufferHubStatus ret;
201 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
202 client = outClient;
203 ret = status;
204 };
205 ASSERT_TRUE(bufferhub->importBuffer(nullToken, import_cb).isOk());
206 EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
207 EXPECT_EQ(nullptr, client.get());
208}
209
210// This test has a very little chance to fail (number of existing tokens / 2 ^ 32)
211TEST_F(BufferHubBufferTest, ImportInvalidToken) {
212 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
213 sp<IBufferHub> bufferhub = IBufferHub::getService();
214 ASSERT_NE(nullptr, bufferhub.get());
215
216 native_handle_t* tokenHandle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
217 tokenHandle->data[0] = 0;
218
219 hidl_handle invalidToken(tokenHandle);
220 sp<IBufferClient> client;
221 BufferHubStatus ret;
222 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
223 client = outClient;
224 ret = status;
225 };
226 ASSERT_TRUE(bufferhub->importBuffer(invalidToken, import_cb).isOk());
227 EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
228 EXPECT_EQ(nullptr, client.get());
229
230 native_handle_delete(tokenHandle);
Fan Xu18d90ea2018-11-06 15:46:44 -0800231}
232
Fan Xuca70b7b2018-10-31 13:20:12 -0700233} // namespace
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700234} // namespace android