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