/*
 * Copyright (c) 2011-2018, 2020-2021 The Linux Foundation. All rights reserved.
 * Not a Contribution
 *
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Changes from Qualcomm Innovation Center are provided under the following license:
 * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
*/

#include "gr_buf_mgr.h"

#include <QtiGralloc.h>
#include <QtiGrallocPriv.h>
#include <QtiGrallocDefs.h>
#include <gralloctypes/Gralloc4.h>
#include <sys/mman.h>

#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <fstream>

#include "gr_adreno_info.h"
#include "gr_buf_descriptor.h"
#include "gr_utils.h"
#include "qd_utils.h"
#include "color_extensions.h"

static bool enable_logs = false;

namespace gralloc {

using aidl::android::hardware::graphics::common::BlendMode;
using aidl::android::hardware::graphics::common::Cta861_3;
using aidl::android::hardware::graphics::common::Dataspace;
using aidl::android::hardware::graphics::common::PlaneLayout;
using aidl::android::hardware::graphics::common::Rect;
using aidl::android::hardware::graphics::common::Smpte2086;
using aidl::android::hardware::graphics::common::StandardMetadataType;
using aidl::android::hardware::graphics::common::XyColor;
using ::android::hardware::graphics::common::V1_2::PixelFormat;
using IMapper_4_0_Error =  ::android::hardware::graphics::mapper::V4_0::Error;

static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
  return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
                    descriptor.GetUsage());
}

static Error dataspaceToColorMetadata(Dataspace dataspace, ColorMetaData *color_metadata) {
  ColorMetaData out;
  uint32_t primaries = (uint32_t)dataspace & (uint32_t)Dataspace::STANDARD_MASK;
  uint32_t transfer = (uint32_t)dataspace & (uint32_t)Dataspace::TRANSFER_MASK;
  uint32_t range = (uint32_t)dataspace & (uint32_t)Dataspace::RANGE_MASK;

  switch (primaries) {
    case (uint32_t)Dataspace::STANDARD_BT709:
      out.colorPrimaries = ColorPrimaries_BT709_5;
      break;
    // TODO(user): verify this is equivalent
    case (uint32_t)Dataspace::STANDARD_BT470M:
      out.colorPrimaries = ColorPrimaries_BT470_6M;
      break;
    case (uint32_t)Dataspace::STANDARD_BT601_625:
    case (uint32_t)Dataspace::STANDARD_BT601_625_UNADJUSTED:
      out.colorPrimaries = ColorPrimaries_BT601_6_625;
      break;
    case (uint32_t)Dataspace::STANDARD_BT601_525:
    case (uint32_t)Dataspace::STANDARD_BT601_525_UNADJUSTED:
      out.colorPrimaries = ColorPrimaries_BT601_6_525;
      break;
    case (uint32_t)Dataspace::STANDARD_FILM:
      out.colorPrimaries = ColorPrimaries_GenericFilm;
      break;
    case (uint32_t)Dataspace::STANDARD_BT2020:
      out.colorPrimaries = ColorPrimaries_BT2020;
      break;
    case (uint32_t)Dataspace::STANDARD_ADOBE_RGB:
      out.colorPrimaries = ColorPrimaries_AdobeRGB;
      break;
    case (uint32_t)Dataspace::STANDARD_DCI_P3:
      out.colorPrimaries = ColorPrimaries_DCIP3;
      break;
    default:
      return Error::UNSUPPORTED;
      /*
       ColorPrimaries_SMPTE_240M;
       ColorPrimaries_SMPTE_ST428;
       ColorPrimaries_EBU3213;
      */
  }

  switch (transfer) {
    case (uint32_t)Dataspace::TRANSFER_SRGB:
      out.transfer = Transfer_sRGB;
      break;
    case (uint32_t)Dataspace::TRANSFER_GAMMA2_2:
      out.transfer = Transfer_Gamma2_2;
      break;
    case (uint32_t)Dataspace::TRANSFER_GAMMA2_8:
      out.transfer = Transfer_Gamma2_8;
      break;
    case (uint32_t)Dataspace::TRANSFER_SMPTE_170M:
      out.transfer = Transfer_SMPTE_170M;
      break;
    case (uint32_t)Dataspace::TRANSFER_LINEAR:
      out.transfer = Transfer_Linear;
      break;
    case (uint32_t)Dataspace::TRANSFER_HLG:
      out.transfer = Transfer_HLG;
      break;
    default:
      return Error::UNSUPPORTED;
      /*
      Transfer_SMPTE_240M
      Transfer_Log
      Transfer_Log_Sqrt
      Transfer_XvYCC
      Transfer_BT1361
      Transfer_sYCC
      Transfer_BT2020_2_1
      Transfer_BT2020_2_2
      Transfer_SMPTE_ST2084
      Transfer_ST_428
      */
  }

  switch (range) {
    case (uint32_t)Dataspace::RANGE_FULL:
      out.range = Range_Full;
      break;
    case (uint32_t)Dataspace::RANGE_LIMITED:
      out.range = Range_Limited;
      break;
    case (uint32_t)Dataspace::RANGE_EXTENDED:
      out.range = Range_Extended;
      break;
    default:
      return Error::UNSUPPORTED;
  }

  color_metadata->colorPrimaries = out.colorPrimaries;
  color_metadata->transfer = out.transfer;
  color_metadata->range = out.range;
  return Error::NONE;
}

#ifdef QTI_YUV_PLANE_INFO
static Error getYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
  Error err = Error::NONE;
  int ret = 0;
  uint32_t width = UINT(hnd->width);
  uint32_t height = UINT(hnd->height);
  int format = hnd->format;
  uint64_t usage = hnd->usage;
  int32_t interlaced = 0;
  int plane_count = 0;
  int unaligned_width = INT(hnd->unaligned_width);
  int unaligned_height = INT(hnd->unaligned_height);
  BufferInfo info(unaligned_width, unaligned_height, format, usage);

  auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);

  memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));

  // Check metadata  if UBWC buffer has been rendered in linear format
  if (metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_LINEAR_FORMAT)])
    format = metadata->linearFormat;

  // Check metadata if geometry has been updated
  if (metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
          (int64_t)StandardMetadataType::CROP)])
    BufferInfo info(metadata->crop.right, metadata->crop.bottom, format, usage);

  if (GetAlignedWidthAndHeight(info, &width, &height)) {
    err = Error::BAD_VALUE;
    return err;
  }

  // Check metadata for interlaced content
  if (metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)])
    interlaced = 1 << 0;

  PlaneLayoutInfo plane_info[8] = {};
  // Get the chroma offsets from the handle width/height. We take advantage
  // of the fact the width _is_ the stride
  ret = GetYUVPlaneInfo(info, format, width, height, interlaced, &plane_count, plane_info, hnd);
  if (ret == 0) {
    if (interlaced && format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
      CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, &plane_info[0], &ycbcr[0]);
      unsigned int uv_stride = 0, uv_height = 0, uv_size = 0;
      unsigned int alignment = 4096;
      uint64_t field_base;
      height = (height + 1) >> 1;
      uv_stride = MMM_COLOR_FMT_UV_STRIDE(MMM_COLOR_FMT_NV12_UBWC, INT(width));
      uv_height = MMM_COLOR_FMT_UV_SCANLINES(MMM_COLOR_FMT_NV12_UBWC, INT(height));
      uv_size = ALIGN((uv_stride * uv_height), alignment);
      field_base = hnd->base + plane_info[1].offset + uv_size;
      memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
      CopyPlaneLayoutInfotoAndroidYcbcr(field_base, plane_count, &plane_info[4], &ycbcr[1]);
    } else {
      CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, plane_info, ycbcr);
      switch (format) {
        case static_cast<int>(PixelFormat::YCRCB_420_SP):
        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_NV21_ZSL:
          std::swap(ycbcr->cb, ycbcr->cr);
      }
    }
  } else {
    err = Error::BAD_VALUE;
  }
  return err;
}
#endif

int BufferManager::GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
  auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
  hidl_vec<uint8_t> crop;
  int32_t interlaced = 0;
  *stride = hnd->width;
  *height = hnd->height;
  if (metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(
          (int64_t)StandardMetadataType::CROP)]) {
    *stride = metadata->crop.right;
    *height = metadata->crop.bottom;
  } else if (metadata
                 ->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(QTI_PP_PARAM_INTERLACED)]) {
    interlaced = metadata->interlaced;
    if (interlaced && IsUBwcFormat(hnd->format)) {
      uint32_t alignedw = 0, alignedh = 0;
      BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
      int err = GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
      if (err) {
        *stride = 0;
        *height = 0;
        return err;
      }
      *stride = static_cast<int>(alignedw);
      *height = static_cast<int>(alignedh * 2);
    }
  }
  return 0;
}

BufferManager::BufferManager() : next_id_(0) {
  handles_map_.clear();
  allocator_ = new Allocator();
  enable_logs = property_get_bool(ENABLE_LOGS_PROP, 0);
}

BufferManager *BufferManager::GetInstance() {
  static BufferManager *instance = new BufferManager();
  return instance;
}

BufferManager::~BufferManager() {
  if (allocator_) {
    delete allocator_;
  }
}

void BufferManager::SetGrallocDebugProperties(gralloc::GrallocProperties props) {
  allocator_->SetProperties(props);
  if (AdrenoMemInfo::GetInstance()) {
    AdrenoMemInfo::GetInstance()->AdrenoSetProperties(props);
  }
}

Error BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
  auto hnd = buf->handle;
  ALOGD_IF(enable_logs, "FreeBuffer handle:%p", hnd);

  if (private_handle_t::validate(hnd) != 0) {
    ALOGE("FreeBuffer: Invalid handle: %p", hnd);
    return Error::BAD_BUFFER;
  }

  auto meta_size = GetMetaDataSize(hnd->reserved_size, buf->custom_content_md_size);

  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, hnd->fd,
                             buf->ion_handle_main) != 0) {
    return Error::BAD_BUFFER;
  }

  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
                             hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
    return Error::BAD_BUFFER;
  }

  private_handle_t *handle = const_cast<private_handle_t *>(hnd);
  handle->fd = -1;
  handle->fd_metadata = -1;
  free(handle);
  return Error::NONE;
}

Error BufferManager::ValidateBufferSize(private_handle_t const *hnd, BufferInfo info) {
  unsigned int size, alignedw, alignedh;
  unsigned int max_bpp =
      gralloc::GetBppForUncompressedRGB(static_cast<int>(PixelFormat::RGBA_FP16));
  info.format = GetImplDefinedFormat(info.usage, info.format);
  int ret = GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
  if ((ret < 0) || (OVERFLOW((alignedw * max_bpp), alignedh))) {
    return Error::BAD_BUFFER;
  }
  auto ion_fd_size = static_cast<unsigned int>(lseek(hnd->fd, 0, SEEK_END));
  if (size != ion_fd_size) {
    return Error::BAD_VALUE;
  }
  return Error::NONE;
}

void BufferManager::RegisterHandleLocked(const private_handle_t *hnd, int ion_handle,
                                         int ion_handle_meta) {
  auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);

  if (hnd->base_metadata) {
#ifdef METADATA_V2
    buffer->reserved_size = hnd->reserved_size;
    if (buffer->reserved_size > 0) {
      buffer->reserved_region_ptr =
          reinterpret_cast<void *>(hnd->base_metadata + sizeof(MetaData_t));
    } else {
      buffer->reserved_region_ptr = nullptr;
    }

    buffer->custom_content_md_size = hnd->custom_content_md_reserved_size;
    if (buffer->custom_content_md_size > 0) {
      buffer->custom_content_md_region_ptr =
          reinterpret_cast<void *>(hnd->base_metadata + sizeof(MetaData_t) + buffer->reserved_size);
    } else {
      buffer->custom_content_md_region_ptr = nullptr;
    }
#else
    buffer->reserved_size = hnd->reserved_size;
    buffer->reserved_region_ptr = reinterpret_cast<void *>(hnd->base_metadata + sizeof(MetaData_t));
#endif
  }

  handles_map_.emplace(std::make_pair(hnd, buffer));
}

Error BufferManager::ImportHandleLocked(private_handle_t *hnd) {
  if (private_handle_t::validate(hnd) != 0) {
    ALOGE("ImportHandleLocked: Invalid handle: %p", hnd);
    return Error::BAD_BUFFER;
  }
  ALOGD_IF(enable_logs, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
  int ion_handle = allocator_->ImportBuffer(hnd->fd);
  if (ion_handle < 0) {
    ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
    return Error::BAD_BUFFER;
  }
  int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
  if (ion_handle_meta < 0) {
    ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd,
          hnd->id);
    return Error::BAD_BUFFER;
  }
  // Initialize members that aren't transported
  hnd->size = static_cast<unsigned int>(lseek(hnd->fd, 0, SEEK_END));
  hnd->offset = 0;
  hnd->offset_metadata = 0;
  hnd->base = 0;
  hnd->base_metadata = 0;
  hnd->gpuaddr = 0;

  if (ValidateAndMap(hnd)) {
    ALOGE("Failed to map metadata: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
    return Error::BAD_BUFFER;
  }

  RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
  allocated_ += hnd->size;
  if (allocated_ >= kAllocThreshold) {
    kAllocThreshold += kMemoryOffset;
    BuffersDump();
  }
  return Error::NONE;
}

std::shared_ptr<BufferManager::Buffer> BufferManager::GetBufferFromHandleLocked(
    const private_handle_t *hnd) {
  auto it = handles_map_.find(hnd);
  if (it != handles_map_.end()) {
    return it->second;
  } else {
    return nullptr;
  }
}

Error BufferManager::MapBuffer(private_handle_t const *handle) {
  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
  ALOGD_IF(enable_logs, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);

  hnd->base = 0;
  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
                            hnd->fd) != 0) {
    return Error::BAD_BUFFER;
  }
  return Error::NONE;
}

Error BufferManager::IsBufferImported(const private_handle_t *hnd) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf != nullptr) {
    return Error::NONE;
  }
  return Error::BAD_BUFFER;
}

Error BufferManager::RetainBuffer(private_handle_t const *hnd) {
  ALOGD_IF(enable_logs, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
  auto err = Error::NONE;
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf != nullptr) {
    buf->IncRef();
  } else {
    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
    err = ImportHandleLocked(handle);
  }
  return err;
}

Error BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
  ALOGD_IF(enable_logs, "Release buffer handle:%p", hnd);
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf == nullptr) {
    ALOGE("Could not find handle: %p", hnd);
    return Error::BAD_BUFFER;
  } else {
    if (buf->DecRef()) {
      handles_map_.erase(hnd);
      // Unmap, close ion handle and close fd
      if (allocated_ >= hnd->size) {
        allocated_ -= hnd->size;
      }
      FreeBuffer(buf);
    }
  }
  return Error::NONE;
}

Error BufferManager::LockBuffer(const private_handle_t *hnd, uint64_t usage) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto err = Error::NONE;
  ALOGD_IF(enable_logs, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);

  // If buffer is not meant for CPU return err
  if (!CpuCanAccess(usage)) {
    return Error::BAD_VALUE;
  }

  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf == nullptr) {
    return Error::BAD_BUFFER;
  }

  if (hnd->base == 0) {
    // we need to map for real
    err = MapBuffer(hnd);
  }

  // Invalidate if CPU reads in software and there are non-CPU
  // writers. No need to do this for the metadata buffer as it is
  // only read/written in software.

  // todo use handle here
  if (err == Error::NONE && (hnd->flags & qtigralloc::PRIV_FLAGS_USES_ION) &&
      (hnd->flags & qtigralloc::PRIV_FLAGS_CACHED)) {
    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
                                buf->ion_handle_main, CACHE_INVALIDATE, hnd->fd)) {
      return Error::BAD_BUFFER;
    }
  }

  // Mark the buffer to be flushed after CPU write.
  if (err == Error::NONE && CpuCanWrite(usage)) {
    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
    handle->flags |= qtigralloc::PRIV_FLAGS_NEEDS_FLUSH;
  }

  return err;
}

Error BufferManager::FlushBuffer(const private_handle_t *handle) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto status = Error::NONE;

  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf == nullptr) {
    return Error::BAD_BUFFER;
  }

  if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
                              buf->ion_handle_main, CACHE_CLEAN, hnd->fd) != 0) {
    status = Error::BAD_BUFFER;
  }

  return status;
}

Error BufferManager::RereadBuffer(const private_handle_t *handle) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto status = Error::NONE;

  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf == nullptr) {
    return Error::BAD_BUFFER;
  }

  if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
                              buf->ion_handle_main, CACHE_INVALIDATE, hnd->fd) != 0) {
    status = Error::BAD_BUFFER;
  }

  return status;
}

Error BufferManager::UnlockBuffer(const private_handle_t *handle) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  auto status = Error::NONE;

  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
  auto buf = GetBufferFromHandleLocked(hnd);
  if (buf == nullptr) {
    return Error::BAD_BUFFER;
  }

  if (hnd->flags & qtigralloc::PRIV_FLAGS_NEEDS_FLUSH) {
    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
                                buf->ion_handle_main, CACHE_CLEAN, hnd->fd) != 0) {
      status = Error::BAD_BUFFER;
    }
    hnd->flags &= ~qtigralloc::PRIV_FLAGS_NEEDS_FLUSH;
  } else {
    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
                                buf->ion_handle_main, CACHE_READ_DONE, hnd->fd) != 0) {
      status = Error::BAD_BUFFER;
    }
  }

  return status;
}

// TODO(user): Move this once private_handle_t definition is out of QSSI
static void InitializePrivateHandle(private_handle_t *hnd, int fd, int meta_fd, int flags,
                                    int width, int height, int uw, int uh, int format, int buf_type,
                                    unsigned int size, uint64_t usage = 0) {
  hnd->fd = fd;
  hnd->fd_metadata = meta_fd;
  hnd->magic = private_handle_t::kMagic;
  hnd->flags = flags;
  hnd->width = width;
  hnd->height = height;
  hnd->unaligned_width = uw;
  hnd->unaligned_height = uh;
  hnd->format = format;
  hnd->buffer_type = buf_type;
  hnd->layer_count = 1;
  hnd->id = 0;
  hnd->usage = usage;
  hnd->size = size;
  hnd->offset = 0;
  hnd->offset_metadata = 0;
  hnd->base = 0;
  hnd->base_metadata = 0;
  hnd->gpuaddr = 0;
  hnd->version = static_cast<int>(sizeof(native_handle));
  hnd->numInts = private_handle_t::NumInts();
  hnd->numFds = private_handle_t::kNumFds;
}

Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
                                    unsigned int bufferSize, bool testAlloc) {
  if (!handle)
    return Error::BAD_BUFFER;
  std::lock_guard<std::mutex> buffer_lock(buffer_lock_);

  uint64_t usage = descriptor.GetUsage();
  int format = GetImplDefinedFormat(usage, descriptor.GetFormat());
  uint32_t layer_count = descriptor.GetLayerCount();

  unsigned int size;
  unsigned int alignedw, alignedh;
  int err = 0;

  int buffer_type = GetBufferType(format);
  BufferInfo info = GetBufferInfo(descriptor);
  info.format = format;
  info.layer_count = layer_count;

  GraphicsMetadata graphics_metadata = {};
  err = GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh, &graphics_metadata);
  if (err == -ENOTSUP) {
    return Error::UNSUPPORTED;
  } else if (err < 0) {
    return Error::BAD_DESCRIPTOR;
  }

  if (size == 0) {
    ALOGW("gralloc failed to allocate buffer for size %d format %d AWxAH %dx%d usage %" PRIu64,
          size, format, alignedw, alignedh, usage);
    return Error::UNSUPPORTED;
  }

  if (testAlloc) {
    return Error::NONE;
  }

  size = (bufferSize >= size) ? bufferSize : size;
  uint64_t flags = 0;
  auto page_size = UINT(getpagesize());
  AllocData data;
  data.align = GetDataAlignment(format, usage);
  data.size = size;
  data.handle = (uintptr_t)handle;
  data.uncached = UseUncached(format, usage);

  // Allocate buffer memory
  err = allocator_->AllocateMem(&data, usage, format);
  if (err) {
    ALOGE("gralloc failed to allocate err=%s format %d size %d WxH %dx%d usage %" PRIu64,
          strerror(-err), format, size, alignedw, alignedh, usage);
    return Error::NO_RESOURCES;
  }

  // Allocate memory for MetaData
  AllocData e_data;
  uint64_t custom_content_md_reserved_size = GetCustomContentMetadataSize(format, usage);
  e_data.size = static_cast<unsigned int>(GetMetaDataSize(descriptor.GetReservedSize(),
                                                          custom_content_md_reserved_size));
  e_data.handle = data.handle;
  e_data.align = page_size;

  err = allocator_->AllocateMem(&e_data, 0, 0);
  if (err) {
    ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
    return Error::NO_RESOURCES;
  }

  flags = GetHandleFlags(format, usage);
  flags |= data.alloc_type;

  // Create handle
  // In FreeBuffer(), there's no way to tell if malloc or new was used at allocation time
  // On the importBuffer path, native_handle_clone() uses malloc
  // To avoid mismatch between malloc/free and new/delete in FreeBuffer(),
  // this was changed to malloc
  private_handle_t *hnd = static_cast<private_handle_t *>(malloc(sizeof(private_handle_t)));
  if (hnd == nullptr) {
    ALOGE("gralloc failed to allocate private_handle_t");
    return Error::NO_RESOURCES;
  }

  InitializePrivateHandle(hnd, data.fd, e_data.fd, INT(flags), INT(alignedw), INT(alignedh),
                          descriptor.GetWidth(), descriptor.GetHeight(), format, buffer_type,
                          data.size, usage);

  hnd->reserved_size = static_cast<unsigned int>(descriptor.GetReservedSize());
  hnd->id = ++next_id_;
  hnd->base = 0;
  hnd->base_metadata = 0;
  hnd->layer_count = layer_count;
  hnd->custom_content_md_reserved_size = custom_content_md_reserved_size;

  bool use_adreno_for_size = CanUseAdrenoForSize(buffer_type, usage);
  if (use_adreno_for_size) {
    SetMetaData(hnd, QTI_GRAPHICS_METADATA, reinterpret_cast<void *>(&graphics_metadata));
    UnmapAndReset(hnd);
  }

  auto error = ValidateAndMap(hnd);

  if (error != 0) {
    ALOGE("ValidateAndMap failed");
    return Error::BAD_BUFFER;
  }
  auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
  auto nameLength = std::min(descriptor.GetName().size(), size_t(MAX_NAME_LEN - 1));
  nameLength = descriptor.GetName().copy(metadata->name, nameLength);
  metadata->name[nameLength] = '\0';

#ifdef METADATA_V2
  metadata->reservedSize = descriptor.GetReservedSize();
#else
  metadata->reservedRegion.size =
      std::min(descriptor.GetReservedSize(), (uint64_t)RESERVED_REGION_SIZE);
#endif
  metadata->crop.top = 0;
  metadata->crop.left = 0;
  metadata->crop.right = hnd->width;
  metadata->crop.bottom = hnd->height;

  UnmapAndReset(hnd);

  *handle = hnd;

  RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
  ALOGD_IF(enable_logs, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
  if (enable_logs) {
    private_handle_t::Dump(hnd);
  }
  return Error::NONE;
}

void BufferManager::BuffersDump() {
  char timeStamp[32];
  char hms[32];
  uint64_t millis;
  struct timeval tv;
  struct tm ptm;

  gettimeofday(&tv, NULL);
  localtime_r(&tv.tv_sec, &ptm);
  strftime(hms, sizeof(hms), "%H:%M:%S", &ptm);
  millis = tv.tv_usec / 1000;
  snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03" PRIu64, hms, millis);

  std::fstream fs;
  fs.open(file_dump_.kDumpFile, std::ios::app);
  if (!fs) {
    return;
  }
  fs << "============================" << std::endl;
  fs << timeStamp << std::endl;
  fs << "Total layers = " << handles_map_.size() << std::endl;
  uint64_t totalAllocationSize = 0;
  for (auto it : handles_map_) {
    auto buf = it.second;
    auto hnd = buf->handle;
    auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
    fs << std::setw(80) << "Client:" << (metadata ? metadata->name : "No name");
    fs << std::setw(20) << "WxH:" << std::setw(4) << hnd->width << " x " << std::setw(4)
       << hnd->height;
    fs << std::setw(20) << "Size: " << std::setw(9) << hnd->size << std::endl;
    totalAllocationSize += hnd->size;
  }
  fs << "Total allocation  = " << totalAllocationSize / 1024 << "KiB" << std::endl;
  file_dump_.position = fs.tellp();
  if (file_dump_.position > (20 * 1024 * 1024)) {
    file_dump_.position = 0;
  }
  fs.close();
}

Error BufferManager::Dump(std::ostringstream *os) {
  std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
  for (auto it : handles_map_) {
    auto buf = it.second;
    auto hnd = buf->handle;
    *os << "handle id: " << std::setw(4) << hnd->id;
    *os << " fd: " << std::setw(3) << hnd->fd;
    *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
    *os << " wxh: " << std::setw(4) << hnd->width << " x " << std::setw(4) << hnd->height;
    *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
    *os << std::setw(4) << hnd->unaligned_height;
    *os << " size: " << std::setw(9) << hnd->size;
    *os << std::hex << std::setfill('0');
    *os << " priv_flags: "
        << "0x" << std::setw(8) << hnd->flags;
    *os << " usage: "
        << "0x" << std::setw(8) << hnd->usage;
    // TODO(user): get format string from qdutils
    *os << " format: "
        << "0x" << std::setw(8) << hnd->format;
    *os << std::dec << std::setfill(' ') << std::endl;
  }
  return Error::NONE;
}

// Get list of private handles in handles_map_
Error BufferManager::GetAllHandles(std::vector<const private_handle_t *> *out_handle_list) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  if (handles_map_.empty()) {
    return Error::NO_RESOURCES;
  }
  out_handle_list->reserve(handles_map_.size());
  for (auto handle : handles_map_) {
    out_handle_list->push_back(handle.first);
  }
  return Error::NONE;
}

Error BufferManager::GetReservedRegion(private_handle_t *handle, void **reserved_region,
                                       uint64_t *reserved_region_size) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  if (!handle)
    return Error::BAD_BUFFER;

  auto buf = GetBufferFromHandleLocked(handle);
  if (buf == nullptr)
    return Error::BAD_BUFFER;
  if (!handle->base_metadata) {
    return Error::BAD_BUFFER;
  }

  *reserved_region = buf->reserved_region_ptr;
  *reserved_region_size = buf->reserved_size;

  return Error::NONE;
}

Error BufferManager::GetCustomContentMdRegion(private_handle_t *handle,
                                            void **custom_content_md_region,
                                            uint64_t *custom_content_md_region_size) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  if (!handle)
    return Error::BAD_BUFFER;

  auto buf = GetBufferFromHandleLocked(handle);
  if (buf == nullptr)
    return Error::BAD_BUFFER;
  if (!handle->base_metadata) {
    return Error::BAD_BUFFER;
  }

  *custom_content_md_region = buf->custom_content_md_region_ptr;
  *custom_content_md_region_size = buf->custom_content_md_size;

  return Error::NONE;
}

Error BufferManager::GetMetadataValue(private_handle_t *handle, int64_t metadatatype_value,
                                      void *param) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  if (!handle)
    return Error::BAD_BUFFER;
  auto buf = GetBufferFromHandleLocked(handle);
  if (buf == nullptr)
    return Error::BAD_BUFFER;

  if (!handle->base_metadata) {
    return Error::BAD_BUFFER;
  }

  auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
  if (metadatatype_value == QTI_CUSTOM_CONTENT_METADATA) {
    Error error = Error::NONE;
    void *custom_content_md_region = buf->custom_content_md_region_ptr;
    uint64_t custom_content_md_region_size = buf->custom_content_md_size;

      if (buf->custom_content_md_region_ptr == nullptr ||
          buf->custom_content_md_size != sizeof(CustomContentMetadata)) {
        error = Error::UNSUPPORTED;
      } else {
        memcpy(param, custom_content_md_region, sizeof(CustomContentMetadata));
      }

    return error;
  } else {
    return GetMetaDataValue(handle, metadatatype_value, param);
  }
}

#ifdef QTI_CUSTOM_CONTENT_METADATA
static Error GetCustomMetadataHelper(void *custom_content_md_region_ptr,
                                     uint64_t custom_content_md_size,
                                     hidl_vec<uint8_t> *out) {
  Error error = Error::NONE;
  if (custom_content_md_region_ptr == nullptr ||
      custom_content_md_size != sizeof(CustomContentMetadata)) {
    error = Error::UNSUPPORTED;
  } else {
    if (qtigralloc::encodeCustomContentMetadata(custom_content_md_region_ptr, out) !=
        android::hardware::graphics::mapper::V4_0::Error::NONE) {
      error = Error::BAD_VALUE;
    }
  }

  return error;
}
#endif

Error BufferManager::GetMetadata(private_handle_t *handle, int64_t metadatatype_value,
                                 hidl_vec<uint8_t> *out) {
  std::lock_guard<std::mutex> lock(buffer_lock_);
  if (!handle)
    return Error::BAD_BUFFER;
  auto buf = GetBufferFromHandleLocked(handle);
  if (buf == nullptr)
    return Error::BAD_BUFFER;

  if (!handle->base_metadata) {
    return Error::BAD_BUFFER;
  }

  auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);

  void *metadata_ptr = nullptr;
  auto result = GetMetaDataByReference(handle, metadatatype_value, &metadata_ptr);
  Error error = Error::NONE;
  switch (metadatatype_value) {
    case (int64_t)StandardMetadataType::BUFFER_ID:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeBufferId(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::NAME: {
      if (metadata_ptr != nullptr) {
        std::string name(reinterpret_cast<char *>(metadata_ptr));
        android::gralloc4::encodeName(name, out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    }
    case (int64_t)StandardMetadataType::WIDTH:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeWidth(
            static_cast<uint64_t>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::HEIGHT:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeHeight(
            static_cast<uint64_t>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::LAYER_COUNT:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeLayerCount(
            static_cast<uint64_t>(*reinterpret_cast<uint32_t *>(metadata_ptr)), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
      // TODO(user): need to return IMPLEMENTATION_DEFINED,
      // which wouldn't be known from private_handle_t
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodePixelFormatRequested(
            static_cast<PixelFormat>(*reinterpret_cast<int32_t *>(metadata_ptr)), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC: {
      uint32_t drm_format = 0;
      uint64_t drm_format_modifier = 0;
      GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
      android::gralloc4::encodePixelFormatFourCC(drm_format, out);
      break;
    }
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER: {
      uint32_t drm_format = 0;
      uint64_t drm_format_modifier = 0;
      GetDRMFormat(handle->format, handle->flags, &drm_format, &drm_format_modifier);
      android::gralloc4::encodePixelFormatModifier(drm_format_modifier, out);
      break;
    }
    case (int64_t)StandardMetadataType::USAGE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUsage(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeAllocationSize(*reinterpret_cast<uint64_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::PROTECTED_CONTENT: {
      // update to use metadata ptr when implemented
      uint64_t protected_content = (handle->flags & qtigralloc::PRIV_FLAGS_SECURE_BUFFER) ? 1 : 0;
      android::gralloc4::encodeProtectedContent(protected_content, out);
      break;
    }
    case (int64_t)StandardMetadataType::CHROMA_SITING:
      android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None, out);
      break;
    case (int64_t)StandardMetadataType::DATASPACE:
#ifdef METADATA_V2
      if (metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)]) {
#endif
        Dataspace dataspace;
        ColorMetadataToDataspace(metadata->color, &dataspace);
        android::gralloc4::encodeDataspace(dataspace, out);
#ifdef METADATA_V2
      } else {
        android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, out);
      }
#endif
      break;
    case (int64_t)StandardMetadataType::INTERLACED:
      if (metadata->interlaced > 0) {
        android::gralloc4::encodeInterlaced(qtigralloc::Interlaced_Qti, out);
      } else {
        android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, out);
      }
      break;
    case (int64_t)StandardMetadataType::COMPRESSION:
      if (handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED ||
          handle->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED_PI) {
        android::gralloc4::encodeCompression(qtigralloc::Compression_QtiUBWC, out);
      } else {
        android::gralloc4::encodeCompression(android::gralloc4::Compression_None, out);
      }
      break;
    case (int64_t)StandardMetadataType::PLANE_LAYOUTS: {
      std::vector<PlaneLayout> plane_layouts;
      GetPlaneLayout(handle, &plane_layouts);
      android::gralloc4::encodePlaneLayouts(plane_layouts, out);
      break;
    }
    case (int64_t)StandardMetadataType::BLEND_MODE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeBlendMode(*reinterpret_cast<BlendMode *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case (int64_t)StandardMetadataType::SMPTE2086: {
      if (metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled) {
        Smpte2086 mastering_display_values;
        mastering_display_values.primaryRed = {
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0]) /
                50000.0f,
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1]) /
                50000.0f};
        mastering_display_values.primaryGreen = {
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0]) /
                50000.0f,
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1]) /
                50000.0f};
        mastering_display_values.primaryBlue = {
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0]) /
                50000.0f,
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1]) /
                50000.0f};
        mastering_display_values.whitePoint = {
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[0]) /
                50000.0f,
            static_cast<float>(metadata->color.masteringDisplayInfo.primaries.whitePoint[1]) /
                50000.0f};
        mastering_display_values.maxLuminance =
            static_cast<float>(metadata->color.masteringDisplayInfo.maxDisplayLuminance);
        mastering_display_values.minLuminance =
            static_cast<float>(metadata->color.masteringDisplayInfo.minDisplayLuminance) / 10000.0f;
        android::gralloc4::encodeSmpte2086(mastering_display_values, out);
      } else {
        android::gralloc4::encodeSmpte2086(std::nullopt, out);
      }
      break;
    }
    case (int64_t)StandardMetadataType::CTA861_3: {
      if (metadata->color.contentLightLevel.lightLevelSEIEnabled) {
        Cta861_3 content_light_level;
        content_light_level.maxContentLightLevel =
            static_cast<float>(metadata->color.contentLightLevel.maxContentLightLevel);
        content_light_level.maxFrameAverageLightLevel =
            static_cast<float>(metadata->color.contentLightLevel.minPicAverageLightLevel) /
            10000.0f;
        android::gralloc4::encodeCta861_3(content_light_level, out);
      } else {
        android::gralloc4::encodeCta861_3(std::nullopt, out);
      }
      break;
    }
    case (int64_t)StandardMetadataType::SMPTE2094_40: {
      if (metadata->color.dynamicMetaDataValid &&
          metadata->color.dynamicMetaDataLen <= HDR_DYNAMIC_META_DATA_SZ) {
        std::vector<uint8_t> dynamic_metadata_payload;
        dynamic_metadata_payload.resize(metadata->color.dynamicMetaDataLen);
        dynamic_metadata_payload.assign(
            metadata->color.dynamicMetaDataPayload,
            metadata->color.dynamicMetaDataPayload + metadata->color.dynamicMetaDataLen);
        android::gralloc4::encodeSmpte2094_40(dynamic_metadata_payload, out);
      } else {
        android::gralloc4::encodeSmpte2094_40(std::nullopt, out);
      }
      break;
    }
    case (int64_t)StandardMetadataType::CROP: {
      // Crop is the same for all planes
      std::vector<Rect> out_crop = {
          {metadata->crop.left, metadata->crop.top, metadata->crop.right, metadata->crop.bottom}};
      android::gralloc4::encodeCrop(out_crop, out);
      break;
    }
    case QTI_VT_TIMESTAMP:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint64(qtigralloc::MetadataType_VTTimestamp,
                                        *reinterpret_cast<uint64_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_COLOR_METADATA:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeColorMetadata(*reinterpret_cast<ColorMetaData *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_PP_PARAM_INTERLACED:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeInt32(qtigralloc::MetadataType_PPParamInterlaced,
                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_VIDEO_PERF_MODE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_VideoPerfMode,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_GRAPHICS_METADATA:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeGraphicsMetadata(*reinterpret_cast<GraphicsMetadata *>(metadata_ptr),
                                           out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_UBWC_CR_STATS_INFO:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeUBWCStats(reinterpret_cast<UBWCStats *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_REFRESH_RATE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeFloat(qtigralloc::MetadataType_RefreshRate,
                                       *reinterpret_cast<float *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_MAP_SECURE_BUFFER:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeInt32(qtigralloc::MetadataType_MapSecureBuffer,
                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_LINEAR_FORMAT:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_LinearFormat,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_SINGLE_BUFFER_MODE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_SingleBufferMode,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_CVP_METADATA:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeCVPMetadata(*reinterpret_cast<CVPMetadata *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_VIDEO_HISTOGRAM_STATS:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeVideoHistogramMetadata(
            *reinterpret_cast<VideoHistogramMetadata *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#ifdef QTI_VIDEO_TRANSCODE_STATS
     case QTI_VIDEO_TRANSCODE_STATS:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeVideoTranscodeStatsMetadata(
            *reinterpret_cast<VideoTranscodeStatsMetadata *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
    case QTI_FD:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeInt32(qtigralloc::MetadataType_FD,
                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_PRIVATE_FLAGS:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeInt32(qtigralloc::MetadataType_PrivateFlags,
                                       *reinterpret_cast<int32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_ALIGNED_WIDTH_IN_PIXELS:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedWidthInPixels,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_ALIGNED_HEIGHT_IN_PIXELS:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#ifdef METADATA_V2
    case QTI_STANDARD_METADATA_STATUS:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeMetadataState(reinterpret_cast<bool *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
    case QTI_VENDOR_METADATA_STATUS:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeMetadataState(reinterpret_cast<bool *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_BUFFER_TYPE
    case QTI_BUFFER_TYPE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_BufferType,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_VIDEO_TS_INFO
    case QTI_VIDEO_TS_INFO:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeVideoTimestampInfo(*reinterpret_cast<VideoTimestampInfo *>(metadata_ptr),
                                             out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_CUSTOM_DIMENSIONS_STRIDE
    case QTI_CUSTOM_DIMENSIONS_STRIDE: {
      int32_t stride;
      int32_t height;
      if (GetCustomDimensions(handle, &stride, &height) == 0) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_CustomDimensionsStride, stride,
                                        out);
        break;
      } else {
        error = Error::BAD_VALUE;
        break;
      }
    }
#endif
#ifdef QTI_CUSTOM_DIMENSIONS_HEIGHT
    case QTI_CUSTOM_DIMENSIONS_HEIGHT: {
      int32_t stride = handle->width;
      int32_t height = handle->height;
      if (GetCustomDimensions(handle, &stride, &height) == 0) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_CustomDimensionsHeight, height,
                                        out);
        break;
      } else {
        error = Error::BAD_VALUE;
        break;
      }
    }
#endif
#ifdef QTI_RGB_DATA_ADDRESS
    case QTI_RGB_DATA_ADDRESS: {
      void *rgb_data = nullptr;
      if (GetRgbDataAddress(handle, &rgb_data) == 0) {
        uint64_t addr_ptr = reinterpret_cast<std::uintptr_t>(rgb_data);
        android::gralloc4::encodeUint64(qtigralloc::MetadataType_RgbDataAddress, addr_ptr, out);
        break;
      } else {
        error = Error::BAD_BUFFER;
        break;
      }
    }
#endif
#ifdef QTI_COLORSPACE
    case QTI_COLORSPACE: {
      uint32_t colorspace;
      error = GetColorSpaceFromColorMetaData(metadata->color, &colorspace);
      if (error == Error::NONE) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_ColorSpace, colorspace, out);
        break;
      } else {
        error = Error::BAD_BUFFER;
        break;
      }
    }
#endif
#ifdef QTI_YUV_PLANE_INFO
    case QTI_YUV_PLANE_INFO: {
      qti_ycbcr layout[2];
      android_ycbcr yuv_plane_info[2];
      error = getYUVPlaneInfo(handle, yuv_plane_info);
      if (error == Error::NONE) {
        for (int i = 0; i < 2; i++) {
          layout[i].y = yuv_plane_info[i].y;
          layout[i].cr = yuv_plane_info[i].cr;
          layout[i].cb = yuv_plane_info[i].cb;
          layout[i].yStride = static_cast<uint32_t>(yuv_plane_info[i].ystride);
          layout[i].cStride = static_cast<uint32_t>(yuv_plane_info[i].cstride);
          layout[i].chromaStep = static_cast<uint32_t>(yuv_plane_info[i].chroma_step);
        }

        uint64_t yOffset = (reinterpret_cast<uint64_t>(layout[0].y) - handle->base);
        uint64_t crOffset = (reinterpret_cast<uint64_t>(layout[0].cr) - handle->base);
        uint64_t cbOffset = (reinterpret_cast<uint64_t>(layout[0].cb) - handle->base);
        ALOGD_IF(enable_logs, " layout: y: %" PRIu64 " , cr: %" PRIu64 " , cb: %" PRIu64
                              " , yStride: %d, cStride: %d, chromaStep: %d ",
                 yOffset, crOffset, cbOffset, layout[0].yStride, layout[0].cStride,
                 layout[0].chromaStep);

        qtigralloc::encodeYUVPlaneInfoMetadata(layout, out);
        break;
      } else {
        error = Error::BAD_BUFFER;
        break;
      }
    }
#endif
#ifdef QTI_BUFFER_PERMISSION
    case QTI_BUFFER_PERMISSION:
      if (metadata_ptr != nullptr) {
        qtigralloc::encodeBufferPermission(reinterpret_cast<BufferPermission *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_MEM_HANDLE
    case QTI_MEM_HANDLE:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeInt64(qtigralloc::MetadataType_MemHandle,
                                       *reinterpret_cast<int64_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_TIMED_RENDERING
    case QTI_TIMED_RENDERING:
      if (metadata_ptr != nullptr) {
        android::gralloc4::encodeUint32(qtigralloc::MetadataType_TimedRendering,
                                        *reinterpret_cast<uint32_t *>(metadata_ptr), out);
      } else {
        return Error::BAD_VALUE;
      }
      break;
#endif
#ifdef QTI_CUSTOM_CONTENT_METADATA
    case QTI_CUSTOM_CONTENT_METADATA:
      error = GetCustomMetadataHelper(buf->custom_content_md_region_ptr,
                                      buf->custom_content_md_size, out);
      break;
#endif
    default:
      error = Error::UNSUPPORTED;
  }

  return error;
}

Error BufferManager::SetMetadata(private_handle_t *handle, int64_t metadatatype_value,
                                 hidl_vec<uint8_t> in) {
  std::lock_guard<std::mutex> lock(buffer_lock_);

  if (!handle)
    return Error::BAD_BUFFER;

  auto buf = GetBufferFromHandleLocked(handle);
  if (buf == nullptr)
    return Error::BAD_BUFFER;

  if (!handle->base_metadata) {
    return Error::BAD_BUFFER;
  }
  if (in.size() == 0) {
    return Error::UNSUPPORTED;
  }

  auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);

  switch (metadatatype_value) {
    // These are constant (unchanged after allocation)
    case (int64_t)StandardMetadataType::BUFFER_ID:
    case (int64_t)StandardMetadataType::NAME:
    case (int64_t)StandardMetadataType::WIDTH:
    case (int64_t)StandardMetadataType::HEIGHT:
    case (int64_t)StandardMetadataType::LAYER_COUNT:
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_REQUESTED:
    case (int64_t)StandardMetadataType::USAGE:
      return Error::BAD_VALUE;
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_FOURCC:
    case (int64_t)StandardMetadataType::PIXEL_FORMAT_MODIFIER:
    case (int64_t)StandardMetadataType::PROTECTED_CONTENT:
    case (int64_t)StandardMetadataType::ALLOCATION_SIZE:
    case (int64_t)StandardMetadataType::PLANE_LAYOUTS:
    case (int64_t)StandardMetadataType::CHROMA_SITING:
    case (int64_t)StandardMetadataType::INTERLACED:
    case (int64_t)StandardMetadataType::COMPRESSION:
    case QTI_FD:
    case QTI_PRIVATE_FLAGS:
    case QTI_ALIGNED_WIDTH_IN_PIXELS:
    case QTI_ALIGNED_HEIGHT_IN_PIXELS:
#ifdef QTI_CUSTOM_DIMENSIONS_STRIDE
    case QTI_CUSTOM_DIMENSIONS_STRIDE:
#endif
#ifdef QTI_CUSTOM_DIMENSIONS_HEIGHT
    case QTI_CUSTOM_DIMENSIONS_HEIGHT:
#endif
#ifdef QTI_RGB_DATA_ADDRESS
    case QTI_RGB_DATA_ADDRESS:
#endif
#ifdef QTI_COLORSPACE
    case QTI_COLORSPACE:
#endif
#ifdef QTI_MEM_HANDLE
    case QTI_MEM_HANDLE:
#endif
      return Error::UNSUPPORTED;
    case (int64_t)StandardMetadataType::DATASPACE:
      Dataspace dataspace;
      if (android::gralloc4::decodeDataspace(in, &dataspace)) {
        return Error::UNSUPPORTED;
      }
      dataspaceToColorMetadata(dataspace, &metadata->color);
      break;
    case (int64_t)StandardMetadataType::BLEND_MODE:
      BlendMode mode;
      android::gralloc4::decodeBlendMode(in, &mode);
      metadata->blendMode = (int32_t)mode;
      break;
    case (int64_t)StandardMetadataType::SMPTE2086: {
      std::optional<Smpte2086> mastering_display_values;
      if (android::gralloc4::decodeSmpte2086(in, &mastering_display_values)) {
        return Error::UNSUPPORTED;
      }
      if (mastering_display_values != std::nullopt) {
        metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled = true;

        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][0] =
            static_cast<uint32_t>(mastering_display_values->primaryRed.x * 50000.0f);
        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[0][1] =
            static_cast<uint32_t>(mastering_display_values->primaryRed.y * 50000.0f);

        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][0] =
            static_cast<uint32_t>(mastering_display_values->primaryGreen.x * 50000.0f);
        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[1][1] =
            static_cast<uint32_t>(mastering_display_values->primaryGreen.y * 50000.0f);

        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][0] =
            static_cast<uint32_t>(mastering_display_values->primaryBlue.x * 50000.0f);
        metadata->color.masteringDisplayInfo.primaries.rgbPrimaries[2][1] =
            static_cast<uint32_t>(mastering_display_values->primaryBlue.y * 50000.0f);

        metadata->color.masteringDisplayInfo.primaries.whitePoint[0] =
            static_cast<uint32_t>(mastering_display_values->whitePoint.x * 50000.0f);
        metadata->color.masteringDisplayInfo.primaries.whitePoint[1] =
            static_cast<uint32_t>(mastering_display_values->whitePoint.y * 50000.0f);

        metadata->color.masteringDisplayInfo.maxDisplayLuminance =
            static_cast<uint32_t>(mastering_display_values->maxLuminance);
        metadata->color.masteringDisplayInfo.minDisplayLuminance =
            static_cast<uint32_t>(mastering_display_values->minLuminance * 10000.0f);
      } else {
#ifdef METADATA_V2
        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
            false;
#endif
        metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled = false;
      }
      break;
    }
    case (int64_t)StandardMetadataType::CTA861_3: {
      std::optional<Cta861_3> content_light_level;
      if (android::gralloc4::decodeCta861_3(in, &content_light_level)) {
        return Error::UNSUPPORTED;
      }
      if (content_light_level != std::nullopt) {
        metadata->color.contentLightLevel.lightLevelSEIEnabled = true;
        metadata->color.contentLightLevel.maxContentLightLevel =
            static_cast<uint32_t>(content_light_level->maxContentLightLevel);
        metadata->color.contentLightLevel.minPicAverageLightLevel =
            static_cast<uint32_t>(content_light_level->maxFrameAverageLightLevel * 10000.0f);
      } else {
#ifdef METADATA_V2
        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
            false;
#endif
        metadata->color.contentLightLevel.lightLevelSEIEnabled = false;
      }
      break;
    }
    case (int64_t)StandardMetadataType::SMPTE2094_40: {
      std::optional<std::vector<uint8_t>> dynamic_metadata_payload;
      if (android::gralloc4::decodeSmpte2094_40(in, &dynamic_metadata_payload)) {
        return Error::UNSUPPORTED;
      }
      if (dynamic_metadata_payload != std::nullopt) {
        if (dynamic_metadata_payload->size() > HDR_DYNAMIC_META_DATA_SZ)
          return Error::BAD_VALUE;

        metadata->color.dynamicMetaDataLen = dynamic_metadata_payload->size();
        std::copy(dynamic_metadata_payload->begin(), dynamic_metadata_payload->end(),
                  metadata->color.dynamicMetaDataPayload);
        metadata->color.dynamicMetaDataValid = true;
      } else {
// Reset metadata by passing in std::nullopt
#ifdef METADATA_V2
        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
            false;
#endif
        metadata->color.dynamicMetaDataValid = false;
      }
      break;
    }
    case (int64_t)StandardMetadataType::CROP: {
      std::vector<Rect> in_crop;
      if (android::gralloc4::decodeCrop(in, &in_crop)) {
        return Error::UNSUPPORTED;
      }

      if (in_crop.size() != 1) {
        return Error::UNSUPPORTED;
      }

      metadata->crop.left = in_crop[0].left;
      metadata->crop.top = in_crop[0].top;
      metadata->crop.right = in_crop[0].right;
      metadata->crop.bottom = in_crop[0].bottom;
      break;
    }
    case QTI_VT_TIMESTAMP:
      if (android::gralloc4::decodeUint64(qtigralloc::MetadataType_VTTimestamp, in,
                                      &metadata->vtTimeStamp)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_COLOR_METADATA:
      ColorMetaData color;
      if (qtigralloc::decodeColorMetadata(in, &color) != IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      metadata->color = color;
      break;
    case QTI_PP_PARAM_INTERLACED:
      if (android::gralloc4::decodeInt32(qtigralloc::MetadataType_PPParamInterlaced, in,
                                     &metadata->interlaced)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_VIDEO_PERF_MODE:
      if (android::gralloc4::decodeUint32(qtigralloc::MetadataType_VideoPerfMode, in,
                                      &metadata->isVideoPerfMode)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_GRAPHICS_METADATA:
      if (qtigralloc::decodeGraphicsMetadata(in, &metadata->graphics_metadata) !=
                                       IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_UBWC_CR_STATS_INFO:
      if (qtigralloc::decodeUBWCStats(in, &metadata->ubwcCRStats[0]) != IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_REFRESH_RATE:
      if (android::gralloc4::decodeFloat(qtigralloc::MetadataType_RefreshRate, in,
                                     &metadata->refreshrate)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_MAP_SECURE_BUFFER:
      if (android::gralloc4::decodeInt32(qtigralloc::MetadataType_MapSecureBuffer, in,
                                     &metadata->mapSecureBuffer)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_LINEAR_FORMAT:
      if (android::gralloc4::decodeUint32(qtigralloc::MetadataType_LinearFormat, in,
                                      &metadata->linearFormat)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_SINGLE_BUFFER_MODE:
      if (android::gralloc4::decodeUint32(qtigralloc::MetadataType_SingleBufferMode, in,
                                      &metadata->isSingleBufferMode)) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_CVP_METADATA:
      if (qtigralloc::decodeCVPMetadata(in, &metadata->cvpMetadata) != IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      break;
    case QTI_VIDEO_HISTOGRAM_STATS:
      if (qtigralloc::decodeVideoHistogramMetadata(in, &metadata->video_histogram_stats) !=
                                      IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      break;
#ifdef QTI_VIDEO_TRANSCODE_STATS
    case QTI_VIDEO_TRANSCODE_STATS:
      qtigralloc::decodeVideoTranscodeStatsMetadata(in, &metadata->video_transcode_stats);
      break;
#endif
#ifdef QTI_VIDEO_TS_INFO
    case QTI_VIDEO_TS_INFO:
      if (qtigralloc::decodeVideoTimestampInfo(in, &metadata->videoTsInfo) !=
                                      IMapper_4_0_Error::NONE) {
        return Error::UNSUPPORTED;
      }
      break;
#endif
#ifdef QTI_BUFFER_PERMISSION
    case QTI_BUFFER_PERMISSION: {
      qtigralloc::decodeBufferPermission(in, &metadata->bufferPerm[0]);
      allocator_->SetBufferPermission(handle->fd, &metadata->bufferPerm[0], &metadata->memHandle);
    }
    break;
#endif
#ifdef QTI_TIMED_RENDERING
    case QTI_TIMED_RENDERING:
      android::gralloc4::decodeUint32(qtigralloc::MetadataType_TimedRendering, in,
                                      &metadata->timedRendering);
      break;
#endif
#ifdef QTI_CUSTOM_CONTENT_METADATA
    case QTI_CUSTOM_CONTENT_METADATA:
      if (buf->custom_content_md_region_ptr == nullptr ||
          buf->custom_content_md_size != sizeof(CustomContentMetadata)) {
        return Error::UNSUPPORTED;
      } else {
        if (qtigralloc::decodeCustomContentMetadata(in, buf->custom_content_md_region_ptr) !=
            android::hardware::graphics::mapper::V4_0::Error::NONE) {
          return Error::BAD_VALUE;
        }
      }
      break;
#endif
    default:
      return Error::BAD_VALUE;
  }

#ifdef METADATA_V2
  if (IS_VENDOR_METADATA_TYPE(metadatatype_value)) {
    if (GET_VENDOR_METADATA_STATUS_INDEX(metadatatype_value) < METADATA_SET_SIZE) {
      metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(metadatatype_value)] = true;
    }
  } else {
    if (GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value) < METADATA_SET_SIZE) {
      metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
          true;
    }
  }
#endif

  return Error::NONE;
}

}  //  namespace gralloc
