/*
 * 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 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);
  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
