• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <base/logging.h>
2 #include <gtest/gtest.h>
3 #include <poll.h>
4 
5 #include <android/hardware_buffer.h>
6 
7 #include <algorithm>
8 #include <set>
9 #include <thread>
10 #include <vector>
11 
12 #include <dvr/dvr_deleter.h>
13 #include <dvr/dvr_display_manager.h>
14 #include <dvr/dvr_surface.h>
15 
16 #include <pdx/status.h>
17 
18 using android::pdx::ErrorStatus;
19 using android::pdx::Status;
20 
21 namespace android {
22 namespace dvr {
23 
24 namespace {
25 
GetAttribute(DvrSurfaceAttributeKey key,bool value)26 DvrSurfaceAttribute GetAttribute(DvrSurfaceAttributeKey key, bool value) {
27   DvrSurfaceAttribute attribute;
28   attribute.key = key;
29   attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
30   attribute.value.bool_value = value;
31   return attribute;
32 }
33 
GetAttribute(DvrSurfaceAttributeKey key,int32_t value)34 DvrSurfaceAttribute GetAttribute(DvrSurfaceAttributeKey key, int32_t value) {
35   DvrSurfaceAttribute attribute;
36   attribute.key = key;
37   attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
38   attribute.value.bool_value = value;
39   return attribute;
40 }
41 
CreateApplicationSurface(bool visible=false,int32_t z_order=0)42 Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false,
43                                                   int32_t z_order = 0) {
44   DvrSurface* surface = nullptr;
45   DvrSurfaceAttribute attributes[] = {
46       GetAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order),
47       GetAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)};
48 
49   const int ret = dvrSurfaceCreate(
50       attributes, std::extent<decltype(attributes)>::value, &surface);
51   if (ret < 0)
52     return ErrorStatus(-ret);
53   else
54     return {UniqueDvrSurface(surface)};
55 }
56 
CreateSurfaceQueue(const UniqueDvrSurface & surface,uint32_t width,uint32_t height,uint32_t format,uint32_t layer_count,uint64_t usage,size_t capacity)57 Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
58     const UniqueDvrSurface& surface, uint32_t width, uint32_t height,
59     uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity) {
60   DvrWriteBufferQueue* queue;
61   const int ret =
62       dvrSurfaceCreateWriteBufferQueue(surface.get(), width, height, format,
63                                        layer_count, usage, capacity, &queue);
64   if (ret < 0)
65     return ErrorStatus(-ret);
66   else
67     return {UniqueDvrWriteBufferQueue(queue)};
68 }
69 
70 class TestDisplayManager {
71  public:
TestDisplayManager(UniqueDvrDisplayManager display_manager,UniqueDvrSurfaceState surface_state)72   TestDisplayManager(UniqueDvrDisplayManager display_manager,
73                      UniqueDvrSurfaceState surface_state)
74       : display_manager_(std::move(display_manager)),
75         surface_state_(std::move(surface_state)) {
76     const int fd = dvrDisplayManagerGetEventFd(display_manager_.get());
77     LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd);
78     display_manager_event_fd_ = fd;
79   }
80 
GetReadBufferQueue(int surface_id,int queue_id)81   Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id,
82                                                       int queue_id) {
83     DvrReadBufferQueue* queue;
84     const int ret = dvrDisplayManagerGetReadBufferQueue(
85         display_manager_.get(), surface_id, queue_id, &queue);
86     if (ret < 0)
87       return ErrorStatus(-ret);
88     else
89       return {UniqueDvrReadBufferQueue(queue)};
90   }
91 
UpdateSurfaceState()92   Status<void> UpdateSurfaceState() {
93     const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(),
94                                                      surface_state_.get());
95     if (ret < 0)
96       return ErrorStatus(-ret);
97     else
98       return {};
99   }
100 
WaitForUpdate()101   Status<void> WaitForUpdate() {
102     if (display_manager_event_fd_ < 0)
103       return ErrorStatus(-display_manager_event_fd_);
104 
105     const int kTimeoutMs = 10000;  // 10s
106     pollfd pfd = {display_manager_event_fd_, POLLIN, 0};
107     const int count = poll(&pfd, 1, kTimeoutMs);
108     if (count < 0)
109       return ErrorStatus(errno);
110     else if (count == 0)
111       return ErrorStatus(ETIMEDOUT);
112 
113     int events;
114     const int ret = dvrDisplayManagerTranslateEpollEventMask(
115         display_manager_.get(), pfd.revents, &events);
116     if (ret < 0)
117       return ErrorStatus(-ret);
118     else if (events & POLLIN)
119       return UpdateSurfaceState();
120     else
121       return ErrorStatus(EPROTO);
122   }
123 
GetSurfaceCount()124   Status<size_t> GetSurfaceCount() {
125     size_t count = 0;
126     const int ret =
127         dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count);
128     if (ret < 0)
129       return ErrorStatus(-ret);
130     else
131       return {count};
132   }
133 
GetUpdateFlags(size_t surface_index)134   Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) {
135     DvrSurfaceUpdateFlags update_flags;
136     const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(),
137                                                   surface_index, &update_flags);
138     if (ret < 0)
139       return ErrorStatus(-ret);
140     else
141       return {update_flags};
142   }
143 
GetSurfaceId(size_t surface_index)144   Status<int> GetSurfaceId(size_t surface_index) {
145     int surface_id;
146     const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(),
147                                                 surface_index, &surface_id);
148     if (ret < 0)
149       return ErrorStatus(-ret);
150     else
151       return {surface_id};
152   }
153 
GetProcessId(size_t surface_index)154   Status<int> GetProcessId(size_t surface_index) {
155     int process_id;
156     const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(),
157                                                 surface_index, &process_id);
158     if (ret < 0)
159       return ErrorStatus(-ret);
160     else
161       return {process_id};
162   }
163 
GetAttributes(size_t surface_index)164   Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) {
165     std::vector<DvrSurfaceAttribute> attributes;
166     size_t count = 0;
167     const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(),
168                                                      surface_index, &count);
169     if (ret < 0)
170       return ErrorStatus(-ret);
171 
172     attributes.resize(count);
173     const ssize_t return_count = dvrSurfaceStateGetAttributes(
174         surface_state_.get(), surface_index, attributes.data(), count);
175     if (return_count < 0)
176       return ErrorStatus(-return_count);
177 
178     attributes.resize(return_count);
179     return {std::move(attributes)};
180   }
181 
GetQueueIds(size_t surface_index)182   Status<std::vector<int>> GetQueueIds(size_t surface_index) {
183     std::vector<int> queue_ids;
184     size_t count = 0;
185     const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(),
186                                                  surface_index, &count);
187     if (ret < 0)
188       return ErrorStatus(-ret);
189 
190     if (count > 0) {
191       queue_ids.resize(count);
192       const ssize_t return_count = dvrSurfaceStateGetQueueIds(
193           surface_state_.get(), surface_index, queue_ids.data(), count);
194       if (return_count < 0)
195         return ErrorStatus(-return_count);
196 
197       queue_ids.resize(return_count);
198     }
199 
200     return {std::move(queue_ids)};
201   }
202 
203  private:
204   UniqueDvrDisplayManager display_manager_;
205   UniqueDvrSurfaceState surface_state_;
206 
207   // Owned by object in display_manager_, do not explicitly close.
208   int display_manager_event_fd_;
209 
210   TestDisplayManager(const TestDisplayManager&) = delete;
211   void operator=(const TestDisplayManager&) = delete;
212 };
213 
214 class DvrDisplayManagerTest : public ::testing::Test {
215  protected:
SetUp()216   void SetUp() override {
217     int ret;
218     DvrDisplayManager* display_manager;
219     DvrSurfaceState* surface_state;
220 
221     ret = dvrDisplayManagerCreate(&display_manager);
222     ASSERT_EQ(0, ret) << "Failed to create display manager client";
223     ASSERT_NE(nullptr, display_manager);
224 
225     ret = dvrSurfaceStateCreate(&surface_state);
226     ASSERT_EQ(0, ret) << "Failed to create surface state object";
227     ASSERT_NE(nullptr, surface_state);
228 
229     manager_.reset(
230         new TestDisplayManager(UniqueDvrDisplayManager(display_manager),
231                                UniqueDvrSurfaceState(surface_state)));
232   }
TearDown()233   void TearDown() override {}
234 
235   std::unique_ptr<TestDisplayManager> manager_;
236 };
237 
238 // TODO(eieio): Consider moving these somewhere more central because they are
239 // broadly useful.
240 
241 template <typename T>
StatusOk(const char * status_expression,const Status<T> & status)242 testing::AssertionResult StatusOk(const char* status_expression,
243                                   const Status<T>& status) {
244   if (!status.ok()) {
245     return testing::AssertionFailure()
246            << "(" << status_expression
247            << ") expected to indicate success but actually contains error ("
248            << status.error() << ")";
249   } else {
250     return testing::AssertionSuccess();
251   }
252 }
253 
254 template <typename T>
StatusError(const char * status_expression,const Status<T> & status)255 testing::AssertionResult StatusError(const char* status_expression,
256                                      const Status<T>& status) {
257   if (status.ok()) {
258     return testing::AssertionFailure()
259            << "(" << status_expression
260            << ") expected to indicate error but instead indicates success.";
261   } else {
262     return testing::AssertionSuccess();
263   }
264 }
265 
266 template <typename T>
StatusHasError(const char * status_expression,const char *,const Status<T> & status,int error_code)267 testing::AssertionResult StatusHasError(const char* status_expression,
268                                         const char* /*error_code_expression*/,
269                                         const Status<T>& status,
270                                         int error_code) {
271   if (status.ok()) {
272     return StatusError(status_expression, status);
273   } else if (status.error() != error_code) {
274     return testing::AssertionFailure()
275            << "(" << status_expression << ") expected to indicate error ("
276            << error_code << ") but actually indicates error (" << status.error()
277            << ")";
278   } else {
279     return testing::AssertionSuccess();
280   }
281 }
282 
283 template <typename T, typename U>
StatusHasValue(const char * status_expression,const char *,const Status<T> & status,const U & value)284 testing::AssertionResult StatusHasValue(const char* status_expression,
285                                         const char* /*value_expression*/,
286                                         const Status<T>& status,
287                                         const U& value) {
288   if (!status.ok()) {
289     return StatusOk(status_expression, status);
290   } else if (status.get() != value) {
291     return testing::AssertionFailure()
292            << "(" << status_expression << ") expected to contain value ("
293            << testing::PrintToString(value) << ") but actually contains value ("
294            << testing::PrintToString(status.get()) << ")";
295   } else {
296     return testing::AssertionSuccess();
297   }
298 }
299 
300 template <typename T, typename Op>
StatusPred(const char * status_expression,const char * pred_expression,const Status<T> & status,Op pred)301 testing::AssertionResult StatusPred(const char* status_expression,
302                                     const char* pred_expression,
303                                     const Status<T>& status, Op pred) {
304   if (!status.ok()) {
305     return StatusOk(status_expression, status);
306   } else if (!pred(status.get())) {
307     return testing::AssertionFailure()
308            << status_expression << " value ("
309            << testing::PrintToString(status.get())
310            << ") failed to pass predicate " << pred_expression;
311   } else {
312     return testing::AssertionSuccess();
313   }
314 }
315 
316 #define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status)
317 #define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status)
318 
319 #define ASSERT_STATUS_ERROR_VALUE(value, status) \
320   ASSERT_PRED_FORMAT2(StatusHasError, status, value)
321 
322 #define ASSERT_STATUS_EQ(value, status) \
323   ASSERT_PRED_FORMAT2(StatusHasValue, status, value)
324 
325 #define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status)
326 #define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status)
327 
328 #define EXPECT_STATUS_ERROR_VALUE(value, status) \
329   EXPECT_PRED_FORMAT2(StatusHasError, status, value)
330 
331 #define EXPECT_STATUS_EQ(value, status) \
332   EXPECT_PRED_FORMAT2(StatusHasValue, status, value)
333 
334 #define EXPECT_STATUS_PRED(pred, status) \
335   EXPECT_PRED_FORMAT2(StatusPred, status, pred)
336 
337 #if 0
338 // Verify utility predicate/macro functionality. This section is commented out
339 // because it is designed to fail in some cases to validate the helpers.
340 TEST_F(DvrDisplayManagerTest, ExpectVoid) {
341   Status<void> status_error{ErrorStatus{EINVAL}};
342   Status<void> status_ok{};
343 
344   EXPECT_STATUS_ERROR(status_error);
345   EXPECT_STATUS_ERROR(status_ok);
346   EXPECT_STATUS_OK(status_error);
347   EXPECT_STATUS_OK(status_ok);
348 
349   EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
350   EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
351   EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
352   EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
353 }
354 
355 TEST_F(DvrDisplayManagerTest, ExpectInt) {
356   Status<int> status_error{ErrorStatus{EINVAL}};
357   Status<int> status_ok{10};
358 
359   EXPECT_STATUS_ERROR(status_error);
360   EXPECT_STATUS_ERROR(status_ok);
361   EXPECT_STATUS_OK(status_error);
362   EXPECT_STATUS_OK(status_ok);
363 
364   EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
365   EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
366   EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
367   EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
368 
369   EXPECT_STATUS_EQ(10, status_error);
370   EXPECT_STATUS_EQ(20, status_error);
371   EXPECT_STATUS_EQ(10, status_ok);
372   EXPECT_STATUS_EQ(20, status_ok);
373 
374   auto pred1 = [](const auto& value) { return value < 15; };
375   auto pred2 = [](const auto& value) { return value > 5; };
376   auto pred3 = [](const auto& value) { return value > 15; };
377   auto pred4 = [](const auto& value) { return value < 5; };
378 
379   EXPECT_STATUS_PRED(pred1, status_error);
380   EXPECT_STATUS_PRED(pred2, status_error);
381   EXPECT_STATUS_PRED(pred3, status_error);
382   EXPECT_STATUS_PRED(pred4, status_error);
383   EXPECT_STATUS_PRED(pred1, status_ok);
384   EXPECT_STATUS_PRED(pred2, status_ok);
385   EXPECT_STATUS_PRED(pred3, status_ok);
386   EXPECT_STATUS_PRED(pred4, status_ok);
387 }
388 #endif
389 
TEST_F(DvrDisplayManagerTest,SurfaceCreateEvent)390 TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) {
391   // Get surface state and verify there are no surfaces.
392   ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
393   ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
394 
395   // Get flags for invalid surface index.
396   EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0));
397 
398   // Create an application surface.
399   auto surface_status = CreateApplicationSurface();
400   ASSERT_STATUS_OK(surface_status);
401   UniqueDvrSurface surface = surface_status.take();
402   ASSERT_NE(nullptr, surface.get());
403 
404   const int surface_id = dvrSurfaceGetId(surface.get());
405   ASSERT_GE(surface_id, 0);
406 
407   // Now there should be one new surface.
408   ASSERT_STATUS_OK(manager_->WaitForUpdate());
409   EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount());
410 
411   // Verify the new surface flag is set.
412   auto check_flags = [](const auto& value) {
413     return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE;
414   };
415   EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
416 
417   // Verify the surface id matches.
418   EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0));
419 
420   // Verify the owning process of the surface.
421   EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0));
422 
423   surface.reset();
424 
425   ASSERT_STATUS_OK(manager_->WaitForUpdate());
426   EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount());
427 }
428 
TEST_F(DvrDisplayManagerTest,SurfaceAttributeEvent)429 TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) {
430   // Get surface state and verify there are no surfaces.
431   ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
432   ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
433 
434   // Get attributes for an invalid surface index.
435   EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0));
436 
437   const bool kInitialVisibility = true;
438   const int32_t kInitialZOrder = 10;
439   auto surface_status =
440       CreateApplicationSurface(kInitialVisibility, kInitialZOrder);
441   ASSERT_STATUS_OK(surface_status);
442   auto surface = surface_status.take();
443   ASSERT_NE(nullptr, surface.get());
444 
445   ASSERT_STATUS_OK(manager_->WaitForUpdate());
446   ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
447 
448   // Check the initial attribute values.
449   auto attribute_status = manager_->GetAttributes(0);
450   ASSERT_STATUS_OK(attribute_status);
451   auto attributes = attribute_status.take();
452   EXPECT_GE(attributes.size(), 2u);
453 
454   const std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
455                                            DVR_SURFACE_ATTRIBUTE_VISIBLE};
456 
457   // Collect all the keys in attributes that match the expected keys.
458   std::set<int32_t> actual_keys;
459   std::for_each(attributes.begin(), attributes.end(),
460                 [&expected_keys, &actual_keys](const auto& attribute) {
461                   if (expected_keys.find(attribute.key) != expected_keys.end())
462                     actual_keys.emplace(attribute.key);
463                 });
464 
465   // If the sets match then attributes contained at least the expected keys,
466   // even if other keys were also present.
467   EXPECT_EQ(expected_keys, actual_keys);
468 }
469 
TEST_F(DvrDisplayManagerTest,SurfaceQueueEvent)470 TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) {
471   // Create an application surface.
472   auto surface_status = CreateApplicationSurface();
473   ASSERT_STATUS_OK(surface_status);
474   UniqueDvrSurface surface = surface_status.take();
475   ASSERT_NE(nullptr, surface.get());
476 
477   const int surface_id = dvrSurfaceGetId(surface.get());
478   ASSERT_GE(surface_id, 0);
479   // Get surface state and verify there is one surface.
480   ASSERT_STATUS_OK(manager_->WaitForUpdate());
481   ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
482 
483   // Verify there are no queues for the surface recorded in the state snapshot.
484   EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0));
485 
486   // Create a new queue in the surface.
487   auto write_queue_status = CreateSurfaceQueue(
488       surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1,
489       AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1);
490   ASSERT_STATUS_OK(write_queue_status);
491   UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
492   ASSERT_NE(nullptr, write_queue.get());
493 
494   const int queue_id = dvrWriteBufferQueueGetId(write_queue.get());
495   ASSERT_GE(queue_id, 0);
496 
497   // Update surface state.
498   ASSERT_STATUS_OK(manager_->WaitForUpdate());
499   ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
500 
501   // Verify the buffers changed flag is set.
502   auto check_flags = [](const auto& value) {
503     return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED;
504   };
505   EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
506 
507   auto queue_ids_status = manager_->GetQueueIds(0);
508   ASSERT_STATUS_OK(queue_ids_status);
509 
510   auto queue_ids = queue_ids_status.take();
511   ASSERT_EQ(1u, queue_ids.size());
512   EXPECT_EQ(queue_id, queue_ids[0]);
513 
514   auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id);
515   ASSERT_STATUS_OK(read_queue_status);
516   UniqueDvrReadBufferQueue read_queue = read_queue_status.take();
517   ASSERT_NE(nullptr, read_queue.get());
518   EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get()));
519 
520   write_queue.reset();
521 
522   // Verify that destroying the queue generates a surface update event.
523   ASSERT_STATUS_OK(manager_->WaitForUpdate());
524   ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
525 
526   // Verify that the buffers changed flag is set.
527   EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
528 
529   // Verify that the queue ids reflect the change.
530   queue_ids_status = manager_->GetQueueIds(0);
531   ASSERT_STATUS_OK(queue_ids_status);
532 
533   queue_ids = queue_ids_status.take();
534   ASSERT_EQ(0u, queue_ids.size());
535 }
536 
TEST_F(DvrDisplayManagerTest,MultiLayerBufferQueue)537 TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) {
538   // Create an application surface.
539   auto surface_status = CreateApplicationSurface();
540   ASSERT_STATUS_OK(surface_status);
541   UniqueDvrSurface surface = surface_status.take();
542   ASSERT_NE(nullptr, surface.get());
543 
544   // Get surface state and verify there is one surface.
545   ASSERT_STATUS_OK(manager_->WaitForUpdate());
546   ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
547 
548   // Create a new queue in the surface.
549   const uint32_t kLayerCount = 3;
550   auto write_queue_status = CreateSurfaceQueue(
551       surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount,
552       AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1);
553   ASSERT_STATUS_OK(write_queue_status);
554   UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
555   ASSERT_NE(nullptr, write_queue.get());
556 
557   DvrWriteBuffer* buffer = nullptr;
558   dvrWriteBufferCreateEmpty(&buffer);
559   int fence_fd = -1;
560   int error =
561       dvrWriteBufferQueueDequeue(write_queue.get(), 1000, buffer, &fence_fd);
562   ASSERT_EQ(0, error);
563 
564   AHardwareBuffer* hardware_buffer = nullptr;
565   error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer);
566   ASSERT_EQ(0, error);
567 
568   AHardwareBuffer_Desc desc = {};
569   AHardwareBuffer_describe(hardware_buffer, &desc);
570   ASSERT_EQ(kLayerCount, desc.layers);
571 
572   AHardwareBuffer_release(hardware_buffer);
573   dvrWriteBufferDestroy(buffer);
574 }
575 
576 }  // namespace
577 
578 }  // namespace dvr
579 }  // namespace android
580