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