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