BufferQueue_test.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * Copyright (C) 2012 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. #define LOG_TAG "BufferQueue_test"
  17. //#define LOG_NDEBUG 0
  18. #include "DummyConsumer.h"
  19. #include <gui/BufferItem.h>
  20. #include <gui/BufferQueue.h>
  21. #include <gui/IProducerListener.h>
  22. #include <ui/GraphicBuffer.h>
  23. #include <binder/IPCThreadState.h>
  24. #include <binder/IServiceManager.h>
  25. #include <binder/ProcessState.h>
  26. #include <utils/String8.h>
  27. #include <utils/threads.h>
  28. #include <gtest/gtest.h>
  29. namespace android {
  30. class BufferQueueTest : public ::testing::Test {
  31. public:
  32. protected:
  33. BufferQueueTest() {
  34. const ::testing::TestInfo* const testInfo =
  35. ::testing::UnitTest::GetInstance()->current_test_info();
  36. ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
  37. testInfo->name());
  38. }
  39. ~BufferQueueTest() {
  40. const ::testing::TestInfo* const testInfo =
  41. ::testing::UnitTest::GetInstance()->current_test_info();
  42. ALOGV("End test: %s.%s", testInfo->test_case_name(),
  43. testInfo->name());
  44. }
  45. void GetMinUndequeuedBufferCount(int* bufferCount) {
  46. ASSERT_TRUE(bufferCount != NULL);
  47. ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
  48. bufferCount));
  49. ASSERT_GE(*bufferCount, 0);
  50. }
  51. void createBufferQueue() {
  52. BufferQueue::createBufferQueue(&mProducer, &mConsumer);
  53. }
  54. sp<IGraphicBufferProducer> mProducer;
  55. sp<IGraphicBufferConsumer> mConsumer;
  56. };
  57. static const uint32_t TEST_DATA = 0x12345678u;
  58. // XXX: Tests that fork a process to hold the BufferQueue must run before tests
  59. // that use a local BufferQueue, or else Binder will get unhappy
  60. TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
  61. const String16 PRODUCER_NAME = String16("BQTestProducer");
  62. const String16 CONSUMER_NAME = String16("BQTestConsumer");
  63. pid_t forkPid = fork();
  64. ASSERT_NE(forkPid, -1);
  65. if (forkPid == 0) {
  66. // Child process
  67. sp<IGraphicBufferProducer> producer;
  68. sp<IGraphicBufferConsumer> consumer;
  69. BufferQueue::createBufferQueue(&producer, &consumer);
  70. sp<IServiceManager> serviceManager = defaultServiceManager();
  71. serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
  72. serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
  73. ProcessState::self()->startThreadPool();
  74. IPCThreadState::self()->joinThreadPool();
  75. LOG_ALWAYS_FATAL("Shouldn't be here");
  76. }
  77. sp<IServiceManager> serviceManager = defaultServiceManager();
  78. sp<IBinder> binderProducer =
  79. serviceManager->getService(PRODUCER_NAME);
  80. mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
  81. EXPECT_TRUE(mProducer != NULL);
  82. sp<IBinder> binderConsumer =
  83. serviceManager->getService(CONSUMER_NAME);
  84. mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
  85. EXPECT_TRUE(mConsumer != NULL);
  86. sp<DummyConsumer> dc(new DummyConsumer);
  87. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
  88. IGraphicBufferProducer::QueueBufferOutput output;
  89. ASSERT_EQ(OK,
  90. mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
  91. int slot;
  92. sp<Fence> fence;
  93. sp<GraphicBuffer> buffer;
  94. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  95. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  96. GRALLOC_USAGE_SW_WRITE_OFTEN));
  97. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  98. uint32_t* dataIn;
  99. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  100. reinterpret_cast<void**>(&dataIn)));
  101. *dataIn = TEST_DATA;
  102. ASSERT_EQ(OK, buffer->unlock());
  103. IGraphicBufferProducer::QueueBufferInput input(0, false,
  104. HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
  105. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
  106. ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
  107. BufferItem item;
  108. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
  109. uint32_t* dataOut;
  110. ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  111. reinterpret_cast<void**>(&dataOut)));
  112. ASSERT_EQ(*dataOut, TEST_DATA);
  113. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  114. }
  115. TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
  116. createBufferQueue();
  117. sp<DummyConsumer> dc(new DummyConsumer);
  118. mConsumer->consumerConnect(dc, false);
  119. IGraphicBufferProducer::QueueBufferOutput qbo;
  120. mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
  121. &qbo);
  122. mProducer->setBufferCount(4);
  123. int slot;
  124. sp<Fence> fence;
  125. sp<GraphicBuffer> buf;
  126. IGraphicBufferProducer::QueueBufferInput qbi(0, false,
  127. HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
  128. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
  129. BufferItem item;
  130. for (int i = 0; i < 2; i++) {
  131. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  132. mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
  133. GRALLOC_USAGE_SW_READ_OFTEN));
  134. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
  135. ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
  136. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
  137. }
  138. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  139. mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
  140. GRALLOC_USAGE_SW_READ_OFTEN));
  141. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
  142. ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
  143. // Acquire the third buffer, which should fail.
  144. ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
  145. }
  146. TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
  147. createBufferQueue();
  148. sp<DummyConsumer> dc(new DummyConsumer);
  149. mConsumer->consumerConnect(dc, false);
  150. int minBufferCount;
  151. ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
  152. EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
  153. minBufferCount - 1));
  154. EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
  155. EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
  156. EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
  157. BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
  158. EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
  159. }
  160. TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
  161. createBufferQueue();
  162. sp<DummyConsumer> dc(new DummyConsumer);
  163. mConsumer->consumerConnect(dc, false);
  164. int minBufferCount;
  165. ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
  166. EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
  167. EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
  168. EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
  169. EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
  170. BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
  171. }
  172. TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
  173. createBufferQueue();
  174. sp<DummyConsumer> dc(new DummyConsumer);
  175. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
  176. IGraphicBufferProducer::QueueBufferOutput output;
  177. ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
  178. NATIVE_WINDOW_API_CPU, false, &output));
  179. ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
  180. ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
  181. BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
  182. ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
  183. int slot;
  184. sp<Fence> fence;
  185. sp<GraphicBuffer> buffer;
  186. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  187. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  188. GRALLOC_USAGE_SW_WRITE_OFTEN));
  189. ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
  190. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  191. ASSERT_EQ(OK, mProducer->detachBuffer(slot));
  192. ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
  193. sp<GraphicBuffer> safeToClobberBuffer;
  194. // Can no longer request buffer from this slot
  195. ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
  196. uint32_t* dataIn;
  197. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  198. reinterpret_cast<void**>(&dataIn)));
  199. *dataIn = TEST_DATA;
  200. ASSERT_EQ(OK, buffer->unlock());
  201. int newSlot;
  202. ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
  203. ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
  204. ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
  205. IGraphicBufferProducer::QueueBufferInput input(0, false,
  206. HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
  207. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
  208. ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
  209. BufferItem item;
  210. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
  211. uint32_t* dataOut;
  212. ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  213. reinterpret_cast<void**>(&dataOut)));
  214. ASSERT_EQ(*dataOut, TEST_DATA);
  215. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  216. }
  217. TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
  218. createBufferQueue();
  219. sp<DummyConsumer> dc(new DummyConsumer);
  220. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
  221. IGraphicBufferProducer::QueueBufferOutput output;
  222. ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
  223. NATIVE_WINDOW_API_CPU, false, &output));
  224. int slot;
  225. sp<Fence> fence;
  226. sp<GraphicBuffer> buffer;
  227. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  228. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  229. GRALLOC_USAGE_SW_WRITE_OFTEN));
  230. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  231. IGraphicBufferProducer::QueueBufferInput input(0, false,
  232. HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
  233. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
  234. ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
  235. ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
  236. ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
  237. BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
  238. ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
  239. BufferItem item;
  240. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
  241. ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
  242. ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired
  243. uint32_t* dataIn;
  244. ASSERT_EQ(OK, item.mGraphicBuffer->lock(
  245. GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  246. reinterpret_cast<void**>(&dataIn)));
  247. *dataIn = TEST_DATA;
  248. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  249. int newSlot;
  250. sp<GraphicBuffer> safeToClobberBuffer;
  251. ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
  252. ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
  253. ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
  254. ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
  255. EGL_NO_SYNC_KHR, Fence::NO_FENCE));
  256. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  257. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  258. GRALLOC_USAGE_SW_WRITE_OFTEN));
  259. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  260. uint32_t* dataOut;
  261. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  262. reinterpret_cast<void**>(&dataOut)));
  263. ASSERT_EQ(*dataOut, TEST_DATA);
  264. ASSERT_EQ(OK, buffer->unlock());
  265. }
  266. TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
  267. createBufferQueue();
  268. sp<DummyConsumer> dc(new DummyConsumer);
  269. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
  270. IGraphicBufferProducer::QueueBufferOutput output;
  271. ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
  272. NATIVE_WINDOW_API_CPU, false, &output));
  273. int slot;
  274. sp<Fence> fence;
  275. sp<GraphicBuffer> buffer;
  276. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  277. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  278. GRALLOC_USAGE_SW_WRITE_OFTEN));
  279. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  280. uint32_t* dataIn;
  281. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  282. reinterpret_cast<void**>(&dataIn)));
  283. *dataIn = TEST_DATA;
  284. ASSERT_EQ(OK, buffer->unlock());
  285. IGraphicBufferProducer::QueueBufferInput input(0, false,
  286. HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
  287. NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
  288. ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
  289. BufferItem item;
  290. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
  291. ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
  292. int newSlot;
  293. ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
  294. ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
  295. ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
  296. uint32_t* dataOut;
  297. ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  298. reinterpret_cast<void**>(&dataOut)));
  299. ASSERT_EQ(*dataOut, TEST_DATA);
  300. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  301. }
  302. TEST_F(BufferQueueTest, TestDisallowingAllocation) {
  303. createBufferQueue();
  304. sp<DummyConsumer> dc(new DummyConsumer);
  305. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
  306. IGraphicBufferProducer::QueueBufferOutput output;
  307. ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
  308. NATIVE_WINDOW_API_CPU, true, &output));
  309. static const uint32_t WIDTH = 320;
  310. static const uint32_t HEIGHT = 240;
  311. ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
  312. int slot;
  313. sp<Fence> fence;
  314. sp<GraphicBuffer> buffer;
  315. // This should return an error since it would require an allocation
  316. ASSERT_EQ(OK, mProducer->allowAllocation(false));
  317. ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0,
  318. 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
  319. // This should succeed, now that we've lifted the prohibition
  320. ASSERT_EQ(OK, mProducer->allowAllocation(true));
  321. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  322. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  323. GRALLOC_USAGE_SW_WRITE_OFTEN));
  324. // Release the previous buffer back to the BufferQueue
  325. mProducer->cancelBuffer(slot, fence);
  326. // This should fail since we're requesting a different size
  327. ASSERT_EQ(OK, mProducer->allowAllocation(false));
  328. ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false,
  329. WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
  330. }
  331. TEST_F(BufferQueueTest, TestGenerationNumbers) {
  332. createBufferQueue();
  333. sp<DummyConsumer> dc(new DummyConsumer);
  334. ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
  335. IGraphicBufferProducer::QueueBufferOutput output;
  336. ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
  337. NATIVE_WINDOW_API_CPU, true, &output));
  338. ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
  339. // Get one buffer to play with
  340. int slot;
  341. sp<Fence> fence;
  342. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  343. mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 0));
  344. sp<GraphicBuffer> buffer;
  345. ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
  346. // Ensure that the generation number we set propagates to allocated buffers
  347. ASSERT_EQ(1U, buffer->getGenerationNumber());
  348. ASSERT_EQ(OK, mProducer->detachBuffer(slot));
  349. ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
  350. // These should fail, since we've changed the generation number on the queue
  351. int outSlot;
  352. ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
  353. ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
  354. buffer->setGenerationNumber(2);
  355. // This should succeed now that we've changed the buffer's generation number
  356. ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
  357. ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
  358. // This should also succeed with the new generation number
  359. ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
  360. }
  361. } // namespace android