• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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