1 #include <private/dvr/buffer_hub_queue_producer.h>
2
3 #include <base/logging.h>
4 #include <gui/IProducerListener.h>
5 #include <gui/Surface.h>
6
7 #include <gtest/gtest.h>
8
9 namespace android {
10 namespace dvr {
11
12 namespace {
13
14 // Default dimensions before setDefaultBufferSize is called by the consumer.
15 constexpr uint32_t kDefaultWidth = 1;
16 constexpr uint32_t kDefaultHeight = 1;
17
18 // Default format before setDefaultBufferFormat is called by the consumer.
19 constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
20 constexpr int kDefaultConsumerUsageBits = 0;
21
22 // Default transform hint before setTransformHint is called by the consumer.
23 constexpr uint32_t kDefaultTransformHint = 0;
24
25 constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
26 constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
27 constexpr int kTestApiInvalid = 0xDEADBEEF;
28 constexpr int kTestProducerUsageBits = 0;
29 constexpr bool kTestControlledByApp = true;
30
31 // Builder pattern to slightly vary *almost* correct input
32 // -- avoids copying and pasting
33 struct QueueBufferInputBuilder {
buildandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder34 IGraphicBufferProducer::QueueBufferInput build() {
35 return IGraphicBufferProducer::QueueBufferInput(
36 mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
37 mTransform, mFence);
38 }
39
setTimestampandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder40 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
41 this->mTimestamp = timestamp;
42 return *this;
43 }
44
setIsAutoTimestampandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder45 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
46 this->mIsAutoTimestamp = isAutoTimestamp;
47 return *this;
48 }
49
setDataSpaceandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder50 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
51 this->mDataSpace = dataSpace;
52 return *this;
53 }
54
setCropandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder55 QueueBufferInputBuilder& setCrop(Rect crop) {
56 this->mCrop = crop;
57 return *this;
58 }
59
setScalingModeandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder60 QueueBufferInputBuilder& setScalingMode(int scalingMode) {
61 this->mScalingMode = scalingMode;
62 return *this;
63 }
64
setTransformandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder65 QueueBufferInputBuilder& setTransform(uint32_t transform) {
66 this->mTransform = transform;
67 return *this;
68 }
69
setFenceandroid::dvr::__anon369a2e570111::QueueBufferInputBuilder70 QueueBufferInputBuilder& setFence(sp<Fence> fence) {
71 this->mFence = fence;
72 return *this;
73 }
74
75 private:
76 int64_t mTimestamp{1384888611};
77 bool mIsAutoTimestamp{false};
78 android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
79 Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
80 int mScalingMode{0};
81 uint32_t mTransform{0};
82 sp<Fence> mFence{Fence::NO_FENCE};
83 };
84
85 // This is a test that covers our implementation of bufferhubqueue-based
86 // IGraphicBufferProducer.
87 class BufferHubQueueProducerTest : public ::testing::Test {
88 protected:
SetUp()89 virtual void SetUp() {
90 const ::testing::TestInfo* const testInfo =
91 ::testing::UnitTest::GetInstance()->current_test_info();
92 ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
93 testInfo->name());
94
95 mProducer = BufferHubQueueProducer::Create();
96 ASSERT_TRUE(mProducer != nullptr);
97 mSurface = new Surface(mProducer, true);
98 ASSERT_TRUE(mSurface != nullptr);
99 }
100
101 // Connect to a producer in a 'correct' fashion.
ConnectProducer()102 void ConnectProducer() {
103 IGraphicBufferProducer::QueueBufferOutput output;
104 // Can connect the first time.
105 ASSERT_EQ(NO_ERROR, mProducer->connect(kDummyListener, kTestApi,
106 kTestControlledByApp, &output));
107 }
108
109 // Dequeue a buffer in a 'correct' fashion.
110 // Precondition: Producer is connected.
DequeueBuffer(int * outSlot)111 void DequeueBuffer(int* outSlot) {
112 sp<Fence> fence;
113 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
114 }
115
DequeueBuffer(int * outSlot,sp<Fence> * outFence)116 void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
117 ASSERT_NE(nullptr, outSlot);
118 ASSERT_NE(nullptr, outFence);
119
120 int ret = mProducer->dequeueBuffer(outSlot, outFence, kDefaultWidth,
121 kDefaultHeight, kDefaultFormat,
122 kTestProducerUsageBits, nullptr);
123 // BUFFER_NEEDS_REALLOCATION can be either on or off.
124 ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);
125
126 // Slot number should be in boundary.
127 ASSERT_LE(0, *outSlot);
128 ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
129 }
130
131 // Create a generic "valid" input for queueBuffer
132 // -- uses the default buffer format, width, etc.
CreateBufferInput()133 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
134 return QueueBufferInputBuilder().build();
135 }
136
137 const sp<IProducerListener> kDummyListener{new DummyProducerListener};
138
139 sp<BufferHubQueueProducer> mProducer;
140 sp<Surface> mSurface;
141 };
142
TEST_F(BufferHubQueueProducerTest,ConnectFirst_ReturnsError)143 TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
144 IGraphicBufferProducer::QueueBufferOutput output;
145
146 // NULL output returns BAD_VALUE
147 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
148 kTestControlledByApp, nullptr));
149
150 // Invalid API returns bad value
151 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApiInvalid,
152 kTestControlledByApp, &output));
153 }
154
TEST_F(BufferHubQueueProducerTest,ConnectAgain_ReturnsError)155 TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
156 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
157
158 // Can't connect when there is already a producer connected.
159 IGraphicBufferProducer::QueueBufferOutput output;
160 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
161 kTestControlledByApp, &output));
162 }
163
TEST_F(BufferHubQueueProducerTest,Disconnect_Succeeds)164 TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
165 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
166
167 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
168 }
169
TEST_F(BufferHubQueueProducerTest,Disconnect_ReturnsError)170 TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
171 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
172
173 // Must disconnect with same API number
174 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
175 // API must not be out of range
176 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
177 }
178
TEST_F(BufferHubQueueProducerTest,Query_Succeeds)179 TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
180 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
181
182 int32_t value = -1;
183 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
184 EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
185
186 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
187 EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
188
189 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
190 EXPECT_EQ(kDefaultFormat, value);
191
192 EXPECT_EQ(NO_ERROR,
193 mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
194 EXPECT_LE(0, value);
195 EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, static_cast<size_t>(value));
196
197 EXPECT_EQ(NO_ERROR,
198 mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
199 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
200
201 EXPECT_EQ(NO_ERROR,
202 mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
203 EXPECT_EQ(kDefaultConsumerUsageBits, value);
204 }
205
TEST_F(BufferHubQueueProducerTest,Query_ReturnsError)206 TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
207 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
208
209 // One past the end of the last 'query' enum value. Update this if we add more
210 // enums.
211 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
212
213 int value;
214 // What was out of range
215 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
216 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
217 EXPECT_EQ(BAD_VALUE,
218 mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
219
220 // Some enums from window.h are 'invalid'
221 EXPECT_EQ(BAD_VALUE,
222 mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
223 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
224 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
225 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
226 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
227
228 // Value was NULL
229 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
230 }
231
TEST_F(BufferHubQueueProducerTest,Queue_Succeeds)232 TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
233 int slot = -1;
234
235 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
236 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
237
238 // Request the buffer (pre-requisite for queueing)
239 sp<GraphicBuffer> buffer;
240 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
241
242 // A generic "valid" input
243 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
244 IGraphicBufferProducer::QueueBufferOutput output;
245
246 // Queue the buffer back into the BQ
247 ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));
248
249 EXPECT_EQ(kDefaultWidth, output.width);
250 EXPECT_EQ(kDefaultHeight, output.height);
251 EXPECT_EQ(kDefaultTransformHint, output.transformHint);
252
253 // BufferHubQueue delivers buffers to consumer immediately.
254 EXPECT_EQ(0u, output.numPendingBuffers);
255
256 // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
257 // be a SurfaceFlinger specific optimization.
258 EXPECT_EQ(0u, output.nextFrameNumber);
259
260 // Buffer was not in the dequeued state
261 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
262 }
263
264 // Test invalid slot number
TEST_F(BufferHubQueueProducerTest,QueueInvalidSlot_ReturnsError)265 TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
266 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
267
268 // A generic "valid" input
269 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
270 IGraphicBufferProducer::QueueBufferOutput output;
271
272 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
273 EXPECT_EQ(BAD_VALUE,
274 mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
275 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
276 input, &output));
277 }
278
279 // Slot was not in the dequeued state (all slots start out in Free state)
TEST_F(BufferHubQueueProducerTest,QueueNotDequeued_ReturnsError)280 TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
281 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
282
283 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
284 IGraphicBufferProducer::QueueBufferOutput output;
285
286 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
287 }
288
289 // Slot was enqueued without requesting a buffer
TEST_F(BufferHubQueueProducerTest,QueueNotRequested_ReturnsError)290 TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
291 int slot = -1;
292
293 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
294 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
295
296 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
297 IGraphicBufferProducer::QueueBufferOutput output;
298
299 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
300 }
301
302 // Test when fence was NULL
TEST_F(BufferHubQueueProducerTest,QueueNoFence_ReturnsError)303 TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
304 int slot = -1;
305
306 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
307 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
308
309 sp<GraphicBuffer> buffer;
310 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
311
312 sp<Fence> nullFence = NULL;
313
314 IGraphicBufferProducer::QueueBufferInput input =
315 QueueBufferInputBuilder().setFence(nullFence).build();
316 IGraphicBufferProducer::QueueBufferOutput output;
317
318 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
319 }
320
321 // Test scaling mode was invalid
TEST_F(BufferHubQueueProducerTest,QueueTestInvalidScalingMode_ReturnsError)322 TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
323 int slot = -1;
324
325 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
326 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
327
328 sp<GraphicBuffer> buffer;
329 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
330
331 IGraphicBufferProducer::QueueBufferInput input =
332 QueueBufferInputBuilder().setScalingMode(-1).build();
333 IGraphicBufferProducer::QueueBufferOutput output;
334
335 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
336
337 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
338
339 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
340 }
341
342 // Test crop rect is out of bounds of the buffer dimensions
TEST_F(BufferHubQueueProducerTest,QueueCropOutOfBounds_ReturnsError)343 TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
344 int slot = -1;
345
346 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
347 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
348
349 sp<GraphicBuffer> buffer;
350 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
351
352 IGraphicBufferProducer::QueueBufferInput input =
353 QueueBufferInputBuilder()
354 .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
355 .build();
356 IGraphicBufferProducer::QueueBufferOutput output;
357
358 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
359 }
360
TEST_F(BufferHubQueueProducerTest,CancelBuffer_Succeeds)361 TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
362 int slot = -1;
363 sp<Fence> fence;
364
365 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
366 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
367
368 // Should be able to cancel buffer after a dequeue.
369 EXPECT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));
370 }
371
TEST_F(BufferHubQueueProducerTest,SetMaxDequeuedBufferCount_Succeeds)372 TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
373 return;
374 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
375
376 int minUndequeuedBuffers;
377 ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
378 &minUndequeuedBuffers));
379
380 const int minBuffers = 1;
381 const int maxBuffers =
382 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
383
384 ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
385 << "async mode: " << false;
386 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(minBuffers))
387 << "bufferCount: " << minBuffers;
388
389 // Should now be able to dequeue up to minBuffers times
390 // Should now be able to dequeue up to maxBuffers times
391 int slot = -1;
392 for (int i = 0; i < minBuffers; ++i) {
393 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
394 }
395
396 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers));
397
398 // queue the first buffer to enable max dequeued buffer count checking
399 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
400 IGraphicBufferProducer::QueueBufferOutput output;
401 sp<GraphicBuffer> buffer;
402 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
403 ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));
404
405 sp<Fence> fence;
406 for (int i = 0; i < maxBuffers; ++i) {
407 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
408 }
409
410 // Cancel a buffer, so we can decrease the buffer count
411 ASSERT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));
412
413 // Should now be able to decrease the max dequeued count by 1
414 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
415 }
416
TEST_F(BufferHubQueueProducerTest,SetMaxDequeuedBufferCount_Fails)417 TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
418 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
419
420 int minUndequeuedBuffers;
421 ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
422 &minUndequeuedBuffers));
423
424 const int minBuffers = 1;
425 const int maxBuffers =
426 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
427
428 ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
429 << "async mode: " << false;
430 // Buffer count was out of range
431 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
432 << "bufferCount: " << 0;
433 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
434 << "bufferCount: " << maxBuffers + 1;
435
436 // Set max dequeue count to 2
437 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(2));
438 // Dequeue 2 buffers
439 int slot = -1;
440 sp<Fence> fence;
441 for (int i = 0; i < 2; i++) {
442 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
443 (mProducer->dequeueBuffer(
444 &slot, &fence, kDefaultWidth, kDefaultHeight,
445 kDefaultFormat, kTestProducerUsageBits, nullptr)))
446 << "slot: " << slot;
447 }
448
449 // Client has too many buffers dequeued
450 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
451 << "bufferCount: " << minBuffers;
452 }
453
TEST_F(BufferHubQueueProducerTest,DisconnectedProducerReturnsError_dequeueBuffer)454 TEST_F(BufferHubQueueProducerTest,
455 DisconnectedProducerReturnsError_dequeueBuffer) {
456 int slot = -1;
457 sp<Fence> fence;
458
459 ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
460 kDefaultHeight, kDefaultFormat,
461 kTestProducerUsageBits, nullptr));
462 }
463
TEST_F(BufferHubQueueProducerTest,DisconnectedProducerReturnsError_requestBuffer)464 TEST_F(BufferHubQueueProducerTest,
465 DisconnectedProducerReturnsError_requestBuffer) {
466 int slot = -1;
467 sp<GraphicBuffer> buffer;
468
469 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
470 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
471
472 // Shouldn't be able to request buffer after disconnect.
473 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
474 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
475 }
476
TEST_F(BufferHubQueueProducerTest,DisconnectedProducerReturnsError_queueBuffer)477 TEST_F(BufferHubQueueProducerTest,
478 DisconnectedProducerReturnsError_queueBuffer) {
479 int slot = -1;
480 sp<GraphicBuffer> buffer;
481
482 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
483 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
484 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
485
486 // A generic "valid" input
487 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
488 IGraphicBufferProducer::QueueBufferOutput output;
489
490 // Shouldn't be able to queue buffer after disconnect.
491 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
492 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
493 }
494
TEST_F(BufferHubQueueProducerTest,DisconnectedProducerReturnsError_cancelBuffer)495 TEST_F(BufferHubQueueProducerTest,
496 DisconnectedProducerReturnsError_cancelBuffer) {
497 int slot = -1;
498 sp<GraphicBuffer> buffer;
499
500 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
501 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
502 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
503
504 // Shouldn't be able to cancel buffer after disconnect.
505 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
506 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
507 }
508
509 } // namespace
510
511 } // namespace dvr
512 } // namespace android
513