blob: 9c06fae06439e76743adb42fa5b7d493b9d47010 [file] [log] [blame]
Igor Murashkin7ea777f2013-11-18 16:58:36 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "IGraphicBufferProducer_test"
18//#define LOG_NDEBUG 0
19
20#include <gtest/gtest.h>
21
22#include <utils/String8.h>
23#include <utils/threads.h>
24
25#include <ui/GraphicBuffer.h>
Igor Murashkin7ea777f2013-11-18 16:58:36 -080026
27#include <gui/BufferQueue.h>
28
29#include <vector>
30
31#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
32#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
33
34#define TEST_TOKEN ((IBinder*)(NULL))
35#define TEST_API NATIVE_WINDOW_API_CPU
36#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
37#define TEST_CONTROLLED_BY_APP false
38#define TEST_PRODUCER_USAGE_BITS (0)
39
40// TODO: Make these public constants in a header
41enum {
42 // Default dimensions before setDefaultBufferSize is called
43 DEFAULT_WIDTH = 1,
44 DEFAULT_HEIGHT = 1,
45
46 // Default format before setDefaultBufferFormat is called
47 DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888,
48
49 // Default transform hint before setTransformHint is called
50 DEFAULT_TRANSFORM_HINT = 0,
51};
52
53namespace android {
54
55namespace {
56// Parameters for a generic "valid" input for queueBuffer.
57const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
58const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
59const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
60const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
61const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
62const bool QUEUE_BUFFER_INPUT_ASYNC = false;
63const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
64}; // namespace anonymous
65
66struct DummyConsumer : public BnConsumerListener {
67 virtual void onFrameAvailable() {}
68 virtual void onBuffersReleased() {}
Jesse Hall49bfda12014-03-13 15:09:17 -070069 virtual void onSidebandStreamChanged() {}
Igor Murashkin7ea777f2013-11-18 16:58:36 -080070};
71
72class IGraphicBufferProducerTest : public ::testing::Test {
73protected:
74
75 IGraphicBufferProducerTest() {}
76
77 virtual void SetUp() {
78 const ::testing::TestInfo* const testInfo =
79 ::testing::UnitTest::GetInstance()->current_test_info();
80 ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
81 testInfo->name());
82
Igor Murashkin7ea777f2013-11-18 16:58:36 -080083 mDC = new DummyConsumer;
84
Dan Stoza5603a2f2014-04-07 13:41:37 -070085 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
Igor Murashkin7ea777f2013-11-18 16:58:36 -080086
87 // Test check: Can't connect producer if no consumer yet
88 ASSERT_EQ(NO_INIT, TryConnectProducer());
89
90 // Must connect consumer before producer connects will succeed.
91 ASSERT_OK(mConsumer->consumerConnect(mDC, /*controlledByApp*/false));
92 }
93
94 virtual void TearDown() {
95 const ::testing::TestInfo* const testInfo =
96 ::testing::UnitTest::GetInstance()->current_test_info();
97 ALOGV("End test: %s.%s", testInfo->test_case_name(),
98 testInfo->name());
99 }
100
101 status_t TryConnectProducer() {
102 IGraphicBufferProducer::QueueBufferOutput output;
103 return mProducer->connect(TEST_TOKEN,
104 TEST_API,
105 TEST_CONTROLLED_BY_APP,
106 &output);
107 // TODO: use params to vary token, api, producercontrolledbyapp, etc
108 }
109
110 // Connect to a producer in a 'correct' fashion.
111 // Precondition: Consumer is connected.
112 void ConnectProducer() {
113 ASSERT_OK(TryConnectProducer());
114 }
115
116 // Create a generic "valid" input for queueBuffer
117 // -- uses the default buffer format, width, etc.
118 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
119 return QueueBufferInputBuilder().build();
120 }
121
122 // Builder pattern to slightly vary *almost* correct input
123 // -- avoids copying and pasting
124 struct QueueBufferInputBuilder {
125 QueueBufferInputBuilder() {
126 timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
127 isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
128 crop = QUEUE_BUFFER_INPUT_RECT;
129 scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
130 transform = QUEUE_BUFFER_INPUT_TRANSFORM;
131 async = QUEUE_BUFFER_INPUT_ASYNC;
132 fence = QUEUE_BUFFER_INPUT_FENCE;
133 }
134
135 IGraphicBufferProducer::QueueBufferInput build() {
136 return IGraphicBufferProducer::QueueBufferInput(
137 timestamp,
138 isAutoTimestamp,
139 crop,
140 scalingMode,
141 transform,
142 async,
143 fence);
144 }
145
146 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
147 this->timestamp = timestamp;
148 return *this;
149 }
150
151 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
152 this->isAutoTimestamp = isAutoTimestamp;
153 return *this;
154 }
155
156 QueueBufferInputBuilder& setCrop(Rect crop) {
157 this->crop = crop;
158 return *this;
159 }
160
161 QueueBufferInputBuilder& setScalingMode(int scalingMode) {
162 this->scalingMode = scalingMode;
163 return *this;
164 }
165
166 QueueBufferInputBuilder& setTransform(uint32_t transform) {
167 this->transform = transform;
168 return *this;
169 }
170
171 QueueBufferInputBuilder& setAsync(bool async) {
172 this->async = async;
173 return *this;
174 }
175
176 QueueBufferInputBuilder& setFence(sp<Fence> fence) {
177 this->fence = fence;
178 return *this;
179 }
180
181 private:
182 int64_t timestamp;
183 bool isAutoTimestamp;
184 Rect crop;
185 int scalingMode;
186 uint32_t transform;
187 int async;
188 sp<Fence> fence;
189 }; // struct QueueBufferInputBuilder
190
191 // To easily store dequeueBuffer results into containers
192 struct DequeueBufferResult {
193 int slot;
194 sp<Fence> fence;
195 };
196
197 status_t dequeueBuffer(bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage, DequeueBufferResult* result) {
198 return mProducer->dequeueBuffer(&result->slot, &result->fence, async, w, h, format, usage);
199 }
200
201private: // hide from test body
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800202 sp<DummyConsumer> mDC;
203
204protected: // accessible from test body
205 sp<IGraphicBufferProducer> mProducer;
206 sp<IGraphicBufferConsumer> mConsumer;
207};
208
209TEST_F(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
210 IGraphicBufferProducer::QueueBufferOutput output;
211
212 // NULL output returns BAD_VALUE
213 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
214 TEST_API,
215 TEST_CONTROLLED_BY_APP,
216 /*output*/NULL));
217
218 // Invalid API returns bad value
219 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
220 /*api*/0xDEADBEEF,
221 TEST_CONTROLLED_BY_APP,
222 &output));
223
224 // TODO: get a token from a dead process somehow
225}
226
227TEST_F(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
228 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
229
230 // Can't connect when there is already a producer connected
231 IGraphicBufferProducer::QueueBufferOutput output;
232 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
233 TEST_API,
234 TEST_CONTROLLED_BY_APP,
235 &output));
236
237 ASSERT_OK(mConsumer->consumerDisconnect());
238 // Can't connect when IGBP is abandoned
239 EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
240 TEST_API,
241 TEST_CONTROLLED_BY_APP,
242 &output));
243}
244
245TEST_F(IGraphicBufferProducerTest, Disconnect_Succeeds) {
246 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
247
248 ASSERT_OK(mProducer->disconnect(TEST_API));
249}
250
251
252TEST_F(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
253 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
254
255 // Must disconnect with same API number
256 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
257 // API must not be out of range
258 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
259
260 // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
261}
262
263TEST_F(IGraphicBufferProducerTest, Query_Succeeds) {
264 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
265
266 // TODO: Make these constants in header
267 const int DEFAULT_CONSUMER_USAGE_BITS = 0;
268
269 int value = -1;
270 EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
271 EXPECT_EQ(DEFAULT_WIDTH, value);
272
273 EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
274 EXPECT_EQ(DEFAULT_HEIGHT, value);
275
276 EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
277 EXPECT_EQ(DEFAULT_FORMAT, value);
278
279 EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
280 EXPECT_LE(0, value);
281 EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
282
283 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
284 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
285
286 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
287 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
288
289}
290
291TEST_F(IGraphicBufferProducerTest, Query_ReturnsError) {
292 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
293
294 // One past the end of the last 'query' enum value. Update this if we add more enums.
295 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_CONSUMER_USAGE_BITS + 1;
296
297 int value;
298 // What was out of range
299 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
300 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
301 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
302
303 // Some enums from window.h are 'invalid'
304 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
305 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
306 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
307 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
308 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
309 // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
310
311 // Value was NULL
312 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/NULL));
313
314 ASSERT_OK(mConsumer->consumerDisconnect());
315
316 // BQ was abandoned
317 EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
318
319 // TODO: other things in window.h that are supported by Surface::query
320 // but not by BufferQueue::query
321}
322
323// TODO: queue under more complicated situations not involving just a single buffer
324TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) {
325 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
326
327 int dequeuedSlot = -1;
328 sp<Fence> dequeuedFence;
329
330 // XX: OK to assume first call returns this flag or not? Not really documented.
331 ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
332 mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
333 QUEUE_BUFFER_INPUT_ASYNC,
334 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
335 TEST_PRODUCER_USAGE_BITS));
336
337 EXPECT_LE(0, dequeuedSlot);
338 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
339
340 // Request the buffer (pre-requisite for queueing)
341 sp<GraphicBuffer> dequeuedBuffer;
342 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
343
344 // A generic "valid" input
345 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
346 IGraphicBufferProducer::QueueBufferOutput output;
347
348 // Queue the buffer back into the BQ
349 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
350
351 {
352 uint32_t width;
353 uint32_t height;
354 uint32_t transformHint;
355 uint32_t numPendingBuffers;
356
357 output.deflate(&width, &height, &transformHint, &numPendingBuffers);
358
359 EXPECT_EQ(DEFAULT_WIDTH, width);
360 EXPECT_EQ(DEFAULT_HEIGHT, height);
361 EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint);
362 EXPECT_EQ(1, numPendingBuffers); // since queueBuffer was called exactly once
363 }
364
365 // Buffer was not in the dequeued state
366 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
367}
368
369TEST_F(IGraphicBufferProducerTest, Queue_ReturnsError) {
370 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
371
372 // Invalid slot number
373 {
374 // A generic "valid" input
375 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
376 IGraphicBufferProducer::QueueBufferOutput output;
377
378 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
379 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
380 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
381 input, &output));
382 }
383
384 // Slot was not in the dequeued state (all slots start out in Free state)
385 {
386 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
387 IGraphicBufferProducer::QueueBufferOutput output;
388
389 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
390 }
391
392 // Put the slot into the "dequeued" state for the rest of the test
393 int dequeuedSlot = -1;
394 sp<Fence> dequeuedFence;
395
396 ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
397 mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
398 QUEUE_BUFFER_INPUT_ASYNC,
399 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
400 TEST_PRODUCER_USAGE_BITS));
401
402 // Slot was enqueued without requesting a buffer
403 {
404 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
405 IGraphicBufferProducer::QueueBufferOutput output;
406
407 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
408 }
409
410 // Request the buffer so that the rest of the tests don't fail on earlier checks.
411 sp<GraphicBuffer> dequeuedBuffer;
412 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
413
414 // Fence was NULL
415 {
416 sp<Fence> nullFence = NULL;
417
418 IGraphicBufferProducer::QueueBufferInput input =
419 QueueBufferInputBuilder().setFence(nullFence).build();
420 IGraphicBufferProducer::QueueBufferOutput output;
421
422 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
423 }
424
425 // Scaling mode was unknown
426 {
427 IGraphicBufferProducer::QueueBufferInput input =
428 QueueBufferInputBuilder().setScalingMode(-1).build();
429 IGraphicBufferProducer::QueueBufferOutput output;
430
431 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
432
433 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
434
435 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
436 }
437
438 // Crop rect is out of bounds of the buffer dimensions
439 {
440 IGraphicBufferProducer::QueueBufferInput input =
441 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
442 .build();
443 IGraphicBufferProducer::QueueBufferOutput output;
444
445 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
446 }
447
448 // Abandon the buffer queue so that the last test fails
449 ASSERT_OK(mConsumer->consumerDisconnect());
450
451 // The buffer queue has been abandoned.
452 {
453 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
454 IGraphicBufferProducer::QueueBufferOutput output;
455
456 EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
457 }
458}
459
460TEST_F(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
461 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
462
463 int dequeuedSlot = -1;
464 sp<Fence> dequeuedFence;
465
466 ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
467 mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
468 QUEUE_BUFFER_INPUT_ASYNC,
469 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
470 TEST_PRODUCER_USAGE_BITS));
471
472 // No return code, but at least test that it doesn't blow up...
473 // TODO: add a return code
474 mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
475}
476
477TEST_F(IGraphicBufferProducerTest, SetBufferCount_Succeeds) {
478
479 // The producer does not wish to set a buffer count
480 EXPECT_OK(mProducer->setBufferCount(0)) << "bufferCount: " << 0;
481 // TODO: how to test "0" buffer count?
482
483 int minBuffers;
484 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minBuffers));
485
486 // The MIN_UNDEQUEUED_BUFFERS limit is exclusive, so need to increment by at least 1
487 minBuffers++;
488
489 ASSERT_OK(mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
490
491 std::vector<DequeueBufferResult> dequeueList;
492
493 // Should now be able to dequeue up to minBuffers times
494 for (int i = 0; i < minBuffers; ++i) {
495 DequeueBufferResult result;
496
497 EXPECT_LE(OK,
498 dequeueBuffer(QUEUE_BUFFER_INPUT_ASYNC,
499 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
500 TEST_PRODUCER_USAGE_BITS, &result))
501 << "iteration: " << i << ", slot: " << result.slot;
502
503 dequeueList.push_back(result);
504 }
505
506 // Cancel every buffer, so we can set buffer count again
507 for (int i = 0; i < minBuffers; ++i) {
508 DequeueBufferResult& result = dequeueList[i];
509 mProducer->cancelBuffer(result.slot, result.fence);
510 }
511
512 ASSERT_OK(mProducer->setBufferCount(BufferQueue::NUM_BUFFER_SLOTS));
513
514 // Should now be able to dequeue up to NUM_BUFFER_SLOTS times
515 for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; ++i) {
516 int dequeuedSlot = -1;
517 sp<Fence> dequeuedFence;
518
519 EXPECT_LE(OK,
520 mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
521 QUEUE_BUFFER_INPUT_ASYNC,
522 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
523 TEST_PRODUCER_USAGE_BITS))
524 << "iteration: " << i << ", slot: " << dequeuedSlot;
525 }
526}
527
528TEST_F(IGraphicBufferProducerTest, SetBufferCount_Fails) {
529 int minBuffers;
530 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minBuffers));
531
532 // The MIN_UNDEQUEUED_BUFFERS limit is exclusive, so need to increment by at least 1
533 minBuffers++;
534
535 // Buffer count was out of range
536 EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(-1)) << "bufferCount: " << -1;
537 EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(minBuffers - 1)) << "bufferCount: " << minBuffers - 1;
538 EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(BufferQueue::NUM_BUFFER_SLOTS + 1))
539 << "bufferCount: " << BufferQueue::NUM_BUFFER_SLOTS + 1;
540
541 // Pre-requisite to fail out a valid setBufferCount call
542 {
543 int dequeuedSlot = -1;
544 sp<Fence> dequeuedFence;
545
546 ASSERT_LE(OK,
547 mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
548 QUEUE_BUFFER_INPUT_ASYNC,
549 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
550 TEST_PRODUCER_USAGE_BITS))
551 << "slot: " << dequeuedSlot;
552 }
553
554 // Client has one or more buffers dequeued
555 EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
556
557 // Abandon buffer queue
558 ASSERT_OK(mConsumer->consumerDisconnect());
559
560 // Fail because the buffer queue was abandoned
561 EXPECT_EQ(NO_INIT, mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
562
563}
564
565} // namespace android