blob: fab10978d644e76a50c20425d85c9a6bd74334e0 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <base/logging.h>
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -08002#include <gui/BufferHubProducer.h>
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -07003#include <gui/IProducerListener.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08004#include <gui/Surface.h>
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -08005#include <pdx/default_transport/channel_parcelable.h>
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -07006
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08007#include <gtest/gtest.h>
8
9namespace android {
10namespace dvr {
11
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080012using pdx::LocalHandle;
13
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080014namespace {
15
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070016// Default dimensions before setDefaultBufferSize is called by the consumer.
17constexpr uint32_t kDefaultWidth = 1;
18constexpr uint32_t kDefaultHeight = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080019
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070020// Default format before setDefaultBufferFormat is called by the consumer.
21constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
22constexpr int kDefaultConsumerUsageBits = 0;
23
24// Default transform hint before setTransformHint is called by the consumer.
25constexpr uint32_t kDefaultTransformHint = 0;
26
27constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
28constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
29constexpr int kTestApiInvalid = 0xDEADBEEF;
30constexpr int kTestProducerUsageBits = 0;
31constexpr bool kTestControlledByApp = true;
32
33// Builder pattern to slightly vary *almost* correct input
34// -- avoids copying and pasting
35struct 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.
89class 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
Jiwen 'Steve' Cai639d4792018-04-05 16:49:05 -070097 auto config = ProducerQueueConfigBuilder().Build();
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080098 auto queue = ProducerQueue::Create(config, UsagePolicy{});
99 ASSERT_TRUE(queue != nullptr);
100
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800101 mProducer = BufferHubProducer::Create(std::move(queue));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700102 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.
Peiyong Lind8460c82020-07-28 16:04:22 -0700111 ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi,
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800112 kTestControlledByApp, &output));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700113 }
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
Ian Elliotta2eb34c2017-07-18 11:05:49 -0600126 int ret = mProducer->dequeueBuffer(
127 outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat,
128 kTestProducerUsageBits, nullptr, nullptr);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700129 // 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
Peiyong Lind8460c82020-07-28 16:04:22 -0700143 const sp<IProducerListener> kStubListener{new StubProducerListener};
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700144
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800145 sp<BufferHubProducer> mProducer;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700146 sp<Surface> mSurface;
147};
148
149TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
150 IGraphicBufferProducer::QueueBufferOutput output;
151
152 // NULL output returns BAD_VALUE
Peiyong Lind8460c82020-07-28 16:04:22 -0700153 EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700154 kTestControlledByApp, nullptr));
155
156 // Invalid API returns bad value
Peiyong Lind8460c82020-07-28 16:04:22 -0700157 EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700158 kTestControlledByApp, &output));
159}
160
161TEST_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;
Peiyong Lind8460c82020-07-28 16:04:22 -0700166 EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700167 kTestControlledByApp, &output));
168}
169
170TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
171 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
172
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800173 ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700174}
175
176TEST_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
185TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
186 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
187
188 int32_t value = -1;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800189 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700190 EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
191
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800192 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700193 EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
194
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800195 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700196 EXPECT_EQ(kDefaultFormat, value);
197
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800198 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700199 EXPECT_LE(0, value);
Corey Tabakab7ca5de2017-05-08 18:55:02 -0700200 EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value);
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700201
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800202 EXPECT_EQ(OK,
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700203 mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
204 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
205
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800206 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700207 EXPECT_EQ(kDefaultConsumerUsageBits, value);
208}
209
210TEST_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
236TEST_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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800244 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700245
246 // A generic "valid" input
247 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
248 IGraphicBufferProducer::QueueBufferOutput output;
249
250 // Queue the buffer back into the BQ
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800251 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700252
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
269TEST_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)
284TEST_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
294TEST_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
307TEST_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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800314 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700315
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
326TEST_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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800333 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700334
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
347TEST_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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800354 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700355
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
365TEST_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.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800373 EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700374}
375
376TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
377 return;
378 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
379
380 int minUndequeuedBuffers;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800381 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
382 &minUndequeuedBuffers));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700383
384 const int minBuffers = 1;
385 const int maxBuffers =
386 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
387
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800388 ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
389 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers))
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700390 << "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
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800399 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700400
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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800405 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
406 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700407
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
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800414 ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700415
416 // Should now be able to decrease the max dequeued count by 1
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800417 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700418}
419
420TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
421 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
422
423 int minUndequeuedBuffers;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800424 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
425 &minUndequeuedBuffers));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700426
427 const int minBuffers = 1;
428 const int maxBuffers =
429 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
430
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800431 ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700432 // 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
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800439 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700440 // 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 &
Ian Elliotta2eb34c2017-07-18 11:05:49 -0600445 (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
446 kDefaultHeight, kDefaultFormat,
447 kTestProducerUsageBits,
448 nullptr, nullptr)))
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700449 << "slot: " << slot;
450 }
451
452 // Client has too many buffers dequeued
453 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
454 << "bufferCount: " << minBuffers;
455}
456
457TEST_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,
Ian Elliotta2eb34c2017-07-18 11:05:49 -0600464 kTestProducerUsageBits,
465 nullptr, nullptr));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700466}
467
468TEST_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.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800477 ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700478 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
479}
480
481TEST_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));
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800488 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700489
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.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800495 ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700496 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
497}
498
499TEST_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));
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800506 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700507
508 // Shouldn't be able to cancel buffer after disconnect.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800509 ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700510 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800511}
512
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700513TEST_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;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800523 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));
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700527
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));
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800533 EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
534 EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700535 }
536
537 // Disconnect then reconnect.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800538 EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700539 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));
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800544 EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
545 EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700546 }
547
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800548 EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700549}
550
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800551TEST_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
Peiyong Lind8460c82020-07-28 16:04:22 -0700557 // Create a valid fake producer parcelable.
558 auto fake_channel_parcelable =
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800559 std::make_unique<pdx::default_transport::ChannelParcelable>(
560 LocalHandle(0), LocalHandle(0), LocalHandle(0));
Peiyong Lind8460c82020-07-28 16:04:22 -0700561 EXPECT_TRUE(fake_channel_parcelable->IsValid());
562 ProducerQueueParcelable fake_producer_parcelable(
563 std::move(fake_channel_parcelable));
564 EXPECT_TRUE(fake_producer_parcelable.IsValid());
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800565
566 // Disconnect producer can be taken out, but only to an invalid parcelable.
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800567 ASSERT_EQ(mProducer->disconnect(kTestApi), OK);
Peiyong Lind8460c82020-07-28 16:04:22 -0700568 EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800569 EXPECT_FALSE(producer_parcelable.IsValid());
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800570 EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800571 EXPECT_TRUE(producer_parcelable.IsValid());
572
573 // Should still be able to query buffer dimension after disconnect.
574 int32_t value = -1;
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800575 EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800576 EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth);
577
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800578 EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800579 EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight);
580
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800581 EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800582 EXPECT_EQ(value, kDefaultFormat);
583
584 // But connect to API will fail.
585 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700586 EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp,
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800587 &output),
588 BAD_VALUE);
589
590 // Create a new producer from the parcelable and connect to kTestApi should
591 // succeed.
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -0800592 sp<BufferHubProducer> new_producer =
593 BufferHubProducer::Create(std::move(producer_parcelable));
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800594 ASSERT_TRUE(new_producer != nullptr);
Peiyong Lind8460c82020-07-28 16:04:22 -0700595 EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp,
596 &output),
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800597 OK);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800598}
599
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800600} // namespace
601
602} // namespace dvr
603} // namespace android