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