1 #include <gtest/gtest.h>
2 #include <poll.h>
3 #include <private/dvr/bufferhub_rpc.h>
4 #include <private/dvr/consumer_buffer.h>
5 #include <private/dvr/producer_buffer.h>
6 #include <sys/epoll.h>
7 #include <sys/eventfd.h>
8 #include <ui/BufferHubDefs.h>
9
10 #include <mutex>
11 #include <thread>
12
13 namespace {
14 #define RETRY_EINTR(fnc_call) \
15 ([&]() -> decltype(fnc_call) { \
16 decltype(fnc_call) result; \
17 do { \
18 result = (fnc_call); \
19 } while (result == -1 && errno == EINTR); \
20 return result; \
21 })()
22
23 using android::BufferHubDefs::isAnyClientAcquired;
24 using android::BufferHubDefs::isAnyClientGained;
25 using android::BufferHubDefs::isAnyClientPosted;
26 using android::BufferHubDefs::isClientAcquired;
27 using android::BufferHubDefs::isClientPosted;
28 using android::BufferHubDefs::isClientReleased;
29 using android::BufferHubDefs::kFirstClientBitMask;
30 using android::dvr::ConsumerBuffer;
31 using android::dvr::ProducerBuffer;
32 using android::pdx::LocalHandle;
33 using android::pdx::Status;
34 using LibBufferHubTest = ::testing::Test;
35
36 const int kWidth = 640;
37 const int kHeight = 480;
38 const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
39 const int kUsage = 0;
40 // Maximum number of consumers for the buffer that only has one producer in the
41 // test.
42 const size_t kMaxConsumerCount =
43 android::BufferHubDefs::kMaxNumberOfClients - 1;
44 const int kPollTimeoutMs = 100;
45
46 // Helper function to poll the eventfd in BufferHubBase.
47 template <class BufferHubBase>
PollBufferEvent(const std::unique_ptr<BufferHubBase> & buffer,int timeout_ms=kPollTimeoutMs)48 int PollBufferEvent(const std::unique_ptr<BufferHubBase>& buffer,
49 int timeout_ms = kPollTimeoutMs) {
50 pollfd p = {buffer->event_fd(), POLLIN, 0};
51 return poll(&p, 1, timeout_ms);
52 }
53
54 } // namespace
55
TEST_F(LibBufferHubTest,TestBasicUsage)56 TEST_F(LibBufferHubTest, TestBasicUsage) {
57 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
58 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
59 ASSERT_TRUE(p.get() != nullptr);
60 std::unique_ptr<ConsumerBuffer> c1 =
61 ConsumerBuffer::Import(p->CreateConsumer());
62 ASSERT_TRUE(c1.get() != nullptr);
63 // Check that consumers can spawn other consumers.
64 std::unique_ptr<ConsumerBuffer> c2 =
65 ConsumerBuffer::Import(c1->CreateConsumer());
66 ASSERT_TRUE(c2.get() != nullptr);
67
68 // Checks the state masks of client p, c1 and c2.
69 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
70 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
71 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
72
73 // Initial state: producer not available, consumers not available.
74 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
75 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
76 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
77
78 EXPECT_EQ(0, p->GainAsync());
79 EXPECT_EQ(0, p->Post(LocalHandle()));
80
81 // New state: producer not available, consumers available.
82 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
83 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c1)));
84 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
85
86 LocalHandle fence;
87 EXPECT_EQ(0, c1->Acquire(&fence));
88 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
89 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
90
91 EXPECT_EQ(0, c2->Acquire(&fence));
92 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
93 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
94
95 EXPECT_EQ(0, c1->Release(LocalHandle()));
96 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
97 EXPECT_EQ(0, c2->Discard());
98 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(p)));
99
100 EXPECT_EQ(0, p->Gain(&fence));
101 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
102 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
103 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
104 }
105
TEST_F(LibBufferHubTest,TestEpoll)106 TEST_F(LibBufferHubTest, TestEpoll) {
107 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
108 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
109 ASSERT_TRUE(p.get() != nullptr);
110 std::unique_ptr<ConsumerBuffer> c =
111 ConsumerBuffer::Import(p->CreateConsumer());
112 ASSERT_TRUE(c.get() != nullptr);
113
114 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
115 ASSERT_TRUE(epoll_fd.IsValid());
116
117 epoll_event event;
118 std::array<epoll_event, 64> events;
119
120 auto event_sources = p->GetEventSources();
121 ASSERT_LT(event_sources.size(), events.size());
122
123 for (const auto& event_source : event_sources) {
124 event = {.events = event_source.event_mask | EPOLLET,
125 .data = {.fd = p->event_fd()}};
126 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
127 &event));
128 }
129
130 event_sources = c->GetEventSources();
131 ASSERT_LT(event_sources.size(), events.size());
132
133 for (const auto& event_source : event_sources) {
134 event = {.events = event_source.event_mask | EPOLLET,
135 .data = {.fd = c->event_fd()}};
136 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
137 &event));
138 }
139
140 // No events should be signaled initially.
141 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
142
143 // Gain and post the producer and check for consumer signal.
144 EXPECT_EQ(0, p->GainAsync());
145 EXPECT_EQ(0, p->Post({}));
146 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
147 kPollTimeoutMs));
148 ASSERT_TRUE(events[0].events & EPOLLIN);
149 ASSERT_EQ(c->event_fd(), events[0].data.fd);
150
151 // Save the event bits to translate later.
152 event = events[0];
153
154 // Check for events again. Edge-triggered mode should prevent any.
155 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
156 kPollTimeoutMs));
157 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
158 kPollTimeoutMs));
159 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
160 kPollTimeoutMs));
161 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
162 kPollTimeoutMs));
163
164 // Translate the events.
165 auto event_status = c->GetEventMask(event.events);
166 ASSERT_TRUE(event_status);
167 ASSERT_TRUE(event_status.get() & EPOLLIN);
168
169 // Check for events again. Edge-triggered mode should prevent any.
170 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
171 kPollTimeoutMs));
172 }
173
TEST_F(LibBufferHubTest,TestStateMask)174 TEST_F(LibBufferHubTest, TestStateMask) {
175 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
176 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
177 ASSERT_TRUE(p.get() != nullptr);
178
179 // It's ok to create up to kMaxConsumerCount consumer buffers.
180 uint32_t client_state_masks = p->client_state_mask();
181 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
182 for (size_t i = 0; i < kMaxConsumerCount; i++) {
183 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
184 ASSERT_TRUE(cs[i].get() != nullptr);
185 // Expect all buffers have unique state mask.
186 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
187 client_state_masks |= cs[i]->client_state_mask();
188 }
189 EXPECT_EQ(client_state_masks, ~0U);
190
191 // The 64th creation will fail with out-of-memory error.
192 auto state = p->CreateConsumer();
193 EXPECT_EQ(state.error(), E2BIG);
194
195 // Release any consumer should allow us to re-create.
196 for (size_t i = 0; i < kMaxConsumerCount; i++) {
197 client_state_masks &= ~cs[i]->client_state_mask();
198 cs[i] = nullptr;
199 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
200 ASSERT_TRUE(cs[i].get() != nullptr);
201 // The released state mask will be reused.
202 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
203 client_state_masks |= cs[i]->client_state_mask();
204 }
205 }
206
TEST_F(LibBufferHubTest,TestStateTransitions)207 TEST_F(LibBufferHubTest, TestStateTransitions) {
208 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
209 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
210 ASSERT_TRUE(p.get() != nullptr);
211 std::unique_ptr<ConsumerBuffer> c =
212 ConsumerBuffer::Import(p->CreateConsumer());
213 ASSERT_TRUE(c.get() != nullptr);
214
215 LocalHandle fence;
216 EXPECT_EQ(0, p->GainAsync());
217
218 // Acquire in gained state should fail.
219 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
220
221 // Post in gained state should succeed.
222 EXPECT_EQ(0, p->Post(LocalHandle()));
223
224 // Post and gain in posted state should fail.
225 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
226 EXPECT_EQ(-EBUSY, p->Gain(&fence));
227
228 // Acquire in posted state should succeed.
229 EXPECT_EQ(0, c->Acquire(&fence));
230
231 // Acquire, post, and gain in acquired state should fail.
232 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
233 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
234 EXPECT_EQ(-EBUSY, p->Gain(&fence));
235
236 // Release in acquired state should succeed.
237 EXPECT_EQ(0, c->Release(LocalHandle()));
238 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
239
240 // Acquire and post in released state should fail.
241 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
242 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
243
244 // Gain in released state should succeed.
245 EXPECT_EQ(0, p->Gain(&fence));
246
247 // Acquire in gained state should fail.
248 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
249 }
250
TEST_F(LibBufferHubTest,TestAsyncStateTransitions)251 TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
252 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
253 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
254 ASSERT_TRUE(p.get() != nullptr);
255 std::unique_ptr<ConsumerBuffer> c =
256 ConsumerBuffer::Import(p->CreateConsumer());
257 ASSERT_TRUE(c.get() != nullptr);
258
259 DvrNativeBufferMetadata metadata;
260 LocalHandle invalid_fence;
261 EXPECT_EQ(0, p->GainAsync());
262
263 // Acquire in gained state should fail.
264 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
265 EXPECT_FALSE(invalid_fence.IsValid());
266 EXPECT_FALSE(invalid_fence.IsValid());
267
268 // Post in gained state should succeed.
269 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
270 EXPECT_EQ(p->buffer_state(), c->buffer_state());
271 EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
272
273 // Post and gain in posted state should fail.
274 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
275 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
276 EXPECT_FALSE(invalid_fence.IsValid());
277
278 // Acquire in posted state should succeed.
279 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
280 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
281 EXPECT_FALSE(invalid_fence.IsValid());
282 EXPECT_EQ(p->buffer_state(), c->buffer_state());
283 EXPECT_TRUE(isAnyClientAcquired(p->buffer_state()));
284
285 // Acquire, post, and gain in acquired state should fail.
286 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
287 EXPECT_FALSE(invalid_fence.IsValid());
288 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
289 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
290 EXPECT_FALSE(invalid_fence.IsValid());
291
292 // Release in acquired state should succeed.
293 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
294 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
295 EXPECT_EQ(p->buffer_state(), c->buffer_state());
296 EXPECT_TRUE(p->is_released());
297
298 // Acquire and post in released state should fail.
299 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
300 EXPECT_FALSE(invalid_fence.IsValid());
301 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
302
303 // Gain in released state should succeed.
304 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
305 EXPECT_FALSE(invalid_fence.IsValid());
306 EXPECT_EQ(p->buffer_state(), c->buffer_state());
307 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
308
309 // Acquire and gain in gained state should fail.
310 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
311 EXPECT_FALSE(invalid_fence.IsValid());
312 }
313
TEST_F(LibBufferHubTest,TestGainTwiceByTheSameProducer)314 TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
315 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
316 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
317 ASSERT_TRUE(p.get() != nullptr);
318
319 ASSERT_EQ(0, p->GainAsync());
320 ASSERT_EQ(0, p->GainAsync());
321 }
322
TEST_F(LibBufferHubTest,TestGainPostedBuffer)323 TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
324 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
325 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
326 ASSERT_TRUE(p.get() != nullptr);
327 std::unique_ptr<ConsumerBuffer> c =
328 ConsumerBuffer::Import(p->CreateConsumer());
329 ASSERT_TRUE(c.get() != nullptr);
330 ASSERT_EQ(0, p->GainAsync());
331 ASSERT_EQ(0, p->Post(LocalHandle()));
332 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
333
334 // Gain in posted state should only succeed with gain_posted_buffer = true.
335 LocalHandle invalid_fence;
336 EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
337 EXPECT_EQ(0, p->Gain(&invalid_fence, true));
338 }
339
TEST_F(LibBufferHubTest,TestGainPostedBufferAsync)340 TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
341 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
342 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
343 ASSERT_TRUE(p.get() != nullptr);
344 std::unique_ptr<ConsumerBuffer> c =
345 ConsumerBuffer::Import(p->CreateConsumer());
346 ASSERT_TRUE(c.get() != nullptr);
347 ASSERT_EQ(0, p->GainAsync());
348 ASSERT_EQ(0, p->Post(LocalHandle()));
349 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
350
351 // GainAsync in posted state should only succeed with gain_posted_buffer
352 // equals true.
353 DvrNativeBufferMetadata metadata;
354 LocalHandle invalid_fence;
355 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
356 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
357 }
358
TEST_F(LibBufferHubTest,TestGainPostedBuffer_noConsumer)359 TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
360 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
361 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
362 ASSERT_TRUE(p.get() != nullptr);
363 ASSERT_EQ(0, p->GainAsync());
364 ASSERT_EQ(0, p->Post(LocalHandle()));
365 // Producer state bit is in released state after post, other clients shall be
366 // in posted state although there is no consumer of this buffer yet.
367 ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
368 ASSERT_TRUE(p->is_released());
369 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
370
371 // Gain in released state should succeed.
372 LocalHandle invalid_fence;
373 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
374 }
375
TEST_F(LibBufferHubTest,TestMaxConsumers)376 TEST_F(LibBufferHubTest, TestMaxConsumers) {
377 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
378 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
379 ASSERT_TRUE(p.get() != nullptr);
380 uint32_t producer_state_mask = p->client_state_mask();
381
382 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
383 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
384 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
385 ASSERT_TRUE(cs[i].get() != nullptr);
386 EXPECT_TRUE(cs[i]->is_released());
387 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
388 }
389
390 EXPECT_EQ(0, p->GainAsync());
391 DvrNativeBufferMetadata metadata;
392 LocalHandle invalid_fence;
393
394 // Post the producer should trigger all consumers to be available.
395 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
396 EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
397 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
398 EXPECT_TRUE(
399 isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
400 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i])));
401 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
402 EXPECT_TRUE(
403 isClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
404 }
405
406 // All consumers have to release before the buffer is considered to be
407 // released.
408 for (size_t i = 0; i < kMaxConsumerCount; i++) {
409 EXPECT_FALSE(p->is_released());
410 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
411 }
412
413 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
414 EXPECT_TRUE(p->is_released());
415
416 // Buffer state cross all clients must be consistent.
417 for (size_t i = 0; i < kMaxConsumerCount; i++) {
418 EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
419 }
420 }
421
TEST_F(LibBufferHubTest,TestCreateConsumerWhenBufferGained)422 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
423 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
424 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
425 ASSERT_TRUE(p.get() != nullptr);
426 EXPECT_EQ(0, p->GainAsync());
427 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
428
429 std::unique_ptr<ConsumerBuffer> c =
430 ConsumerBuffer::Import(p->CreateConsumer());
431 ASSERT_TRUE(c.get() != nullptr);
432 EXPECT_TRUE(isAnyClientGained(c->buffer_state()));
433
434 DvrNativeBufferMetadata metadata;
435 LocalHandle invalid_fence;
436
437 // Post the gained buffer should signal already created consumer.
438 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
439 EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
440 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
441 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
442 EXPECT_TRUE(isAnyClientAcquired(c->buffer_state()));
443 }
444
TEST_F(LibBufferHubTest,TestCreateTheFirstConsumerAfterPostingBuffer)445 TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
446 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
447 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
448 ASSERT_TRUE(p.get() != nullptr);
449 EXPECT_EQ(0, p->GainAsync());
450 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
451
452 DvrNativeBufferMetadata metadata;
453 LocalHandle invalid_fence;
454
455 // Post the gained buffer before any consumer gets created.
456 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
457 EXPECT_TRUE(p->is_released());
458 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
459
460 // Newly created consumer will be signalled for the posted buffer although it
461 // is created after producer posting.
462 std::unique_ptr<ConsumerBuffer> c =
463 ConsumerBuffer::Import(p->CreateConsumer());
464 ASSERT_TRUE(c.get() != nullptr);
465 EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask()));
466 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
467 }
468
TEST_F(LibBufferHubTest,TestCreateConsumerWhenBufferReleased)469 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
470 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
471 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
472 ASSERT_TRUE(p.get() != nullptr);
473
474 std::unique_ptr<ConsumerBuffer> c1 =
475 ConsumerBuffer::Import(p->CreateConsumer());
476 ASSERT_TRUE(c1.get() != nullptr);
477
478 EXPECT_EQ(0, p->GainAsync());
479 DvrNativeBufferMetadata metadata;
480 LocalHandle invalid_fence;
481
482 // Post, acquire, and release the buffer..
483 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
484 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
485 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
486 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
487
488 // Note that the next PDX call is on the producer channel, which may be
489 // executed before Release impulse gets executed by bufferhubd. Thus, here we
490 // need to wait until the releasd is confirmed before creating another
491 // consumer.
492 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
493 EXPECT_TRUE(p->is_released());
494
495 // Create another consumer immediately after the release, should not make the
496 // buffer un-released.
497 std::unique_ptr<ConsumerBuffer> c2 =
498 ConsumerBuffer::Import(p->CreateConsumer());
499 ASSERT_TRUE(c2.get() != nullptr);
500
501 EXPECT_TRUE(p->is_released());
502 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
503 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
504 }
505
TEST_F(LibBufferHubTest,TestWithCustomMetadata)506 TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
507 struct Metadata {
508 int64_t field1;
509 int64_t field2;
510 };
511 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
512 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
513 ASSERT_TRUE(p.get() != nullptr);
514 std::unique_ptr<ConsumerBuffer> c =
515 ConsumerBuffer::Import(p->CreateConsumer());
516 ASSERT_TRUE(c.get() != nullptr);
517 EXPECT_EQ(0, p->GainAsync());
518 Metadata m = {1, 3};
519 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
520 EXPECT_LE(0, RETRY_EINTR(PollBufferEvent(c)));
521 LocalHandle fence;
522 Metadata m2 = {};
523 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
524 EXPECT_EQ(m.field1, m2.field1);
525 EXPECT_EQ(m.field2, m2.field2);
526 EXPECT_EQ(0, c->Release(LocalHandle()));
527 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p, /*timeout_ms=*/0)));
528 }
529
TEST_F(LibBufferHubTest,TestPostWithWrongMetaSize)530 TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
531 struct Metadata {
532 int64_t field1;
533 int64_t field2;
534 };
535 struct OverSizedMetadata {
536 int64_t field1;
537 int64_t field2;
538 int64_t field3;
539 };
540 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
541 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
542 ASSERT_TRUE(p.get() != nullptr);
543 std::unique_ptr<ConsumerBuffer> c =
544 ConsumerBuffer::Import(p->CreateConsumer());
545 ASSERT_TRUE(c.get() != nullptr);
546 EXPECT_EQ(0, p->GainAsync());
547
548 // It is illegal to post metadata larger than originally requested during
549 // buffer allocation.
550 OverSizedMetadata evil_meta = {};
551 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
552 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c)));
553
554 // It is ok to post metadata smaller than originally requested during
555 // buffer allocation.
556 EXPECT_EQ(0, p->Post(LocalHandle()));
557 }
558
TEST_F(LibBufferHubTest,TestAcquireWithWrongMetaSize)559 TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
560 struct Metadata {
561 int64_t field1;
562 int64_t field2;
563 };
564 struct OverSizedMetadata {
565 int64_t field1;
566 int64_t field2;
567 int64_t field3;
568 };
569 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
570 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
571 ASSERT_TRUE(p.get() != nullptr);
572 std::unique_ptr<ConsumerBuffer> c =
573 ConsumerBuffer::Import(p->CreateConsumer());
574 ASSERT_TRUE(c.get() != nullptr);
575 EXPECT_EQ(0, p->GainAsync());
576
577 Metadata m = {1, 3};
578 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
579
580 LocalHandle fence;
581 int64_t sequence;
582 OverSizedMetadata e;
583
584 // It is illegal to acquire metadata larger than originally requested during
585 // buffer allocation.
586 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
587
588 // It is ok to acquire metadata smaller than originally requested during
589 // buffer allocation.
590 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
591 EXPECT_EQ(m.field1, sequence);
592 }
593
TEST_F(LibBufferHubTest,TestAcquireWithNoMeta)594 TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
595 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
596 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
597 ASSERT_TRUE(p.get() != nullptr);
598 std::unique_ptr<ConsumerBuffer> c =
599 ConsumerBuffer::Import(p->CreateConsumer());
600 ASSERT_TRUE(c.get() != nullptr);
601 EXPECT_EQ(0, p->GainAsync());
602
603 int64_t sequence = 3;
604 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
605
606 LocalHandle fence;
607 EXPECT_EQ(0, c->Acquire(&fence));
608 }
609
TEST_F(LibBufferHubTest,TestWithNoMeta)610 TEST_F(LibBufferHubTest, TestWithNoMeta) {
611 std::unique_ptr<ProducerBuffer> p =
612 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
613 ASSERT_TRUE(p.get() != nullptr);
614 std::unique_ptr<ConsumerBuffer> c =
615 ConsumerBuffer::Import(p->CreateConsumer());
616 ASSERT_TRUE(c.get() != nullptr);
617 EXPECT_EQ(0, p->GainAsync());
618
619 LocalHandle fence;
620
621 EXPECT_EQ(0, p->Post(LocalHandle()));
622 EXPECT_EQ(0, c->Acquire(&fence));
623 }
624
TEST_F(LibBufferHubTest,TestFailureToPostMetaFromABufferWithoutMeta)625 TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
626 std::unique_ptr<ProducerBuffer> p =
627 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
628 ASSERT_TRUE(p.get() != nullptr);
629 std::unique_ptr<ConsumerBuffer> c =
630 ConsumerBuffer::Import(p->CreateConsumer());
631 ASSERT_TRUE(c.get() != nullptr);
632 EXPECT_EQ(0, p->GainAsync());
633
634 int64_t sequence = 3;
635 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
636 }
637
638 namespace {
639
PollFd(int fd,int timeout_ms)640 int PollFd(int fd, int timeout_ms) {
641 pollfd p = {fd, POLLIN, 0};
642 return poll(&p, 1, timeout_ms);
643 }
644
645 } // namespace
646
TEST_F(LibBufferHubTest,TestAcquireFence)647 TEST_F(LibBufferHubTest, TestAcquireFence) {
648 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
649 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
650 ASSERT_TRUE(p.get() != nullptr);
651 std::unique_ptr<ConsumerBuffer> c =
652 ConsumerBuffer::Import(p->CreateConsumer());
653 ASSERT_TRUE(c.get() != nullptr);
654 EXPECT_EQ(0, p->GainAsync());
655
656 DvrNativeBufferMetadata meta;
657 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
658
659 // Post with unsignaled fence.
660 EXPECT_EQ(0, p->PostAsync(&meta, f1));
661
662 // Should acquire a valid fence.
663 LocalHandle f2;
664 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
665 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
666 EXPECT_TRUE(f2.IsValid());
667 // The original fence and acquired fence should have different fd number.
668 EXPECT_NE(f1.Get(), f2.Get());
669 EXPECT_GE(0, PollFd(f2.Get(), 0));
670
671 // Signal the original fence will trigger the new fence.
672 eventfd_write(f1.Get(), 1);
673 // Now the original FD has been signaled.
674 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
675
676 // Release the consumer with an invalid fence.
677 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
678
679 // Should gain an invalid fence.
680 LocalHandle f3;
681 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
682 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
683 EXPECT_FALSE(f3.IsValid());
684
685 // Post with a signaled fence.
686 EXPECT_EQ(0, p->PostAsync(&meta, f1));
687
688 // Should acquire a valid fence and it's already signalled.
689 LocalHandle f4;
690 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
691 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
692 EXPECT_TRUE(f4.IsValid());
693 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
694
695 // Release with an unsignalled fence and signal it immediately after release
696 // without producer gainning.
697 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
698 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
699 eventfd_write(f5.Get(), 1);
700
701 // Should gain a valid fence, which is already signaled.
702 LocalHandle f6;
703 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
704 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
705 EXPECT_TRUE(f6.IsValid());
706 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
707 }
708
TEST_F(LibBufferHubTest,TestOrphanedAcquire)709 TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
710 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
711 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
712 ASSERT_TRUE(p.get() != nullptr);
713 std::unique_ptr<ConsumerBuffer> c1 =
714 ConsumerBuffer::Import(p->CreateConsumer());
715 ASSERT_TRUE(c1.get() != nullptr);
716 const uint32_t client_state_mask1 = c1->client_state_mask();
717
718 EXPECT_EQ(0, p->GainAsync());
719 DvrNativeBufferMetadata meta;
720 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
721
722 LocalHandle fence;
723 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
724 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
725
726 // Destroy the consumer who has acquired but not released the buffer.
727 c1 = nullptr;
728
729 // The buffer is now available for the producer to gain.
730 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
731
732 // Newly added consumer is not able to acquire the buffer.
733 std::unique_ptr<ConsumerBuffer> c2 =
734 ConsumerBuffer::Import(p->CreateConsumer());
735 ASSERT_TRUE(c2.get() != nullptr);
736 const uint32_t client_state_mask2 = c2->client_state_mask();
737 EXPECT_NE(client_state_mask1, client_state_mask2);
738 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
739 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
740
741 // Producer should be able to gain.
742 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
743 }
744
TEST_F(LibBufferHubTest,TestAcquireLastPosted)745 TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
746 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
747 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
748 ASSERT_TRUE(p.get() != nullptr);
749 std::unique_ptr<ConsumerBuffer> c1 =
750 ConsumerBuffer::Import(p->CreateConsumer());
751 ASSERT_TRUE(c1.get() != nullptr);
752 const uint32_t client_state_mask1 = c1->client_state_mask();
753
754 EXPECT_EQ(0, p->GainAsync());
755 DvrNativeBufferMetadata meta;
756 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
757 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
758
759 // c2 is created when the buffer is in posted state. buffer state for c1 is
760 // posted. Thus, c2 should be automatically set to posted and able to acquire.
761 std::unique_ptr<ConsumerBuffer> c2 =
762 ConsumerBuffer::Import(p->CreateConsumer());
763 ASSERT_TRUE(c2.get() != nullptr);
764 const uint32_t client_state_mask2 = c2->client_state_mask();
765 EXPECT_NE(client_state_mask1, client_state_mask2);
766 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c2)));
767 LocalHandle invalid_fence;
768 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
769
770 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
771
772 // c3 is created when the buffer is in acquired state. buffer state for c1 and
773 // c2 are acquired. Thus, c3 should be automatically set to posted and able to
774 // acquire.
775 std::unique_ptr<ConsumerBuffer> c3 =
776 ConsumerBuffer::Import(p->CreateConsumer());
777 ASSERT_TRUE(c3.get() != nullptr);
778 const uint32_t client_state_mask3 = c3->client_state_mask();
779 EXPECT_NE(client_state_mask1, client_state_mask3);
780 EXPECT_NE(client_state_mask2, client_state_mask3);
781 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c3)));
782 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
783
784 // Releasing c2 and c3 in normal ways.
785 EXPECT_EQ(0, c2->Release(LocalHandle()));
786 EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
787
788 // Destroy the c1 who has not released the buffer.
789 c1 = nullptr;
790
791 // The buffer is now available for the producer to gain.
792 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
793
794 // C4 is created in released state. Thus, it cannot gain the just posted
795 // buffer.
796 std::unique_ptr<ConsumerBuffer> c4 =
797 ConsumerBuffer::Import(p->CreateConsumer());
798 ASSERT_TRUE(c4.get() != nullptr);
799 const uint32_t client_state_mask4 = c4->client_state_mask();
800 EXPECT_NE(client_state_mask3, client_state_mask4);
801 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c3)));
802 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
803
804 // Producer should be able to gain.
805 EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
806 }
807
TEST_F(LibBufferHubTest,TestDetachBufferFromProducer)808 TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
809 // TODO(b/112338294) rewrite test after migration
810 return;
811
812 /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
813 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
814 std::unique_ptr<ConsumerBuffer> c =
815 ConsumerBuffer::Import(p->CreateConsumer());
816 ASSERT_TRUE(p.get() != nullptr);
817 ASSERT_TRUE(c.get() != nullptr);
818
819 DvrNativeBufferMetadata metadata;
820 LocalHandle invalid_fence;
821 int p_id = p->id();
822
823 // Detach in posted state should fail.
824 EXPECT_EQ(0, p->GainAsync());
825 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
826 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
827 auto s1 = p->Detach();
828 EXPECT_FALSE(s1);
829
830 // Detach in acquired state should fail.
831 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
832 s1 = p->Detach();
833 EXPECT_FALSE(s1);
834
835 // Detach in released state should fail.
836 EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
837 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
838 s1 = p->Detach();
839 EXPECT_FALSE(s1);
840
841 // Detach in gained state should succeed.
842 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
843 s1 = p->Detach();
844 EXPECT_TRUE(s1);
845
846 LocalChannelHandle handle = s1.take();
847 EXPECT_TRUE(handle.valid());
848
849 // Both producer and consumer should have hangup.
850 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
851 auto s2 = p->GetEventMask(POLLHUP);
852 EXPECT_TRUE(s2);
853 EXPECT_EQ(s2.get(), POLLHUP);
854
855 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
856 s2 = p->GetEventMask(POLLHUP);
857 EXPECT_TRUE(s2);
858 EXPECT_EQ(s2.get(), POLLHUP);
859
860 auto s3 = p->CreateConsumer();
861 EXPECT_FALSE(s3);
862 // Note that here the expected error code is EOPNOTSUPP as the socket towards
863 // ProducerChannel has been teared down.
864 EXPECT_EQ(s3.error(), EOPNOTSUPP);
865
866 s3 = c->CreateConsumer();
867 EXPECT_FALSE(s3);
868 // Note that here the expected error code is EPIPE returned from
869 // ConsumerChannel::HandleMessage as the socket is still open but the producer
870 // is gone.
871 EXPECT_EQ(s3.error(), EPIPE);
872
873 // Detached buffer handle can be use to construct a new BufferHubBuffer
874 // object.
875 auto d = BufferHubBuffer::Import(std::move(handle));
876 EXPECT_FALSE(handle.valid());
877 EXPECT_TRUE(d->IsConnected());
878 EXPECT_TRUE(d->IsValid());
879
880 EXPECT_EQ(d->id(), p_id); */
881 }
882
TEST_F(LibBufferHubTest,TestDetach)883 TEST_F(LibBufferHubTest, TestDetach) {
884 // TODO(b/112338294) rewrite test after migration
885 return;
886
887 /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
888 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
889 ASSERT_TRUE(p1.get() != nullptr);
890 int p1_id = p1->id();
891
892 // Detached the producer from gained state.
893 EXPECT_EQ(0, p1->GainAsync());
894 auto status_or_handle = p1->Detach();
895 EXPECT_TRUE(status_or_handle.ok());
896 LocalChannelHandle h1 = status_or_handle.take();
897 EXPECT_TRUE(h1.valid());
898
899 // Detached buffer handle can be use to construct a new BufferHubBuffer
900 // object.
901 auto b1 = BufferHubBuffer::Import(std::move(h1));
902 EXPECT_FALSE(h1.valid());
903 EXPECT_TRUE(b1->IsValid());
904 int b1_id = b1->id();
905 EXPECT_EQ(b1_id, p1_id); */
906 }
907