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