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