Home | History | Annotate | Download | only in 1.0
      1 /*
      2  * Copyright 2017, 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 "H2BGraphicBufferProducer"
     18 
     19 #include <android-base/logging.h>
     20 
     21 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
     22 #include <gui/bufferqueue/1.0/B2HProducerListener.h>
     23 
     24 #include <system/window.h>
     25 
     26 namespace android {
     27 namespace hardware {
     28 namespace graphics {
     29 namespace bufferqueue {
     30 namespace V1_0 {
     31 namespace utils {
     32 
     33 using Status = HGraphicBufferProducer::Status;
     34 using ::android::hardware::graphics::common::V1_0::Dataspace;
     35 typedef ::android::hardware::media::V1_0::Rect HRect;
     36 typedef ::android::hardware::media::V1_0::Region HRegion;
     37 
     38 // Conversion functions
     39 
     40 // native_handle_t helper functions.
     41 
     42 /**
     43  * \brief Take an fd and create a native handle containing only the given fd.
     44  * The created handle will need to be deleted manually with
     45  * `native_handle_delete()`.
     46  *
     47  * \param[in] fd The source file descriptor (of type `int`).
     48  * \return The create `native_handle_t*` that contains the given \p fd. If the
     49  * supplied \p fd is negative, the created native handle will contain no file
     50  * descriptors.
     51  *
     52  * If the native handle cannot be created, the return value will be
     53  * `nullptr`.
     54  *
     55  * This function does not duplicate the file descriptor.
     56  */
     57 inline native_handle_t* native_handle_create_from_fd(int fd) {
     58     if (fd < 0) {
     59         return native_handle_create(0, 0);
     60     }
     61     native_handle_t* nh = native_handle_create(1, 0);
     62     if (nh == nullptr) {
     63         return nullptr;
     64     }
     65     nh->data[0] = fd;
     66     return nh;
     67 }
     68 
     69 /**
     70  * \brief Extract a file descriptor from a native handle.
     71  *
     72  * \param[in] nh The source `native_handle_t*`.
     73  * \param[in] index The index of the file descriptor in \p nh to read from. This
     74  * input has the default value of `0`.
     75  * \return The `index`-th file descriptor in \p nh. If \p nh does not have
     76  * enough file descriptors, the returned value will be `-1`.
     77  *
     78  * This function does not duplicate the file descriptor.
     79  */
     80 inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
     81     return ((nh == nullptr) || (nh->numFds == 0) ||
     82             (nh->numFds <= index) || (index < 0)) ?
     83             -1 : nh->data[index];
     84 }
     85 
     86 /**
     87  * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
     88  * calls.
     89  *
     90  * \param[in] t The source `Return<Status>`.
     91  * \return The corresponding `status_t`.
     92  *
     93  * This function first check if \p t has a transport error. If it does, then the
     94  * return value is the transport error code. Otherwise, the return value is
     95  * converted from `Status` contained inside \p t.
     96  *
     97  * Note:
     98  * - This `Status` is omx-specific. It is defined in `types.hal`.
     99  * - The name of this function is not `convert`.
    100  */
    101 // convert: Return<Status> -> status_t
    102 inline status_t toStatusT(Return<Status> const& t) {
    103     if (t.isOk()) {
    104         return static_cast<status_t>(static_cast<Status>(t));
    105     } else if (t.isDeadObject()) {
    106         return DEAD_OBJECT;
    107     }
    108     return UNKNOWN_ERROR;
    109 }
    110 
    111 /**
    112  * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
    113  *
    114  * \param[in] t The source `Return<void>`.
    115  * \return The corresponding `status_t`.
    116  */
    117 // convert: Return<void> -> status_t
    118 inline status_t toStatusT(Return<void> const& t) {
    119     return t.isOk() ? OK : (t.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR);
    120 }
    121 
    122 /**
    123  * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
    124  *
    125  * \param[out] t The wrapper of type `AnwBuffer`.
    126  * \param[in] l The source `GraphicBuffer`.
    127  */
    128 // wrap: GraphicBuffer -> AnwBuffer
    129 inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
    130     t->attr.width = l.getWidth();
    131     t->attr.height = l.getHeight();
    132     t->attr.stride = l.getStride();
    133     t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
    134     t->attr.layerCount = l.getLayerCount();
    135     t->attr.usage = uint32_t(l.getUsage());     // FIXME: need 64-bits usage version
    136     t->attr.id = l.getId();
    137     t->attr.generationNumber = l.getGenerationNumber();
    138     t->nativeHandle = hidl_handle(l.handle);
    139 }
    140 
    141 /**
    142  * \brief Convert `AnwBuffer` to `GraphicBuffer`.
    143  *
    144  * \param[out] l The destination `GraphicBuffer`.
    145  * \param[in] t The source `AnwBuffer`.
    146  *
    147  * This function will duplicate all file descriptors in \p t.
    148  */
    149 // convert: AnwBuffer -> GraphicBuffer
    150 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
    151 inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
    152     native_handle_t* handle = t.nativeHandle == nullptr ?
    153             nullptr : native_handle_clone(t.nativeHandle);
    154 
    155     size_t const numInts = 12 +
    156             static_cast<size_t>(handle ? handle->numInts : 0);
    157     int32_t* ints = new int32_t[numInts];
    158 
    159     size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
    160     int* fds = new int[numFds];
    161 
    162     ints[0] = 'GBFR';
    163     ints[1] = static_cast<int32_t>(t.attr.width);
    164     ints[2] = static_cast<int32_t>(t.attr.height);
    165     ints[3] = static_cast<int32_t>(t.attr.stride);
    166     ints[4] = static_cast<int32_t>(t.attr.format);
    167     ints[5] = static_cast<int32_t>(t.attr.layerCount);
    168     ints[6] = static_cast<int32_t>(t.attr.usage);
    169     ints[7] = static_cast<int32_t>(t.attr.id >> 32);
    170     ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
    171     ints[9] = static_cast<int32_t>(t.attr.generationNumber);
    172     ints[10] = 0;
    173     ints[11] = 0;
    174     if (handle) {
    175         ints[10] = static_cast<int32_t>(handle->numFds);
    176         ints[11] = static_cast<int32_t>(handle->numInts);
    177         int* intsStart = handle->data + handle->numFds;
    178         std::copy(handle->data, intsStart, fds);
    179         std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
    180     }
    181 
    182     void const* constBuffer = static_cast<void const*>(ints);
    183     size_t size = numInts * sizeof(int32_t);
    184     int const* constFds = static_cast<int const*>(fds);
    185     status_t status = l->unflatten(constBuffer, size, constFds, numFds);
    186 
    187     delete [] fds;
    188     delete [] ints;
    189     native_handle_delete(handle);
    190     return status == NO_ERROR;
    191 }
    192 
    193 // Ref: frameworks/native/libs/ui/Fence.cpp
    194 
    195 /**
    196  * \brief Return the size of the non-fd buffer required to flatten a fence.
    197  *
    198  * \param[in] fence The input fence of type `hidl_handle`.
    199  * \return The required size of the flat buffer.
    200  *
    201  * The current version of this function always returns 4, which is the number of
    202  * bytes required to store the number of file descriptors contained in the fd
    203  * part of the flat buffer.
    204  */
    205 inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
    206     return 4;
    207 };
    208 
    209 /**
    210  * \brief Return the number of file descriptors contained in a fence.
    211  *
    212  * \param[in] fence The input fence of type `hidl_handle`.
    213  * \return `0` if \p fence does not contain a valid file descriptor, or `1`
    214  * otherwise.
    215  */
    216 inline size_t getFenceFdCount(hidl_handle const& fence) {
    217     return native_handle_read_fd(fence) == -1 ? 0 : 1;
    218 }
    219 
    220 /**
    221  * \brief Unflatten `Fence` to `hidl_handle`.
    222  *
    223  * \param[out] fence The destination `hidl_handle`.
    224  * \param[out] nh The underlying native handle.
    225  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    226  * \param[in,out] size The size of the flat non-fd buffer.
    227  * \param[in,out] fds The pointer to the flat fd buffer.
    228  * \param[in,out] numFds The size of the flat fd buffer.
    229  * \return `NO_ERROR` on success; other value on failure.
    230  *
    231  * If the return value is `NO_ERROR`, \p nh will point to a newly created
    232  * native handle, which needs to be deleted with `native_handle_delete()`
    233  * afterwards.
    234  */
    235 inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
    236         void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
    237     if (size < 4) {
    238         return NO_MEMORY;
    239     }
    240 
    241     uint32_t numFdsInHandle;
    242     FlattenableUtils::read(buffer, size, numFdsInHandle);
    243 
    244     if (numFdsInHandle > 1) {
    245         return BAD_VALUE;
    246     }
    247 
    248     if (numFds < numFdsInHandle) {
    249         return NO_MEMORY;
    250     }
    251 
    252     if (numFdsInHandle) {
    253         *nh = native_handle_create_from_fd(*fds);
    254         if (*nh == nullptr) {
    255             return NO_MEMORY;
    256         }
    257         *fence = *nh;
    258         ++fds;
    259         --numFds;
    260     } else {
    261         *nh = nullptr;
    262         *fence = hidl_handle();
    263     }
    264 
    265     return NO_ERROR;
    266 }
    267 
    268 /**
    269  * \brief Flatten `hidl_handle` as `Fence`.
    270  *
    271  * \param[in] fence The source `hidl_handle`.
    272  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    273  * \param[in,out] size The size of the flat non-fd buffer.
    274  * \param[in,out] fds The pointer to the flat fd buffer.
    275  * \param[in,out] numFds The size of the flat fd buffer.
    276  * \return `NO_ERROR` on success; other value on failure.
    277  */
    278 inline status_t flattenFence(hidl_handle const& fence,
    279         void*& buffer, size_t& size, int*& fds, size_t& numFds) {
    280     if (size < getFenceFlattenedSize(fence) ||
    281             numFds < getFenceFdCount(fence)) {
    282         return NO_MEMORY;
    283     }
    284     // Cast to uint32_t since the size of a size_t can vary between 32- and
    285     // 64-bit processes
    286     FlattenableUtils::write(buffer, size,
    287             static_cast<uint32_t>(getFenceFdCount(fence)));
    288     int fd = native_handle_read_fd(fence);
    289     if (fd != -1) {
    290         *fds = fd;
    291         ++fds;
    292         --numFds;
    293     }
    294     return NO_ERROR;
    295 }
    296 
    297 /**
    298  * \brief Wrap `Fence` in `hidl_handle`.
    299  *
    300  * \param[out] t The wrapper of type `hidl_handle`.
    301  * \param[out] nh The native handle pointed to by \p t.
    302  * \param[in] l The source `Fence`.
    303  *
    304  * On success, \p nh will hold a newly created native handle, which must be
    305  * deleted manually with `native_handle_delete()` afterwards.
    306  */
    307 // wrap: Fence -> hidl_handle
    308 inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
    309     size_t const baseSize = l.getFlattenedSize();
    310     std::unique_ptr<uint8_t[]> baseBuffer(
    311             new (std::nothrow) uint8_t[baseSize]);
    312     if (!baseBuffer) {
    313         return false;
    314     }
    315 
    316     size_t const baseNumFds = l.getFdCount();
    317     std::unique_ptr<int[]> baseFds(
    318             new (std::nothrow) int[baseNumFds]);
    319     if (!baseFds) {
    320         return false;
    321     }
    322 
    323     void* buffer = static_cast<void*>(baseBuffer.get());
    324     size_t size = baseSize;
    325     int* fds = static_cast<int*>(baseFds.get());
    326     size_t numFds = baseNumFds;
    327     if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
    328         return false;
    329     }
    330 
    331     void const* constBuffer = static_cast<void const*>(baseBuffer.get());
    332     size = baseSize;
    333     int const* constFds = static_cast<int const*>(baseFds.get());
    334     numFds = baseNumFds;
    335     if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
    336             != NO_ERROR) {
    337         return false;
    338     }
    339 
    340     return true;
    341 }
    342 
    343 /**
    344  * \brief Convert `hidl_handle` to `Fence`.
    345  *
    346  * \param[out] l The destination `Fence`. `l` must not have been used
    347  * (`l->isValid()` must return `false`) before this function is called.
    348  * \param[in] t The source `hidl_handle`.
    349  *
    350  * If \p t contains a valid file descriptor, it will be duplicated.
    351  */
    352 // convert: hidl_handle -> Fence
    353 inline bool convertTo(Fence* l, hidl_handle const& t) {
    354     int fd = native_handle_read_fd(t);
    355     if (fd != -1) {
    356         fd = dup(fd);
    357         if (fd == -1) {
    358             return false;
    359         }
    360     }
    361     native_handle_t* nh = native_handle_create_from_fd(fd);
    362     if (nh == nullptr) {
    363         if (fd != -1) {
    364             close(fd);
    365         }
    366         return false;
    367     }
    368 
    369     size_t const baseSize = getFenceFlattenedSize(t);
    370     std::unique_ptr<uint8_t[]> baseBuffer(
    371             new (std::nothrow) uint8_t[baseSize]);
    372     if (!baseBuffer) {
    373         native_handle_delete(nh);
    374         return false;
    375     }
    376 
    377     size_t const baseNumFds = getFenceFdCount(t);
    378     std::unique_ptr<int[]> baseFds(
    379             new (std::nothrow) int[baseNumFds]);
    380     if (!baseFds) {
    381         native_handle_delete(nh);
    382         return false;
    383     }
    384 
    385     void* buffer = static_cast<void*>(baseBuffer.get());
    386     size_t size = baseSize;
    387     int* fds = static_cast<int*>(baseFds.get());
    388     size_t numFds = baseNumFds;
    389     if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
    390         native_handle_delete(nh);
    391         return false;
    392     }
    393     native_handle_delete(nh);
    394 
    395     void const* constBuffer = static_cast<void const*>(baseBuffer.get());
    396     size = baseSize;
    397     int const* constFds = static_cast<int const*>(baseFds.get());
    398     numFds = baseNumFds;
    399     if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
    400         return false;
    401     }
    402 
    403     return true;
    404 }
    405 
    406 // Ref: frameworks/native/libs/ui/Region.cpp
    407 
    408 /**
    409  * \brief Unflatten `HRegion`.
    410  *
    411  * \param[out] t The destination `HRegion`.
    412  * \param[in,out] buffer The pointer to the flat buffer.
    413  * \param[in,out] size The size of the flat buffer.
    414  * \return `NO_ERROR` on success; other value on failure.
    415  */
    416 inline status_t unflatten(HRegion* t, void const*& buffer, size_t& size) {
    417     if (size < sizeof(uint32_t)) {
    418         return NO_MEMORY;
    419     }
    420 
    421     uint32_t numRects = 0;
    422     FlattenableUtils::read(buffer, size, numRects);
    423     if (size < numRects * sizeof(HRect)) {
    424         return NO_MEMORY;
    425     }
    426     if (numRects > (UINT32_MAX / sizeof(HRect))) {
    427         return NO_MEMORY;
    428     }
    429 
    430     t->resize(numRects);
    431     for (size_t r = 0; r < numRects; ++r) {
    432         ::android::Rect rect(::android::Rect::EMPTY_RECT);
    433         status_t status = rect.unflatten(buffer, size);
    434         if (status != NO_ERROR) {
    435             return status;
    436         }
    437         FlattenableUtils::advance(buffer, size, sizeof(rect));
    438         (*t)[r] = HRect{
    439                 static_cast<int32_t>(rect.left),
    440                 static_cast<int32_t>(rect.top),
    441                 static_cast<int32_t>(rect.right),
    442                 static_cast<int32_t>(rect.bottom)};
    443     }
    444     return NO_ERROR;
    445 }
    446 
    447 // Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
    448 //      IGraphicBufferProducer::QueueBufferInput
    449 
    450 /**
    451  * \brief Return a lower bound on the size of the buffer required to flatten
    452  * `HGraphicBufferProducer::QueueBufferInput`.
    453  *
    454  * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
    455  * \return A lower bound on the size of the flat buffer.
    456  */
    457 constexpr size_t minFlattenedSize(
    458         HGraphicBufferProducer::QueueBufferInput const& /* t */) {
    459     return sizeof(int64_t) + // timestamp
    460             sizeof(int) + // isAutoTimestamp
    461             sizeof(android_dataspace) + // dataSpace
    462             sizeof(::android::Rect) + // crop
    463             sizeof(int) + // scalingMode
    464             sizeof(uint32_t) + // transform
    465             sizeof(uint32_t) + // stickyTransform
    466             sizeof(bool); // getFrameTimestamps
    467 }
    468 
    469 /**
    470  * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
    471  *
    472  * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
    473  * \param[out] nh The underlying native handle for `t->fence`.
    474  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    475  * \param[in,out] size The size of the flat non-fd buffer.
    476  * \param[in,out] fds The pointer to the flat fd buffer.
    477  * \param[in,out] numFds The size of the flat fd buffer.
    478  * \return `NO_ERROR` on success; other value on failure.
    479  *
    480  * If the return value is `NO_ERROR` and `t->fence` contains a valid file
    481  * descriptor, \p nh will be a newly created native handle holding that file
    482  * descriptor. \p nh needs to be deleted with `native_handle_delete()`
    483  * afterwards.
    484  */
    485 inline status_t unflatten(
    486         HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
    487         void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
    488     if (size < minFlattenedSize(*t)) {
    489         return NO_MEMORY;
    490     }
    491 
    492     FlattenableUtils::read(buffer, size, t->timestamp);
    493     int lIsAutoTimestamp;
    494     FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
    495     t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
    496     android_dataspace_t lDataSpace;
    497     FlattenableUtils::read(buffer, size, lDataSpace);
    498     t->dataSpace = static_cast<Dataspace>(lDataSpace);
    499     ::android::Rect lCrop;
    500     FlattenableUtils::read(buffer, size, lCrop);
    501     t->crop = HRect{
    502             static_cast<int32_t>(lCrop.left),
    503             static_cast<int32_t>(lCrop.top),
    504             static_cast<int32_t>(lCrop.right),
    505             static_cast<int32_t>(lCrop.bottom)};
    506     int lScalingMode;
    507     FlattenableUtils::read(buffer, size, lScalingMode);
    508     t->scalingMode = static_cast<int32_t>(lScalingMode);
    509     FlattenableUtils::read(buffer, size, t->transform);
    510     FlattenableUtils::read(buffer, size, t->stickyTransform);
    511     FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
    512 
    513     status_t status = unflattenFence(&(t->fence), nh,
    514             buffer, size, fds, numFds);
    515     if (status != NO_ERROR) {
    516         return status;
    517     }
    518     return unflatten(&(t->surfaceDamage), buffer, size);
    519 }
    520 
    521 /**
    522  * \brief Wrap `IGraphicBufferProducer::QueueBufferInput` in
    523  * `HGraphicBufferProducer::QueueBufferInput`.
    524  *
    525  * \param[out] t The wrapper of type
    526  * `HGraphicBufferProducer::QueueBufferInput`.
    527  * \param[out] nh The underlying native handle for `t->fence`.
    528  * \param[in] l The source `IGraphicBufferProducer::QueueBufferInput`.
    529  *
    530  * If the return value is `true` and `t->fence` contains a valid file
    531  * descriptor, \p nh will be a newly created native handle holding that file
    532  * descriptor. \p nh needs to be deleted with `native_handle_delete()`
    533  * afterwards.
    534  */
    535 inline bool wrapAs(
    536         HGraphicBufferProducer::QueueBufferInput* t,
    537         native_handle_t** nh,
    538         BGraphicBufferProducer::QueueBufferInput const& l) {
    539 
    540     size_t const baseSize = l.getFlattenedSize();
    541     std::unique_ptr<uint8_t[]> baseBuffer(
    542             new (std::nothrow) uint8_t[baseSize]);
    543     if (!baseBuffer) {
    544         return false;
    545     }
    546 
    547     size_t const baseNumFds = l.getFdCount();
    548     std::unique_ptr<int[]> baseFds(
    549             new (std::nothrow) int[baseNumFds]);
    550     if (!baseFds) {
    551         return false;
    552     }
    553 
    554     void* buffer = static_cast<void*>(baseBuffer.get());
    555     size_t size = baseSize;
    556     int* fds = baseFds.get();
    557     size_t numFds = baseNumFds;
    558     if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
    559         return false;
    560     }
    561 
    562     void const* constBuffer = static_cast<void const*>(baseBuffer.get());
    563     size = baseSize;
    564     int const* constFds = static_cast<int const*>(baseFds.get());
    565     numFds = baseNumFds;
    566     if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
    567         return false;
    568     }
    569 
    570     return true;
    571 }
    572 
    573 // Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
    574 
    575 /**
    576  * \brief Return the size of the non-fd buffer required to flatten
    577  * `FenceTimeSnapshot`.
    578  *
    579  * \param[in] t The input `FenceTimeSnapshot`.
    580  * \return The required size of the flat buffer.
    581  */
    582 inline size_t getFlattenedSize(
    583         HGraphicBufferProducer::FenceTimeSnapshot const& t) {
    584     constexpr size_t min = sizeof(t.state);
    585     switch (t.state) {
    586         case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
    587             return min;
    588         case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
    589             return min + getFenceFlattenedSize(t.fence);
    590         case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
    591             return min + sizeof(
    592                     ::android::FenceTime::Snapshot::signalTime);
    593     }
    594     return 0;
    595 }
    596 
    597 /**
    598  * \brief Return the number of file descriptors contained in
    599  * `FenceTimeSnapshot`.
    600  *
    601  * \param[in] t The input `FenceTimeSnapshot`.
    602  * \return The number of file descriptors contained in \p snapshot.
    603  */
    604 inline size_t getFdCount(
    605         HGraphicBufferProducer::FenceTimeSnapshot const& t) {
    606     return t.state ==
    607             HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
    608             getFenceFdCount(t.fence) : 0;
    609 }
    610 
    611 /**
    612  * \brief Flatten `FenceTimeSnapshot`.
    613  *
    614  * \param[in] t The source `FenceTimeSnapshot`.
    615  * \param[out] nh The cloned native handle, if necessary.
    616  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    617  * \param[in,out] size The size of the flat non-fd buffer.
    618  * \param[in,out] fds The pointer to the flat fd buffer.
    619  * \param[in,out] numFds The size of the flat fd buffer.
    620  * \return `NO_ERROR` on success; other value on failure.
    621  *
    622  * This function will duplicate the file descriptor in `t.fence` if `t.state ==
    623  * FENCE`, in which case \p nh will be returned.
    624  */
    625 inline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
    626         native_handle_t** nh,
    627         void*& buffer, size_t& size, int*& fds, size_t& numFds) {
    628     if (size < getFlattenedSize(t)) {
    629         return NO_MEMORY;
    630     }
    631 
    632     *nh = nullptr;
    633     switch (t.state) {
    634         case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
    635             FlattenableUtils::write(buffer, size,
    636                     ::android::FenceTime::Snapshot::State::EMPTY);
    637             return NO_ERROR;
    638         case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
    639             FlattenableUtils::write(buffer, size,
    640                     ::android::FenceTime::Snapshot::State::FENCE);
    641             *nh = t.fence.getNativeHandle() == nullptr ?
    642                     nullptr : native_handle_clone(t.fence);
    643             return flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
    644         case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
    645             FlattenableUtils::write(buffer, size,
    646                     ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
    647             FlattenableUtils::write(buffer, size, t.signalTimeNs);
    648             return NO_ERROR;
    649     }
    650     return NO_ERROR;
    651 }
    652 
    653 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
    654 
    655 /**
    656  * \brief Return a lower bound on the size of the non-fd buffer required to
    657  * flatten `FrameEventsDelta`.
    658  *
    659  * \param[in] t The input `FrameEventsDelta`.
    660  * \return A lower bound on the size of the flat buffer.
    661  */
    662 constexpr size_t minFlattenedSize(
    663         HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
    664     return sizeof(uint64_t) + // mFrameNumber
    665             sizeof(uint8_t) + // mIndex
    666             sizeof(uint8_t) + // mAddPostCompositeCalled
    667             sizeof(uint8_t) + // mAddRetireCalled
    668             sizeof(uint8_t) + // mAddReleaseCalled
    669             sizeof(nsecs_t) + // mPostedTime
    670             sizeof(nsecs_t) + // mRequestedPresentTime
    671             sizeof(nsecs_t) + // mLatchTime
    672             sizeof(nsecs_t) + // mFirstRefreshStartTime
    673             sizeof(nsecs_t); // mLastRefreshStartTime
    674 }
    675 
    676 /**
    677  * \brief Return the size of the non-fd buffer required to flatten
    678  * `FrameEventsDelta`.
    679  *
    680  * \param[in] t The input `FrameEventsDelta`.
    681  * \return The required size of the flat buffer.
    682  */
    683 inline size_t getFlattenedSize(
    684         HGraphicBufferProducer::FrameEventsDelta const& t) {
    685     return minFlattenedSize(t) +
    686             getFlattenedSize(t.gpuCompositionDoneFence) +
    687             getFlattenedSize(t.displayPresentFence) +
    688             getFlattenedSize(t.displayRetireFence) +
    689             getFlattenedSize(t.releaseFence);
    690 };
    691 
    692 /**
    693  * \brief Return the number of file descriptors contained in
    694  * `FrameEventsDelta`.
    695  *
    696  * \param[in] t The input `FrameEventsDelta`.
    697  * \return The number of file descriptors contained in \p t.
    698  */
    699 inline size_t getFdCount(
    700         HGraphicBufferProducer::FrameEventsDelta const& t) {
    701     return getFdCount(t.gpuCompositionDoneFence) +
    702             getFdCount(t.displayPresentFence) +
    703             getFdCount(t.displayRetireFence) +
    704             getFdCount(t.releaseFence);
    705 };
    706 
    707 /**
    708  * \brief Flatten `FrameEventsDelta`.
    709  *
    710  * \param[in] t The source `FrameEventsDelta`.
    711  * \param[out] nh The array of native handles that are cloned.
    712  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    713  * \param[in,out] size The size of the flat non-fd buffer.
    714  * \param[in,out] fds The pointer to the flat fd buffer.
    715  * \param[in,out] numFds The size of the flat fd buffer.
    716  * \return `NO_ERROR` on success; other value on failure.
    717  *
    718  * On success, this function will duplicate file descriptors contained in \p t.
    719  * The cloned native handles will be stored in \p nh. These native handles will
    720  * need to be closed by the caller.
    721  */
    722 // Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
    723 //      FrameEventsDelta::flatten
    724 inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
    725         std::vector<native_handle_t*>* nh,
    726         void*& buffer, size_t& size, int*& fds, size_t numFds) {
    727     // Check that t.index is within a valid range.
    728     if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
    729             || t.index > std::numeric_limits<uint8_t>::max()) {
    730         return BAD_VALUE;
    731     }
    732 
    733     FlattenableUtils::write(buffer, size, t.frameNumber);
    734 
    735     // These are static_cast to uint8_t for alignment.
    736     FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
    737     FlattenableUtils::write(
    738             buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
    739     FlattenableUtils::write(
    740             buffer, size, static_cast<uint8_t>(t.addRetireCalled));
    741     FlattenableUtils::write(
    742             buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
    743 
    744     FlattenableUtils::write(buffer, size, t.postedTimeNs);
    745     FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
    746     FlattenableUtils::write(buffer, size, t.latchTimeNs);
    747     FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
    748     FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
    749     FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
    750 
    751     // Fences
    752     HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
    753     tSnapshot[0] = &t.gpuCompositionDoneFence;
    754     tSnapshot[1] = &t.displayPresentFence;
    755     tSnapshot[2] = &t.displayRetireFence;
    756     tSnapshot[3] = &t.releaseFence;
    757     nh->resize(4);
    758     for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
    759         status_t status = flatten(
    760                 *(tSnapshot[snapshotIndex]),
    761                 &((*nh)[snapshotIndex]),
    762                 buffer, size, fds, numFds);
    763         if (status != NO_ERROR) {
    764             while (snapshotIndex > 0) {
    765                 --snapshotIndex;
    766                 native_handle_close((*nh)[snapshotIndex]);
    767                 native_handle_delete((*nh)[snapshotIndex]);
    768                 (*nh)[snapshotIndex] = nullptr;
    769             }
    770             return status;
    771         }
    772     }
    773     return NO_ERROR;
    774 }
    775 
    776 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
    777 
    778 /**
    779  * \brief Return the size of the non-fd buffer required to flatten
    780  * `HGraphicBufferProducer::FrameEventHistoryDelta`.
    781  *
    782  * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
    783  * \return The required size of the flat buffer.
    784  */
    785 inline size_t getFlattenedSize(
    786         HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
    787     size_t size = 4 + // mDeltas.size()
    788             sizeof(t.compositorTiming);
    789     for (size_t i = 0; i < t.deltas.size(); ++i) {
    790         size += getFlattenedSize(t.deltas[i]);
    791     }
    792     return size;
    793 }
    794 
    795 /**
    796  * \brief Return the number of file descriptors contained in
    797  * `HGraphicBufferProducer::FrameEventHistoryDelta`.
    798  *
    799  * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
    800  * \return The number of file descriptors contained in \p t.
    801  */
    802 inline size_t getFdCount(
    803         HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
    804     size_t numFds = 0;
    805     for (size_t i = 0; i < t.deltas.size(); ++i) {
    806         numFds += getFdCount(t.deltas[i]);
    807     }
    808     return numFds;
    809 }
    810 
    811 /**
    812  * \brief Flatten `FrameEventHistoryDelta`.
    813  *
    814  * \param[in] t The source `FrameEventHistoryDelta`.
    815  * \param[out] nh The array of arrays of cloned native handles.
    816  * \param[in,out] buffer The pointer to the flat non-fd buffer.
    817  * \param[in,out] size The size of the flat non-fd buffer.
    818  * \param[in,out] fds The pointer to the flat fd buffer.
    819  * \param[in,out] numFds The size of the flat fd buffer.
    820  * \return `NO_ERROR` on success; other value on failure.
    821  *
    822  * On success, this function will duplicate file descriptors contained in \p t.
    823  * The cloned native handles will be stored in \p nh. Before making the call, \p
    824  * nh should have enough space to store `n` pointers to arrays of native
    825  * handles, where `n` is the length of `t.deltas`, and each `nh[i]` should have
    826  * enough space to store `4` native handles.
    827  */
    828 inline status_t flatten(
    829         HGraphicBufferProducer::FrameEventHistoryDelta const& t,
    830         std::vector<std::vector<native_handle_t*> >* nh,
    831         void*& buffer, size_t& size, int*& fds, size_t& numFds) {
    832     if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
    833         return BAD_VALUE;
    834     }
    835     if (size < getFlattenedSize(t)) {
    836         return NO_MEMORY;
    837     }
    838 
    839     FlattenableUtils::write(buffer, size, t.compositorTiming);
    840 
    841     FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
    842     nh->resize(t.deltas.size());
    843     for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
    844         status_t status = flatten(
    845                 t.deltas[deltaIndex], &((*nh)[deltaIndex]),
    846                 buffer, size, fds, numFds);
    847         if (status != NO_ERROR) {
    848             while (deltaIndex > 0) {
    849                 --deltaIndex;
    850                 for (size_t snapshotIndex = 0;
    851                         snapshotIndex < 4; ++snapshotIndex) {
    852                     native_handle_close((*nh)[deltaIndex][snapshotIndex]);
    853                     native_handle_delete((*nh)[deltaIndex][snapshotIndex]);
    854                     (*nh)[deltaIndex][snapshotIndex] = nullptr;
    855                 }
    856             }
    857             return status;
    858         }
    859     }
    860     return NO_ERROR;
    861 }
    862 
    863 /**
    864  * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
    865  * `::android::FrameEventHistoryDelta`.
    866  *
    867  * \param[out] l The destination `::android::FrameEventHistoryDelta`.
    868  * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
    869  *
    870  * This function will duplicate all file descriptors contained in \p t.
    871  */
    872 inline bool convertTo(
    873         ::android::FrameEventHistoryDelta* l,
    874         HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
    875 
    876     size_t const baseSize = getFlattenedSize(t);
    877     std::unique_ptr<uint8_t[]> baseBuffer(
    878             new (std::nothrow) uint8_t[baseSize]);
    879     if (!baseBuffer) {
    880         return false;
    881     }
    882 
    883     size_t const baseNumFds = getFdCount(t);
    884     std::unique_ptr<int[]> baseFds(
    885             new (std::nothrow) int[baseNumFds]);
    886     if (!baseFds) {
    887         return false;
    888     }
    889 
    890     void* buffer = static_cast<void*>(baseBuffer.get());
    891     size_t size = baseSize;
    892     int* fds = static_cast<int*>(baseFds.get());
    893     size_t numFds = baseNumFds;
    894     std::vector<std::vector<native_handle_t*> > nhAA;
    895     if (flatten(t, &nhAA, buffer, size, fds, numFds) != NO_ERROR) {
    896         return false;
    897     }
    898 
    899     void const* constBuffer = static_cast<void const*>(baseBuffer.get());
    900     size = baseSize;
    901     int const* constFds = static_cast<int const*>(baseFds.get());
    902     numFds = baseNumFds;
    903     if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
    904         for (const auto& nhA : nhAA) {
    905             for (auto nh : nhA) {
    906                 if (nh != nullptr) {
    907                     native_handle_close(nh);
    908                     native_handle_delete(nh);
    909                 }
    910             }
    911         }
    912         return false;
    913     }
    914 
    915     for (const auto& nhA : nhAA) {
    916         for (const auto& nh : nhA) {
    917             if (nh != nullptr) {
    918                 native_handle_delete(nh);
    919             }
    920         }
    921     }
    922     return true;
    923 }
    924 
    925 // Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
    926 //      IGraphicBufferProducer::QueueBufferOutput
    927 
    928 /**
    929  * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
    930  * `IGraphicBufferProducer::QueueBufferOutput`.
    931  *
    932  * \param[out] l The destination `IGraphicBufferProducer::QueueBufferOutput`.
    933  * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
    934  *
    935  * This function will duplicate all file descriptors contained in \p t.
    936  */
    937 // convert: HGraphicBufferProducer::QueueBufferOutput ->
    938 // IGraphicBufferProducer::QueueBufferOutput
    939 inline bool convertTo(
    940         BGraphicBufferProducer::QueueBufferOutput* l,
    941         HGraphicBufferProducer::QueueBufferOutput const& t) {
    942     if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
    943         return false;
    944     }
    945     l->width = t.width;
    946     l->height = t.height;
    947     l->transformHint = t.transformHint;
    948     l->numPendingBuffers = t.numPendingBuffers;
    949     l->nextFrameNumber = t.nextFrameNumber;
    950     l->bufferReplaced = t.bufferReplaced;
    951     return true;
    952 }
    953 
    954 /**
    955  * \brief Convert `IGraphicBufferProducer::DisconnectMode` to
    956  * `HGraphicBufferProducer::DisconnectMode`.
    957  *
    958  * \param[in] l The source `IGraphicBufferProducer::DisconnectMode`.
    959  * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
    960  */
    961 inline HGraphicBufferProducer::DisconnectMode toHDisconnectMode(
    962         BGraphicBufferProducer::DisconnectMode l) {
    963     switch (l) {
    964         case BGraphicBufferProducer::DisconnectMode::Api:
    965             return HGraphicBufferProducer::DisconnectMode::API;
    966         case BGraphicBufferProducer::DisconnectMode::AllLocal:
    967             return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
    968     }
    969     return HGraphicBufferProducer::DisconnectMode::API;
    970 }
    971 
    972 // H2BGraphicBufferProducer
    973 
    974 status_t H2BGraphicBufferProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    975     *buf = new GraphicBuffer();
    976     status_t fnStatus;
    977     status_t transStatus = toStatusT(mBase->requestBuffer(
    978             static_cast<int32_t>(slot),
    979             [&fnStatus, &buf] (Status status, AnwBuffer const& buffer) {
    980                 fnStatus = toStatusT(status);
    981                 if (!convertTo(buf->get(), buffer)) {
    982                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
    983                 }
    984             }));
    985     return transStatus == NO_ERROR ? fnStatus : transStatus;
    986 }
    987 
    988 status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
    989         int maxDequeuedBuffers) {
    990     return toStatusT(mBase->setMaxDequeuedBufferCount(
    991             static_cast<int32_t>(maxDequeuedBuffers)));
    992 }
    993 
    994 status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
    995     return toStatusT(mBase->setAsyncMode(async));
    996 }
    997 
    998 // FIXME: usage bits truncated -- needs a 64-bits usage version
    999 status_t H2BGraphicBufferProducer::dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,
   1000                                                  uint32_t h, ::android::PixelFormat format,
   1001                                                  uint64_t usage, uint64_t* outBufferAge,
   1002                                                  FrameEventHistoryDelta* outTimestamps) {
   1003     *fence = new Fence();
   1004     status_t fnStatus;
   1005     status_t transStatus = toStatusT(mBase->dequeueBuffer(
   1006             w, h, static_cast<PixelFormat>(format), uint32_t(usage),
   1007             outTimestamps != nullptr,
   1008             [&fnStatus, slot, fence, outTimestamps] (
   1009                     Status status,
   1010                     int32_t tSlot,
   1011                     hidl_handle const& tFence,
   1012                     HGraphicBufferProducer::FrameEventHistoryDelta const& tTs) {
   1013                 fnStatus = toStatusT(status);
   1014                 *slot = tSlot;
   1015                 if (!convertTo(fence->get(), tFence)) {
   1016                     ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
   1017                             "Invalid output fence");
   1018                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1019                 }
   1020                 if (outTimestamps && !convertTo(outTimestamps, tTs)) {
   1021                     ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
   1022                             "Invalid output timestamps");
   1023                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1024                 }
   1025             }));
   1026     if (outBufferAge) {
   1027         // Since the HAL version doesn't return the buffer age, set it to 0:
   1028         *outBufferAge = 0;
   1029     }
   1030     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1031 }
   1032 
   1033 status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
   1034     return toStatusT(mBase->detachBuffer(static_cast<int>(slot)));
   1035 }
   1036 
   1037 status_t H2BGraphicBufferProducer::detachNextBuffer(
   1038         sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
   1039     *outBuffer = new GraphicBuffer();
   1040     *outFence = new Fence();
   1041     status_t fnStatus;
   1042     status_t transStatus = toStatusT(mBase->detachNextBuffer(
   1043             [&fnStatus, outBuffer, outFence] (
   1044                     Status status,
   1045                     AnwBuffer const& tBuffer,
   1046                     hidl_handle const& tFence) {
   1047                 fnStatus = toStatusT(status);
   1048                 if (!convertTo(outFence->get(), tFence)) {
   1049                     ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
   1050                             "Invalid output fence");
   1051                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1052                 }
   1053                 if (!convertTo(outBuffer->get(), tBuffer)) {
   1054                     ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
   1055                             "Invalid output buffer");
   1056                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1057                 }
   1058             }));
   1059     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1060 }
   1061 
   1062 status_t H2BGraphicBufferProducer::attachBuffer(
   1063         int* outSlot, const sp<GraphicBuffer>& buffer) {
   1064     AnwBuffer tBuffer{};
   1065     wrapAs(&tBuffer, *buffer);
   1066     status_t fnStatus;
   1067     status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
   1068             [&fnStatus, outSlot] (Status status, int32_t slot) {
   1069                 fnStatus = toStatusT(status);
   1070                 *outSlot = slot;
   1071             }));
   1072     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1073 }
   1074 
   1075 status_t H2BGraphicBufferProducer::queueBuffer(
   1076         int slot,
   1077         const QueueBufferInput& input,
   1078         QueueBufferOutput* output) {
   1079     HGraphicBufferProducer::QueueBufferInput tInput{};
   1080     native_handle_t* nh;
   1081     if (!wrapAs(&tInput, &nh, input)) {
   1082         ALOGE("H2BGraphicBufferProducer::queueBuffer - "
   1083                 "Invalid input");
   1084         return BAD_VALUE;
   1085     }
   1086     status_t fnStatus;
   1087     status_t transStatus = toStatusT(mBase->queueBuffer(slot, tInput,
   1088             [&fnStatus, output] (
   1089                     Status status,
   1090                     HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
   1091                 fnStatus = toStatusT(status);
   1092                 if (!convertTo(output, tOutput)) {
   1093                     ALOGE("H2BGraphicBufferProducer::queueBuffer - "
   1094                             "Invalid output");
   1095                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1096                 }
   1097             }));
   1098     native_handle_delete(nh);
   1099     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1100 }
   1101 
   1102 status_t H2BGraphicBufferProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
   1103     hidl_handle tFence;
   1104     native_handle_t* nh = nullptr;
   1105     if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
   1106         ALOGE("H2BGraphicBufferProducer::cancelBuffer - "
   1107                 "Invalid input fence");
   1108         return BAD_VALUE;
   1109     }
   1110 
   1111     status_t status = toStatusT(mBase->cancelBuffer(
   1112             static_cast<int32_t>(slot), tFence));
   1113     native_handle_delete(nh);
   1114     return status;
   1115 }
   1116 
   1117 int H2BGraphicBufferProducer::query(int what, int* value) {
   1118     int result;
   1119     status_t transStatus = toStatusT(mBase->query(
   1120             static_cast<int32_t>(what),
   1121             [&result, value] (int32_t tResult, int32_t tValue) {
   1122                 result = static_cast<int>(tResult);
   1123                 *value = static_cast<int>(tValue);
   1124             }));
   1125     return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
   1126 }
   1127 
   1128 status_t H2BGraphicBufferProducer::connect(
   1129         const sp<IProducerListener>& listener, int api,
   1130         bool producerControlledByApp, QueueBufferOutput* output) {
   1131     sp<HProducerListener> tListener = listener == nullptr ?
   1132             nullptr : new B2HProducerListener(listener);
   1133     status_t fnStatus;
   1134     status_t transStatus = toStatusT(mBase->connect(
   1135             tListener, static_cast<int32_t>(api), producerControlledByApp,
   1136             [&fnStatus, output] (
   1137                     Status status,
   1138                     HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
   1139                 fnStatus = toStatusT(status);
   1140                 if (!convertTo(output, tOutput)) {
   1141                     ALOGE("H2BGraphicBufferProducer::connect - "
   1142                             "Invalid output");
   1143                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1144                 }
   1145             }));
   1146     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1147 }
   1148 
   1149 status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
   1150     return toStatusT(mBase->disconnect(
   1151             static_cast<int32_t>(api), toHDisconnectMode(mode)));
   1152 }
   1153 
   1154 status_t H2BGraphicBufferProducer::setSidebandStream(
   1155         const sp<NativeHandle>& stream) {
   1156     return toStatusT(mBase->setSidebandStream(stream == nullptr ? nullptr : stream->handle()));
   1157 }
   1158 
   1159 // FIXME: usage bits truncated -- needs a 64-bits usage version
   1160 void H2BGraphicBufferProducer::allocateBuffers(uint32_t width, uint32_t height,
   1161         ::android::PixelFormat format, uint64_t usage) {
   1162     mBase->allocateBuffers(
   1163             width, height, static_cast<PixelFormat>(format), uint32_t(usage));
   1164 }
   1165 
   1166 status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
   1167     return toStatusT(mBase->allowAllocation(allow));
   1168 }
   1169 
   1170 status_t H2BGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) {
   1171     return toStatusT(mBase->setGenerationNumber(generationNumber));
   1172 }
   1173 
   1174 String8 H2BGraphicBufferProducer::getConsumerName() const {
   1175     String8 lName;
   1176     mBase->getConsumerName([&lName] (hidl_string const& name) {
   1177                 lName = name.c_str();
   1178             });
   1179     return lName;
   1180 }
   1181 
   1182 status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
   1183     return toStatusT(mBase->setSharedBufferMode(sharedBufferMode));
   1184 }
   1185 
   1186 status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
   1187     return toStatusT(mBase->setAutoRefresh(autoRefresh));
   1188 }
   1189 
   1190 status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
   1191     return toStatusT(mBase->setDequeueTimeout(static_cast<int64_t>(timeout)));
   1192 }
   1193 
   1194 status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
   1195         sp<GraphicBuffer>* outBuffer,
   1196         sp<Fence>* outFence,
   1197         float outTransformMatrix[16]) {
   1198     status_t fnStatus;
   1199     status_t transStatus = toStatusT(mBase->getLastQueuedBuffer(
   1200             [&fnStatus, outBuffer, outFence, &outTransformMatrix] (
   1201                     Status status,
   1202                     AnwBuffer const& buffer,
   1203                     hidl_handle const& fence,
   1204                     hidl_array<float, 16> const& transformMatrix) {
   1205                 fnStatus = toStatusT(status);
   1206                 *outBuffer = new GraphicBuffer();
   1207                 if (!convertTo(outBuffer->get(), buffer)) {
   1208                     ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
   1209                             "Invalid output buffer");
   1210                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1211                 }
   1212                 *outFence = new Fence();
   1213                 if (!convertTo(outFence->get(), fence)) {
   1214                     ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
   1215                             "Invalid output fence");
   1216                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
   1217                 }
   1218                 std::copy(transformMatrix.data(),
   1219                         transformMatrix.data() + 16,
   1220                         outTransformMatrix);
   1221             }));
   1222     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1223 }
   1224 
   1225 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
   1226     mBase->getFrameTimestamps([outDelta] (
   1227             HGraphicBufferProducer::FrameEventHistoryDelta const& tDelta) {
   1228                 convertTo(outDelta, tDelta);
   1229             });
   1230 }
   1231 
   1232 status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
   1233     status_t fnStatus;
   1234     status_t transStatus = toStatusT(mBase->getUniqueId(
   1235             [&fnStatus, outId] (Status status, uint64_t id) {
   1236                 fnStatus = toStatusT(status);
   1237                 *outId = id;
   1238             }));
   1239     return transStatus == NO_ERROR ? fnStatus : transStatus;
   1240 }
   1241 
   1242 status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t* outUsage) const {
   1243     ALOGW("getConsumerUsage is not fully supported");
   1244     int result;
   1245     status_t transStatus = toStatusT(mBase->query(
   1246             NATIVE_WINDOW_CONSUMER_USAGE_BITS,
   1247             [&result, outUsage] (int32_t tResult, int32_t tValue) {
   1248                 result = static_cast<int>(tResult);
   1249                 *outUsage = static_cast<uint64_t>(tValue);
   1250             }));
   1251     return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
   1252 }
   1253 
   1254 }  // namespace utils
   1255 }  // namespace V1_0
   1256 }  // namespace bufferqueue
   1257 }  // namespace graphics
   1258 }  // namespace hardware
   1259 }  // namespace android
   1260