blob: 27ab0242ad40f5ec2db19c8260ef1afd0cec9ea1 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07003#include <private/dvr/bufferhub_rpc.h>
Tianyu Jiang49642322018-12-18 11:08:03 -08004#include <private/dvr/consumer_buffer.h>
5#include <private/dvr/producer_buffer.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07006#include <sys/epoll.h>
7#include <sys/eventfd.h>
Tianyu Jiang7359dc92018-12-13 11:22:28 -08008#include <ui/BufferHubDefs.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08009
10#include <mutex>
11#include <thread>
12
Tianyu Jiangb75b0972019-01-31 18:25:57 -080013namespace {
Alex Vakulenko4fe60582017-02-02 11:35:59 -080014#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
Tianyu Jiang727ede42019-02-01 11:44:51 -080023using android::BufferHubDefs::isAnyClientAcquired;
24using android::BufferHubDefs::isAnyClientGained;
25using android::BufferHubDefs::isAnyClientPosted;
26using android::BufferHubDefs::isClientAcquired;
27using android::BufferHubDefs::isClientPosted;
28using android::BufferHubDefs::isClientReleased;
Tianyu Jiang7359dc92018-12-13 11:22:28 -080029using android::BufferHubDefs::kFirstClientBitMask;
Tianyu1a60bb42018-10-08 14:56:08 -070030using android::dvr::ConsumerBuffer;
Tianyu1a60bb42018-10-08 14:56:08 -070031using android::dvr::ProducerBuffer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080032using android::pdx::LocalHandle;
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -070033using android::pdx::Status;
Tianyu Jiangb75b0972019-01-31 18:25:57 -080034using LibBufferHubTest = ::testing::Test;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035
36const int kWidth = 640;
37const int kHeight = 480;
38const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
39const int kUsage = 0;
Tianyu Jiang8f10b752018-10-30 17:24:51 -070040// Maximum number of consumers for the buffer that only has one producer in the
41// test.
42const size_t kMaxConsumerCount =
Tianyu Jiang7359dc92018-12-13 11:22:28 -080043 android::BufferHubDefs::kMaxNumberOfClients - 1;
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -080044const int kPollTimeoutMs = 100;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080045
Tianyu Jiangb75b0972019-01-31 18:25:57 -080046// Helper function to poll the eventfd in BufferHubBase.
47template <class BufferHubBase>
48int 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
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080055
56TEST_F(LibBufferHubTest, TestBasicUsage) {
Tianyu1a60bb42018-10-08 14:56:08 -070057 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080058 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
59 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -070060 std::unique_ptr<ConsumerBuffer> c1 =
Tianyu1a60bb42018-10-08 14:56:08 -070061 ConsumerBuffer::Import(p->CreateConsumer());
Tianyuf669f6a2018-10-10 15:34:32 -070062 ASSERT_TRUE(c1.get() != nullptr);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080063 // Check that consumers can spawn other consumers.
Tianyu1a60bb42018-10-08 14:56:08 -070064 std::unique_ptr<ConsumerBuffer> c2 =
Tianyuf669f6a2018-10-10 15:34:32 -070065 ConsumerBuffer::Import(c1->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080066 ASSERT_TRUE(c2.get() != nullptr);
67
Tianyuf669f6a2018-10-10 15:34:32 -070068 // Checks the state masks of client p, c1 and c2.
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070069 EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
Tianyuf669f6a2018-10-10 15:34:32 -070070 EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
71 EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070072
73 // Initial state: producer not available, consumers not available.
Tianyu Jiangb75b0972019-01-31 18:25:57 -080074 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
75 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
76 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070077
Tianyuf669f6a2018-10-10 15:34:32 -070078 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -070079 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070080
81 // New state: producer not available, consumers available.
Tianyu Jiangb75b0972019-01-31 18:25:57 -080082 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
83 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c1)));
84 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080085
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080086 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -070087 EXPECT_EQ(0, c1->Acquire(&fence));
Tianyu Jiangb75b0972019-01-31 18:25:57 -080088 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
89 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090
Tianyu58a05a22018-10-10 18:41:27 -070091 EXPECT_EQ(0, c2->Acquire(&fence));
Tianyu Jiangb75b0972019-01-31 18:25:57 -080092 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
93 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094
Tianyuf669f6a2018-10-10 15:34:32 -070095 EXPECT_EQ(0, c1->Release(LocalHandle()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -080096 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080097 EXPECT_EQ(0, c2->Discard());
Tianyu Jiangb75b0972019-01-31 18:25:57 -080098 EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(p)));
Tianyuf669f6a2018-10-10 15:34:32 -070099
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800100 EXPECT_EQ(0, p->Gain(&fence));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800101 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
102 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
103 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700104}
105
106TEST_F(LibBufferHubTest, TestEpoll) {
Tianyu1a60bb42018-10-08 14:56:08 -0700107 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700108 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
109 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700110 std::unique_ptr<ConsumerBuffer> c =
111 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700112 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
Tianyuf669f6a2018-10-10 15:34:32 -0700143 // Gain and post the producer and check for consumer signal.
144 EXPECT_EQ(0, p->GainAsync());
Tianyu58a05a22018-10-10 18:41:27 -0700145 EXPECT_EQ(0, p->Post({}));
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800146 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
147 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700148 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.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800155 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));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700163
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.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800170 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
171 kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700172}
173
174TEST_F(LibBufferHubTest, TestStateMask) {
Tianyu1a60bb42018-10-08 14:56:08 -0700175 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700176 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
177 ASSERT_TRUE(p.get() != nullptr);
178
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700179 // It's ok to create up to kMaxConsumerCount consumer buffers.
Tianyu Jianga99f9112018-12-13 18:23:07 -0800180 uint32_t client_state_masks = p->client_state_mask();
Tianyu1a60bb42018-10-08 14:56:08 -0700181 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700182 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu1a60bb42018-10-08 14:56:08 -0700183 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700184 ASSERT_TRUE(cs[i].get() != nullptr);
185 // Expect all buffers have unique state mask.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700186 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
187 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700188 }
Tianyu Jianga99f9112018-12-13 18:23:07 -0800189 EXPECT_EQ(client_state_masks, ~0U);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700190
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.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700196 for (size_t i = 0; i < kMaxConsumerCount; i++) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700197 client_state_masks &= ~cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700198 cs[i] = nullptr;
Tianyu1a60bb42018-10-08 14:56:08 -0700199 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700200 ASSERT_TRUE(cs[i].get() != nullptr);
201 // The released state mask will be reused.
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700202 EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
203 client_state_masks |= cs[i]->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700204 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800205}
206
Corey Tabakad53870c2017-07-06 18:04:27 -0700207TEST_F(LibBufferHubTest, TestStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700208 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabakad53870c2017-07-06 18:04:27 -0700209 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
210 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700211 std::unique_ptr<ConsumerBuffer> c =
212 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabakad53870c2017-07-06 18:04:27 -0700213 ASSERT_TRUE(c.get() != nullptr);
214
Corey Tabakad53870c2017-07-06 18:04:27 -0700215 LocalHandle fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700216 EXPECT_EQ(0, p->GainAsync());
Corey Tabakad53870c2017-07-06 18:04:27 -0700217
Tianyu Jiang60887c92018-11-14 15:52:38 -0800218 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700219 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700220
221 // Post in gained state should succeed.
Tianyu58a05a22018-10-10 18:41:27 -0700222 EXPECT_EQ(0, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700223
Tianyuf669f6a2018-10-10 15:34:32 -0700224 // Post and gain in posted state should fail.
Tianyu58a05a22018-10-10 18:41:27 -0700225 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700226 EXPECT_EQ(-EBUSY, p->Gain(&fence));
227
228 // Acquire in posted state should succeed.
Tianyuf669f6a2018-10-10 15:34:32 -0700229 EXPECT_EQ(0, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700230
231 // Acquire, post, and gain in acquired state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700232 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700233 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700234 EXPECT_EQ(-EBUSY, p->Gain(&fence));
235
236 // Release in acquired state should succeed.
237 EXPECT_EQ(0, c->Release(LocalHandle()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800238 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700239
Tianyuf669f6a2018-10-10 15:34:32 -0700240 // Acquire and post in released state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700241 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Tianyu58a05a22018-10-10 18:41:27 -0700242 EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
Corey Tabakad53870c2017-07-06 18:04:27 -0700243
244 // Gain in released state should succeed.
245 EXPECT_EQ(0, p->Gain(&fence));
246
Tianyu Jiang60887c92018-11-14 15:52:38 -0800247 // Acquire in gained state should fail.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700248 EXPECT_EQ(-EBUSY, c->Acquire(&fence));
Corey Tabakad53870c2017-07-06 18:04:27 -0700249}
250
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700251TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
Tianyu1a60bb42018-10-08 14:56:08 -0700252 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700253 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
254 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700255 std::unique_ptr<ConsumerBuffer> c =
256 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700257 ASSERT_TRUE(c.get() != nullptr);
258
259 DvrNativeBufferMetadata metadata;
260 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700261 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700262
Tianyu Jiang60887c92018-11-14 15:52:38 -0800263 // Acquire in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700264 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
265 EXPECT_FALSE(invalid_fence.IsValid());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700266 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());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800271 EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700272
Tianyuf669f6a2018-10-10 15:34:32 -0700273 // Post and gain in posted state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700274 EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700275 EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
276 EXPECT_FALSE(invalid_fence.IsValid());
277
278 // Acquire in posted state should succeed.
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800279 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700280 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
281 EXPECT_FALSE(invalid_fence.IsValid());
282 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800283 EXPECT_TRUE(isAnyClientAcquired(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700284
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));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800294 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700295 EXPECT_EQ(p->buffer_state(), c->buffer_state());
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800296 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700297
Tianyuf669f6a2018-10-10 15:34:32 -0700298 // Acquire and post in released state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700299 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());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800307 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700308
Tianyuf669f6a2018-10-10 15:34:32 -0700309 // Acquire and gain in gained state should fail.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700310 EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
311 EXPECT_FALSE(invalid_fence.IsValid());
Tianyu Jiang60887c92018-11-14 15:52:38 -0800312}
313
314TEST_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());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700321}
322
Tianyu5465d6c2018-08-14 13:03:10 -0700323TEST_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);
Tianyuf669f6a2018-10-10 15:34:32 -0700327 std::unique_ptr<ConsumerBuffer> c =
328 ConsumerBuffer::Import(p->CreateConsumer());
329 ASSERT_TRUE(c.get() != nullptr);
330 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700331 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800332 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700333
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
340TEST_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);
Tianyuf669f6a2018-10-10 15:34:32 -0700344 std::unique_ptr<ConsumerBuffer> c =
345 ConsumerBuffer::Import(p->CreateConsumer());
346 ASSERT_TRUE(c.get() != nullptr);
347 ASSERT_EQ(0, p->GainAsync());
Tianyu5465d6c2018-08-14 13:03:10 -0700348 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800349 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
Tianyu5465d6c2018-08-14 13:03:10 -0700350
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
Tianyuf669f6a2018-10-10 15:34:32 -0700359TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700360 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700361 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
362 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700363 ASSERT_EQ(0, p->GainAsync());
364 ASSERT_EQ(0, p->Post(LocalHandle()));
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800365 // 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.
Tianyu Jiang727ede42019-02-01 11:44:51 -0800367 ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800368 ASSERT_TRUE(p->is_released());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800369 ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700370
Tianyuf669f6a2018-10-10 15:34:32 -0700371 // Gain in released state should succeed.
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700372 LocalHandle invalid_fence;
Tianyuf669f6a2018-10-10 15:34:32 -0700373 EXPECT_EQ(0, p->Gain(&invalid_fence, false));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700374}
375
376TEST_F(LibBufferHubTest, TestMaxConsumers) {
Tianyu1a60bb42018-10-08 14:56:08 -0700377 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700378 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
379 ASSERT_TRUE(p.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800380 uint32_t producer_state_mask = p->client_state_mask();
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700381
Tianyu1a60bb42018-10-08 14:56:08 -0700382 std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
Tianyuf669f6a2018-10-10 15:34:32 -0700383 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Tianyu1a60bb42018-10-08 14:56:08 -0700384 cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700385 ASSERT_TRUE(cs[i].get() != nullptr);
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800386 EXPECT_TRUE(cs[i]->is_released());
Tianyuf669f6a2018-10-10 15:34:32 -0700387 EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700388 }
389
Tianyuf669f6a2018-10-10 15:34:32 -0700390 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700391 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));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800396 EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
Tianyuf669f6a2018-10-10 15:34:32 -0700397 for (size_t i = 0; i < kMaxConsumerCount; ++i) {
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700398 EXPECT_TRUE(
Tianyu Jiang727ede42019-02-01 11:44:51 -0800399 isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800400 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i])));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700401 EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
Tianyuf669f6a2018-10-10 15:34:32 -0700402 EXPECT_TRUE(
Tianyu Jiang727ede42019-02-01 11:44:51 -0800403 isClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700404 }
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++) {
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800409 EXPECT_FALSE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700410 EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
411 }
412
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800413 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800414 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700415
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
422TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
Tianyu1a60bb42018-10-08 14:56:08 -0700423 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700424 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
425 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700426 EXPECT_EQ(0, p->GainAsync());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800427 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700428
Tianyu1a60bb42018-10-08 14:56:08 -0700429 std::unique_ptr<ConsumerBuffer> c =
430 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700431 ASSERT_TRUE(c.get() != nullptr);
Tianyu Jiang727ede42019-02-01 11:44:51 -0800432 EXPECT_TRUE(isAnyClientGained(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700433
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));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800439 EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800440 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700441 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800442 EXPECT_TRUE(isAnyClientAcquired(c->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700443}
444
Tianyuf669f6a2018-10-10 15:34:32 -0700445TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
Tianyu1a60bb42018-10-08 14:56:08 -0700446 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700447 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
448 ASSERT_TRUE(p.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700449 EXPECT_EQ(0, p->GainAsync());
Tianyu Jiang727ede42019-02-01 11:44:51 -0800450 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700451
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));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800457 EXPECT_TRUE(p->is_released());
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800458 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700459
Tianyu Jiange60a4ad2019-01-04 14:37:23 -0800460 // Newly created consumer will be signalled for the posted buffer although it
461 // is created after producer posting.
Tianyu1a60bb42018-10-08 14:56:08 -0700462 std::unique_ptr<ConsumerBuffer> c =
463 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700464 ASSERT_TRUE(c.get() != nullptr);
Tianyu Jiang727ede42019-02-01 11:44:51 -0800465 EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700466 EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700467}
468
469TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
Tianyu1a60bb42018-10-08 14:56:08 -0700470 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700471 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
472 ASSERT_TRUE(p.get() != nullptr);
473
Tianyu1a60bb42018-10-08 14:56:08 -0700474 std::unique_ptr<ConsumerBuffer> c1 =
475 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700476 ASSERT_TRUE(c1.get() != nullptr);
477
Tianyuf669f6a2018-10-10 15:34:32 -0700478 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700479 DvrNativeBufferMetadata metadata;
480 LocalHandle invalid_fence;
481
482 // Post, acquire, and release the buffer..
483 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800484 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700485 EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
486 EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
487
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800488 // 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.
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800492 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800493 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800494
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700495 // Create another consumer immediately after the release, should not make the
Jiwen 'Steve' Cai2d89e6b2017-12-06 16:32:22 -0800496 // buffer un-released.
Tianyu1a60bb42018-10-08 14:56:08 -0700497 std::unique_ptr<ConsumerBuffer> c2 =
498 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700499 ASSERT_TRUE(c2.get() != nullptr);
500
Tianyu Jianga8df5f32019-01-14 18:42:12 -0800501 EXPECT_TRUE(p->is_released());
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700502 EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
Tianyu Jiang727ede42019-02-01 11:44:51 -0800503 EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
Jiwen 'Steve' Cai9e7f3032017-10-20 18:39:47 -0700504}
505
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800506TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
507 struct Metadata {
508 int64_t field1;
509 int64_t field2;
510 };
Tianyu1a60bb42018-10-08 14:56:08 -0700511 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800512 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
513 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700514 std::unique_ptr<ConsumerBuffer> c =
515 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800516 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700517 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700519 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800520 EXPECT_LE(0, RETRY_EINTR(PollBufferEvent(c)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800521 LocalHandle fence;
522 Metadata m2 = {};
Tianyu Jiangee723f52018-10-24 16:37:38 -0700523 EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800524 EXPECT_EQ(m.field1, m2.field1);
525 EXPECT_EQ(m.field2, m2.field2);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800526 EXPECT_EQ(0, c->Release(LocalHandle()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800527 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p, /*timeout_ms=*/0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800528}
529
530TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
531 struct Metadata {
532 int64_t field1;
533 int64_t field2;
534 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700535 struct OverSizedMetadata {
536 int64_t field1;
537 int64_t field2;
538 int64_t field3;
539 };
Tianyu1a60bb42018-10-08 14:56:08 -0700540 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800541 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
542 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700543 std::unique_ptr<ConsumerBuffer> c =
544 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800545 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700546 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800547
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700548 // It is illegal to post metadata larger than originally requested during
549 // buffer allocation.
550 OverSizedMetadata evil_meta = {};
Tianyu58a05a22018-10-10 18:41:27 -0700551 EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800552 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700553
554 // It is ok to post metadata smaller than originally requested during
555 // buffer allocation.
Tianyu58a05a22018-10-10 18:41:27 -0700556 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800557}
558
559TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
560 struct Metadata {
561 int64_t field1;
562 int64_t field2;
563 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700564 struct OverSizedMetadata {
565 int64_t field1;
566 int64_t field2;
567 int64_t field3;
568 };
Tianyu1a60bb42018-10-08 14:56:08 -0700569 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800570 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
571 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700572 std::unique_ptr<ConsumerBuffer> c =
573 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800574 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700575 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800576
577 Metadata m = {1, 3};
Tianyu58a05a22018-10-10 18:41:27 -0700578 EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800579
580 LocalHandle fence;
581 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700582 OverSizedMetadata e;
583
584 // It is illegal to acquire metadata larger than originally requested during
585 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700586 EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700587
588 // It is ok to acquire metadata smaller than originally requested during
589 // buffer allocation.
Tianyu Jiangee723f52018-10-24 16:37:38 -0700590 EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700591 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800592}
593
594TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700595 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800596 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
597 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700598 std::unique_ptr<ConsumerBuffer> c =
599 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800600 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700601 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800602
603 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700604 EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800605
606 LocalHandle fence;
607 EXPECT_EQ(0, c->Acquire(&fence));
608}
609
610TEST_F(LibBufferHubTest, TestWithNoMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700611 std::unique_ptr<ProducerBuffer> p =
612 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700614 std::unique_ptr<ConsumerBuffer> c =
615 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800616 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700617 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800618
619 LocalHandle fence;
620
Tianyue6e08ab2018-09-13 18:48:55 -0700621 EXPECT_EQ(0, p->Post(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800622 EXPECT_EQ(0, c->Acquire(&fence));
623}
624
625TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
Tianyu1a60bb42018-10-08 14:56:08 -0700626 std::unique_ptr<ProducerBuffer> p =
627 ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800628 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700629 std::unique_ptr<ConsumerBuffer> c =
630 ConsumerBuffer::Import(p->CreateConsumer());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800631 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700632 EXPECT_EQ(0, p->GainAsync());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800633
634 int64_t sequence = 3;
Tianyu58a05a22018-10-10 18:41:27 -0700635 EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800636}
637
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700638namespace {
639
640int PollFd(int fd, int timeout_ms) {
641 pollfd p = {fd, POLLIN, 0};
642 return poll(&p, 1, timeout_ms);
643}
644
645} // namespace
646
647TEST_F(LibBufferHubTest, TestAcquireFence) {
Tianyu1a60bb42018-10-08 14:56:08 -0700648 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700649 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
650 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700651 std::unique_ptr<ConsumerBuffer> c =
652 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700653 ASSERT_TRUE(c.get() != nullptr);
Tianyuf669f6a2018-10-10 15:34:32 -0700654 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700655
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;
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800664 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700665 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.
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800674 EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700675
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;
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800681 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700682 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;
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800690 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700691 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
692 EXPECT_TRUE(f4.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800693 EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700694
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;
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800703 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700704 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
705 EXPECT_TRUE(f6.IsValid());
Jiwen 'Steve' Cai30be1112017-11-08 17:12:20 -0800706 EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700707}
708
709TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
Tianyu1a60bb42018-10-08 14:56:08 -0700710 std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700711 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
712 ASSERT_TRUE(p.get() != nullptr);
Tianyu1a60bb42018-10-08 14:56:08 -0700713 std::unique_ptr<ConsumerBuffer> c1 =
714 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700715 ASSERT_TRUE(c1.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800716 const uint32_t client_state_mask1 = c1->client_state_mask();
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700717
Tianyuf669f6a2018-10-10 15:34:32 -0700718 EXPECT_EQ(0, p->GainAsync());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700719 DvrNativeBufferMetadata meta;
720 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
721
722 LocalHandle fence;
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800723 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
Tianyuf669f6a2018-10-10 15:34:32 -0700724 EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700725
Tianyuf669f6a2018-10-10 15:34:32 -0700726 // 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.
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800730 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Tianyuf669f6a2018-10-10 15:34:32 -0700731
732 // Newly added consumer is not able to acquire the buffer.
Tianyu1a60bb42018-10-08 14:56:08 -0700733 std::unique_ptr<ConsumerBuffer> c2 =
734 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700735 ASSERT_TRUE(c2.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800736 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700737 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800738 EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
Tianyuf669f6a2018-10-10 15:34:32 -0700739 EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700740
Tianyuf669f6a2018-10-10 15:34:32 -0700741 // Producer should be able to gain.
742 EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
743}
744
745TEST_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);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800752 const uint32_t client_state_mask1 = c1->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700753
754 EXPECT_EQ(0, p->GainAsync());
755 DvrNativeBufferMetadata meta;
756 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800757 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
Tianyuf669f6a2018-10-10 15:34:32 -0700758
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);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800764 const uint32_t client_state_mask2 = c2->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700765 EXPECT_NE(client_state_mask1, client_state_mask2);
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800766 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c2)));
Tianyuf669f6a2018-10-10 15:34:32 -0700767 LocalHandle invalid_fence;
768 EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700769
Tianyuf669f6a2018-10-10 15:34:32 -0700770 EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700771
Tianyuf669f6a2018-10-10 15:34:32 -0700772 // 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.
Tianyu1a60bb42018-10-08 14:56:08 -0700775 std::unique_ptr<ConsumerBuffer> c3 =
776 ConsumerBuffer::Import(p->CreateConsumer());
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700777 ASSERT_TRUE(c3.get() != nullptr);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800778 const uint32_t client_state_mask3 = c3->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700779 EXPECT_NE(client_state_mask1, client_state_mask3);
Tianyu Jiang83a991f2018-10-30 16:59:29 -0700780 EXPECT_NE(client_state_mask2, client_state_mask3);
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800781 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c3)));
Tianyuf669f6a2018-10-10 15:34:32 -0700782 EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700783
Tianyuf669f6a2018-10-10 15:34:32 -0700784 // 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.
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800792 EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
Tianyuf669f6a2018-10-10 15:34:32 -0700793
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);
Tianyu Jianga99f9112018-12-13 18:23:07 -0800799 const uint32_t client_state_mask4 = c4->client_state_mask();
Tianyuf669f6a2018-10-10 15:34:32 -0700800 EXPECT_NE(client_state_mask3, client_state_mask4);
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800801 EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c3)));
Tianyuf669f6a2018-10-10 15:34:32 -0700802 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));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700806}
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700807
808TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
Fan Xuddb90db2018-10-03 10:09:14 -0700809 // TODO(b/112338294) rewrite test after migration
810 return;
811
Fan Xu021776e2018-12-05 13:34:48 -0800812 /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700813 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
Tianyu1a60bb42018-10-08 14:56:08 -0700814 std::unique_ptr<ConsumerBuffer> c =
815 ConsumerBuffer::Import(p->CreateConsumer());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700816 ASSERT_TRUE(p.get() != nullptr);
817 ASSERT_TRUE(c.get() != nullptr);
818
819 DvrNativeBufferMetadata metadata;
820 LocalHandle invalid_fence;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700821 int p_id = p->id();
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700822
823 // Detach in posted state should fail.
Tianyuf669f6a2018-10-10 15:34:32 -0700824 EXPECT_EQ(0, p->GainAsync());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700825 EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800826 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700827 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));
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800837 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700838 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
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700846 LocalChannelHandle handle = s1.take();
847 EXPECT_TRUE(handle.valid());
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700848
849 // Both producer and consumer should have hangup.
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800850 EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700851 auto s2 = p->GetEventMask(POLLHUP);
852 EXPECT_TRUE(s2);
853 EXPECT_EQ(s2.get(), POLLHUP);
854
Tianyu Jiangb75b0972019-01-31 18:25:57 -0800855 EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700856 s2 = p->GetEventMask(POLLHUP);
857 EXPECT_TRUE(s2);
858 EXPECT_EQ(s2.get(), POLLHUP);
859
860 auto s3 = p->CreateConsumer();
861 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700862 // Note that here the expected error code is EOPNOTSUPP as the socket towards
863 // ProducerChannel has been teared down.
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700864 EXPECT_EQ(s3.error(), EOPNOTSUPP);
865
866 s3 = c->CreateConsumer();
867 EXPECT_FALSE(s3);
Jiwen 'Steve' Caife924f32018-03-27 13:29:13 -0700868 // 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);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700872
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700873 // Detached buffer handle can be use to construct a new BufferHubBuffer
874 // object.
875 auto d = BufferHubBuffer::Import(std::move(handle));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700876 EXPECT_FALSE(handle.valid());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700877 EXPECT_TRUE(d->IsConnected());
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700878 EXPECT_TRUE(d->IsValid());
879
Fan Xu021776e2018-12-05 13:34:48 -0800880 EXPECT_EQ(d->id(), p_id); */
Tianyub61df912018-10-16 14:55:39 -0700881}
882
883TEST_F(LibBufferHubTest, TestDetach) {
Fan Xuddb90db2018-10-03 10:09:14 -0700884 // TODO(b/112338294) rewrite test after migration
885 return;
886
Fan Xu021776e2018-12-05 13:34:48 -0800887 /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700888 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
889 ASSERT_TRUE(p1.get() != nullptr);
890 int p1_id = p1->id();
891
Tianyuf669f6a2018-10-10 15:34:32 -0700892 // Detached the producer from gained state.
893 EXPECT_EQ(0, p1->GainAsync());
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700894 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
Jiwen 'Steve' Caiff675b72018-10-09 18:08:29 -0700899 // Detached buffer handle can be use to construct a new BufferHubBuffer
900 // object.
901 auto b1 = BufferHubBuffer::Import(std::move(h1));
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700902 EXPECT_FALSE(h1.valid());
903 EXPECT_TRUE(b1->IsValid());
904 int b1_id = b1->id();
Fan Xu021776e2018-12-05 13:34:48 -0800905 EXPECT_EQ(b1_id, p1_id); */
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700906}