1 #include <base/logging.h> 2 #include <gui/BufferHubProducer.h> 3 #include <gui/IProducerListener.h> 4 #include <gui/Surface.h> 5 #include <pdx/default_transport/channel_parcelable.h> 6 7 #include <gtest/gtest.h> 8 9 namespace android { 10 namespace dvr { 11 12 using pdx::LocalHandle; 13 14 namespace { 15 16 // Default dimensions before setDefaultBufferSize is called by the consumer. 17 constexpr uint32_t kDefaultWidth = 1; 18 constexpr uint32_t kDefaultHeight = 1; 19 20 // Default format before setDefaultBufferFormat is called by the consumer. 21 constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888; 22 constexpr int kDefaultConsumerUsageBits = 0; 23 24 // Default transform hint before setTransformHint is called by the consumer. 25 constexpr uint32_t kDefaultTransformHint = 0; 26 27 constexpr int kTestApi = NATIVE_WINDOW_API_CPU; 28 constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL; 29 constexpr int kTestApiInvalid = 0xDEADBEEF; 30 constexpr int kTestProducerUsageBits = 0; 31 constexpr bool kTestControlledByApp = true; 32 33 // Builder pattern to slightly vary *almost* correct input 34 // -- avoids copying and pasting 35 struct QueueBufferInputBuilder { 36 IGraphicBufferProducer::QueueBufferInput build() { 37 return IGraphicBufferProducer::QueueBufferInput( 38 mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode, 39 mTransform, mFence); 40 } 41 42 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) { 43 this->mTimestamp = timestamp; 44 return *this; 45 } 46 47 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) { 48 this->mIsAutoTimestamp = isAutoTimestamp; 49 return *this; 50 } 51 52 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) { 53 this->mDataSpace = dataSpace; 54 return *this; 55 } 56 57 QueueBufferInputBuilder& setCrop(Rect crop) { 58 this->mCrop = crop; 59 return *this; 60 } 61 62 QueueBufferInputBuilder& setScalingMode(int scalingMode) { 63 this->mScalingMode = scalingMode; 64 return *this; 65 } 66 67 QueueBufferInputBuilder& setTransform(uint32_t transform) { 68 this->mTransform = transform; 69 return *this; 70 } 71 72 QueueBufferInputBuilder& setFence(sp<Fence> fence) { 73 this->mFence = fence; 74 return *this; 75 } 76 77 private: 78 int64_t mTimestamp{1384888611}; 79 bool mIsAutoTimestamp{false}; 80 android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN}; 81 Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)}; 82 int mScalingMode{0}; 83 uint32_t mTransform{0}; 84 sp<Fence> mFence{Fence::NO_FENCE}; 85 }; 86 87 // This is a test that covers our implementation of bufferhubqueue-based 88 // IGraphicBufferProducer. 89 class BufferHubQueueProducerTest : public ::testing::Test { 90 protected: 91 virtual void SetUp() { 92 const ::testing::TestInfo* const testInfo = 93 ::testing::UnitTest::GetInstance()->current_test_info(); 94 ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(), 95 testInfo->name()); 96 97 auto config = ProducerQueueConfigBuilder().Build(); 98 auto queue = ProducerQueue::Create(config, UsagePolicy{}); 99 ASSERT_TRUE(queue != nullptr); 100 101 mProducer = BufferHubProducer::Create(std::move(queue)); 102 ASSERT_TRUE(mProducer != nullptr); 103 mSurface = new Surface(mProducer, true); 104 ASSERT_TRUE(mSurface != nullptr); 105 } 106 107 // Connect to a producer in a 'correct' fashion. 108 void ConnectProducer() { 109 IGraphicBufferProducer::QueueBufferOutput output; 110 // Can connect the first time. 111 ASSERT_EQ(OK, mProducer->connect(kDummyListener, kTestApi, 112 kTestControlledByApp, &output)); 113 } 114 115 // Dequeue a buffer in a 'correct' fashion. 116 // Precondition: Producer is connected. 117 void DequeueBuffer(int* outSlot) { 118 sp<Fence> fence; 119 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence)); 120 } 121 122 void DequeueBuffer(int* outSlot, sp<Fence>* outFence) { 123 ASSERT_NE(nullptr, outSlot); 124 ASSERT_NE(nullptr, outFence); 125 126 int ret = mProducer->dequeueBuffer( 127 outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat, 128 kTestProducerUsageBits, nullptr, nullptr); 129 // BUFFER_NEEDS_REALLOCATION can be either on or off. 130 ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret); 131 132 // Slot number should be in boundary. 133 ASSERT_LE(0, *outSlot); 134 ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot); 135 } 136 137 // Create a generic "valid" input for queueBuffer 138 // -- uses the default buffer format, width, etc. 139 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() { 140 return QueueBufferInputBuilder().build(); 141 } 142 143 const sp<IProducerListener> kDummyListener{new DummyProducerListener}; 144 145 sp<BufferHubProducer> mProducer; 146 sp<Surface> mSurface; 147 }; 148 149 TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) { 150 IGraphicBufferProducer::QueueBufferOutput output; 151 152 // NULL output returns BAD_VALUE 153 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi, 154 kTestControlledByApp, nullptr)); 155 156 // Invalid API returns bad value 157 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApiInvalid, 158 kTestControlledByApp, &output)); 159 } 160 161 TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) { 162 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 163 164 // Can't connect when there is already a producer connected. 165 IGraphicBufferProducer::QueueBufferOutput output; 166 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi, 167 kTestControlledByApp, &output)); 168 } 169 170 TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) { 171 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 172 173 ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); 174 } 175 176 TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) { 177 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 178 179 // Must disconnect with same API number 180 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther)); 181 // API must not be out of range 182 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid)); 183 } 184 185 TEST_F(BufferHubQueueProducerTest, Query_Succeeds) { 186 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 187 188 int32_t value = -1; 189 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value)); 190 EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value)); 191 192 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value)); 193 EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value)); 194 195 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value)); 196 EXPECT_EQ(kDefaultFormat, value); 197 198 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value)); 199 EXPECT_LE(0, value); 200 EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value); 201 202 EXPECT_EQ(OK, 203 mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value)); 204 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue 205 206 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value)); 207 EXPECT_EQ(kDefaultConsumerUsageBits, value); 208 } 209 210 TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) { 211 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 212 213 // One past the end of the last 'query' enum value. Update this if we add more 214 // enums. 215 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1; 216 217 int value; 218 // What was out of range 219 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value)); 220 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value)); 221 EXPECT_EQ(BAD_VALUE, 222 mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value)); 223 224 // Some enums from window.h are 'invalid' 225 EXPECT_EQ(BAD_VALUE, 226 mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value)); 227 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value)); 228 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value)); 229 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value)); 230 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value)); 231 232 // Value was NULL 233 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL)); 234 } 235 236 TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) { 237 int slot = -1; 238 239 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 240 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 241 242 // Request the buffer (pre-requisite for queueing) 243 sp<GraphicBuffer> buffer; 244 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 245 246 // A generic "valid" input 247 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 248 IGraphicBufferProducer::QueueBufferOutput output; 249 250 // Queue the buffer back into the BQ 251 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 252 253 EXPECT_EQ(kDefaultWidth, output.width); 254 EXPECT_EQ(kDefaultHeight, output.height); 255 EXPECT_EQ(kDefaultTransformHint, output.transformHint); 256 257 // BufferHubQueue delivers buffers to consumer immediately. 258 EXPECT_EQ(0u, output.numPendingBuffers); 259 260 // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to 261 // be a SurfaceFlinger specific optimization. 262 EXPECT_EQ(0u, output.nextFrameNumber); 263 264 // Buffer was not in the dequeued state 265 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 266 } 267 268 // Test invalid slot number 269 TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) { 270 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 271 272 // A generic "valid" input 273 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 274 IGraphicBufferProducer::QueueBufferOutput output; 275 276 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output)); 277 EXPECT_EQ(BAD_VALUE, 278 mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output)); 279 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS, 280 input, &output)); 281 } 282 283 // Slot was not in the dequeued state (all slots start out in Free state) 284 TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) { 285 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 286 287 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 288 IGraphicBufferProducer::QueueBufferOutput output; 289 290 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output)); 291 } 292 293 // Slot was enqueued without requesting a buffer 294 TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) { 295 int slot = -1; 296 297 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 298 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 299 300 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 301 IGraphicBufferProducer::QueueBufferOutput output; 302 303 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 304 } 305 306 // Test when fence was NULL 307 TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) { 308 int slot = -1; 309 310 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 311 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 312 313 sp<GraphicBuffer> buffer; 314 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 315 316 sp<Fence> nullFence = NULL; 317 318 IGraphicBufferProducer::QueueBufferInput input = 319 QueueBufferInputBuilder().setFence(nullFence).build(); 320 IGraphicBufferProducer::QueueBufferOutput output; 321 322 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 323 } 324 325 // Test scaling mode was invalid 326 TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) { 327 int slot = -1; 328 329 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 330 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 331 332 sp<GraphicBuffer> buffer; 333 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 334 335 IGraphicBufferProducer::QueueBufferInput input = 336 QueueBufferInputBuilder().setScalingMode(-1).build(); 337 IGraphicBufferProducer::QueueBufferOutput output; 338 339 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 340 341 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build(); 342 343 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 344 } 345 346 // Test crop rect is out of bounds of the buffer dimensions 347 TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) { 348 int slot = -1; 349 350 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 351 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 352 353 sp<GraphicBuffer> buffer; 354 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 355 356 IGraphicBufferProducer::QueueBufferInput input = 357 QueueBufferInputBuilder() 358 .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1)) 359 .build(); 360 IGraphicBufferProducer::QueueBufferOutput output; 361 362 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); 363 } 364 365 TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) { 366 int slot = -1; 367 sp<Fence> fence; 368 369 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 370 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence)); 371 372 // Should be able to cancel buffer after a dequeue. 373 EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence)); 374 } 375 376 TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) { 377 return; 378 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 379 380 int minUndequeuedBuffers; 381 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 382 &minUndequeuedBuffers)); 383 384 const int minBuffers = 1; 385 const int maxBuffers = 386 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers; 387 388 ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false; 389 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers)) 390 << "bufferCount: " << minBuffers; 391 392 // Should now be able to dequeue up to minBuffers times 393 // Should now be able to dequeue up to maxBuffers times 394 int slot = -1; 395 for (int i = 0; i < minBuffers; ++i) { 396 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 397 } 398 399 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers)); 400 401 // queue the first buffer to enable max dequeued buffer count checking 402 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 403 IGraphicBufferProducer::QueueBufferOutput output; 404 sp<GraphicBuffer> buffer; 405 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 406 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 407 408 sp<Fence> fence; 409 for (int i = 0; i < maxBuffers; ++i) { 410 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence)); 411 } 412 413 // Cancel a buffer, so we can decrease the buffer count 414 ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence)); 415 416 // Should now be able to decrease the max dequeued count by 1 417 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1)); 418 } 419 420 TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) { 421 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 422 423 int minUndequeuedBuffers; 424 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 425 &minUndequeuedBuffers)); 426 427 const int minBuffers = 1; 428 const int maxBuffers = 429 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers; 430 431 ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false; 432 // Buffer count was out of range 433 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0)) 434 << "bufferCount: " << 0; 435 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1)) 436 << "bufferCount: " << maxBuffers + 1; 437 438 // Set max dequeue count to 2 439 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2)); 440 // Dequeue 2 buffers 441 int slot = -1; 442 sp<Fence> fence; 443 for (int i = 0; i < 2; i++) { 444 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 445 (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, 446 kDefaultHeight, kDefaultFormat, 447 kTestProducerUsageBits, 448 nullptr, nullptr))) 449 << "slot: " << slot; 450 } 451 452 // Client has too many buffers dequeued 453 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1)) 454 << "bufferCount: " << minBuffers; 455 } 456 457 TEST_F(BufferHubQueueProducerTest, 458 DisconnectedProducerReturnsError_dequeueBuffer) { 459 int slot = -1; 460 sp<Fence> fence; 461 462 ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, 463 kDefaultHeight, kDefaultFormat, 464 kTestProducerUsageBits, 465 nullptr, nullptr)); 466 } 467 468 TEST_F(BufferHubQueueProducerTest, 469 DisconnectedProducerReturnsError_requestBuffer) { 470 int slot = -1; 471 sp<GraphicBuffer> buffer; 472 473 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 474 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 475 476 // Shouldn't be able to request buffer after disconnect. 477 ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); 478 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer)); 479 } 480 481 TEST_F(BufferHubQueueProducerTest, 482 DisconnectedProducerReturnsError_queueBuffer) { 483 int slot = -1; 484 sp<GraphicBuffer> buffer; 485 486 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 487 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 488 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 489 490 // A generic "valid" input 491 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 492 IGraphicBufferProducer::QueueBufferOutput output; 493 494 // Shouldn't be able to queue buffer after disconnect. 495 ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); 496 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output)); 497 } 498 499 TEST_F(BufferHubQueueProducerTest, 500 DisconnectedProducerReturnsError_cancelBuffer) { 501 int slot = -1; 502 sp<GraphicBuffer> buffer; 503 504 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 505 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 506 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 507 508 // Shouldn't be able to cancel buffer after disconnect. 509 ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); 510 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE)); 511 } 512 513 TEST_F(BufferHubQueueProducerTest, ConnectDisconnectReconnect) { 514 int slot = -1; 515 sp<GraphicBuffer> buffer; 516 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 517 IGraphicBufferProducer::QueueBufferOutput output; 518 519 EXPECT_NO_FATAL_FAILURE(ConnectProducer()); 520 521 constexpr int maxDequeuedBuffers = 1; 522 int minUndequeuedBuffers; 523 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 524 &minUndequeuedBuffers)); 525 EXPECT_EQ(OK, mProducer->setAsyncMode(false)); 526 EXPECT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers)); 527 528 int maxCapacity = maxDequeuedBuffers + minUndequeuedBuffers; 529 530 // Dequeue, request, and queue all buffers. 531 for (int i = 0; i < maxCapacity; i++) { 532 EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 533 EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 534 EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 535 } 536 537 // Disconnect then reconnect. 538 EXPECT_EQ(OK, mProducer->disconnect(kTestApi)); 539 EXPECT_NO_FATAL_FAILURE(ConnectProducer()); 540 541 // Dequeue, request, and queue all buffers. 542 for (int i = 0; i < maxCapacity; i++) { 543 EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); 544 EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 545 EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 546 } 547 548 EXPECT_EQ(OK, mProducer->disconnect(kTestApi)); 549 } 550 551 TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) { 552 // Connected producer cannot be taken out as a parcelable. 553 EXPECT_NO_FATAL_FAILURE(ConnectProducer()); 554 ProducerQueueParcelable producer_parcelable; 555 EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE); 556 557 // Create a valid dummy producer parcelable. 558 auto dummy_channel_parcelable = 559 std::make_unique<pdx::default_transport::ChannelParcelable>( 560 LocalHandle(0), LocalHandle(0), LocalHandle(0)); 561 EXPECT_TRUE(dummy_channel_parcelable->IsValid()); 562 ProducerQueueParcelable dummy_producer_parcelable( 563 std::move(dummy_channel_parcelable)); 564 EXPECT_TRUE(dummy_producer_parcelable.IsValid()); 565 566 // Disconnect producer can be taken out, but only to an invalid parcelable. 567 ASSERT_EQ(mProducer->disconnect(kTestApi), OK); 568 EXPECT_EQ(mProducer->TakeAsParcelable(&dummy_producer_parcelable), BAD_VALUE); 569 EXPECT_FALSE(producer_parcelable.IsValid()); 570 EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK); 571 EXPECT_TRUE(producer_parcelable.IsValid()); 572 573 // Should still be able to query buffer dimension after disconnect. 574 int32_t value = -1; 575 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value)); 576 EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth); 577 578 EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK); 579 EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight); 580 581 EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK); 582 EXPECT_EQ(value, kDefaultFormat); 583 584 // But connect to API will fail. 585 IGraphicBufferProducer::QueueBufferOutput output; 586 EXPECT_EQ(mProducer->connect(kDummyListener, kTestApi, kTestControlledByApp, 587 &output), 588 BAD_VALUE); 589 590 // Create a new producer from the parcelable and connect to kTestApi should 591 // succeed. 592 sp<BufferHubProducer> new_producer = 593 BufferHubProducer::Create(std::move(producer_parcelable)); 594 ASSERT_TRUE(new_producer != nullptr); 595 EXPECT_EQ(new_producer->connect(kDummyListener, kTestApi, 596 kTestControlledByApp, &output), 597 OK); 598 } 599 600 } // namespace 601 602 } // namespace dvr 603 } // namespace android 604