IGraphicBufferProducer_test.cpp revision 5603a2fbbd1aae74c4635e2f600819fb05d112e0
1/* 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> 26 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() {} 69 virtual void onSidebandStreamChanged() {} 70}; 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 83 mDC = new DummyConsumer; 84 85 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 86 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 202 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 566