/*
 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include "QtiMapperExtensions.h"
#include <cutils/properties.h>
#include <cutils/trace.h>
#include <sync/sync.h>
#include "gr_utils.h"
#include <QtiGralloc.h>

namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace mapperextensions {
namespace V1_1 {
namespace implementation {

using gralloc::BufferInfo;
using MetadataType = ::android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;

QtiMapperExtensions::QtiMapperExtensions() {
  buf_mgr_ = BufferManager::GetInstance();
  enable_logs_ = property_get_bool(ENABLE_LOGS_PROP, 0);
}

Return<void> QtiMapperExtensions::getMapSecureBufferFlag(void *buffer,
                                                         getMapSecureBufferFlag_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  int map_secure_buffer = 0;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = static_cast<Error>(
        gralloc::GetMetaDataValue(hnd, QTI_MAP_SECURE_BUFFER, &map_secure_buffer));
    if (err != Error::NONE) {
      map_secure_buffer = 0;
    }
  }
  hidl_cb(err, map_secure_buffer != 0);
  return Void();
}

Return<void> QtiMapperExtensions::getInterlacedFlag(void *buffer, getInterlacedFlag_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  int interlaced_flag = 0;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    auto ret = static_cast<Error>(
        gralloc::GetMetaDataValue(hnd, QTI_PP_PARAM_INTERLACED, &interlaced_flag));
    if (ret != Error::NONE) {
      interlaced_flag = 0;
      ALOGW(
          "%s: getMetaData returned %d, defaulting to "
          "interlaced_flag = %d",
          __FUNCTION__, ret, interlaced_flag);
    }
  }
  hidl_cb(err, interlaced_flag != 0);
  return Void();
}

Return<void> QtiMapperExtensions::getCustomDimensions(void *buffer,
                                                      getCustomDimensions_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  int stride = 0;
  int height = 0;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    stride = hnd->width;
    height = hnd->height;
    int ret = gralloc::GetCustomDimensions(hnd, &stride, &height);
    if (ret) {
      ALOGW(
          "%s: Error during GetCustomDimensions API call. "
          "stride: %d, height: %d",
          __FUNCTION__, stride, height);
      err = Error::BAD_BUFFER;
    } else {
      err = Error::NONE;
    }
  }
  hidl_cb(err, stride, height);
  return Void();
}

Return<void> QtiMapperExtensions::getRgbDataAddress(void *buffer, getRgbDataAddress_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  void *rgb_data = nullptr;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    if (gralloc::GetRgbDataAddress(hnd, &rgb_data) == 0) {
      err = Error::NONE;
    }
  }
  hidl_cb(err, rgb_data);
  return Void();
}

Return<void> QtiMapperExtensions::calculateBufferAttributes(int32_t width, int32_t height,
                                                            int32_t format, uint64_t usage,
                                                            calculateBufferAttributes_cb hidl_cb) {
  unsigned int alignedw, alignedh;
  auto err = Error::NONE;
  BufferInfo info(width, height, format, usage);
  int ret = gralloc::GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
  if (ret) {
    err = Error::BAD_BUFFER;
  }
  bool ubwc_enabled = gralloc::IsUBwcEnabled(format, usage);
  hidl_cb(err, alignedw, alignedh, ubwc_enabled);
  return Void();
}

Return<void> QtiMapperExtensions::getCustomFormatFlags(int32_t format, uint64_t usage,
                                                       getCustomFormatFlags_cb hidl_cb) {
  uint64_t priv_flags = 0;
  auto err = Error::NONE;
  int32_t custom_format = format;
  if (gralloc::GetCustomFormatFlags(format, usage, &custom_format, &priv_flags) != 0) {
    err = Error::UNSUPPORTED;
  }
  hidl_cb(err, custom_format, priv_flags);
  return Void();
}

Return<void> QtiMapperExtensions::getColorSpace(void *buffer, getColorSpace_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  int color_space = 0;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    gralloc::GetColorSpaceFromMetadata(hnd, &color_space);
    err = Error::NONE;
  }
  hidl_cb(err, color_space);
  return Void();
}

Return<void> QtiMapperExtensions::getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  hidl_vec<YCbCrLayout> layout;
  layout.resize(2);
  android_ycbcr yuv_plane_info[2];
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) == 0) {
      err = 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);
      }
    }
  }
  hidl_cb(err, layout);
  return Void();
}

Return<Error> QtiMapperExtensions::setSingleBufferMode(void *buffer, bool enable) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = static_cast<Error>(gralloc::SetMetaData(hnd, QTI_SINGLE_BUFFER_MODE, &enable));
    err = (err != Error::NONE) ? Error::UNSUPPORTED : err;
  }
  return err;
}

Return<void> QtiMapperExtensions::getFd(void *buffer, getFd_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int fd = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    fd = hnd->fd;
  }
  hidl_cb(err, fd);
  return Void();
}

Return<void> QtiMapperExtensions::getWidth(void *buffer, getWidth_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int width = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    width = hnd->width;
  }
  hidl_cb(err, width);
  return Void();
}

Return<void> QtiMapperExtensions::getHeight(void *buffer, getHeight_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int height = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    height = hnd->height;
  }
  hidl_cb(err, height);
  return Void();
}

Return<void> QtiMapperExtensions::getFormat(void *buffer, getFormat_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int format = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    format = hnd->format;
  }
  hidl_cb(err, format);
  return Void();
}

Return<void> QtiMapperExtensions::getPrivateFlags(void *buffer, getPrivateFlags_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int flags = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    flags = hnd->flags;
  }
  hidl_cb(err, flags);
  return Void();
}

Return<void> QtiMapperExtensions::getUnalignedWidth(void *buffer, getUnalignedWidth_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int unaligned_width = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    unaligned_width = hnd->unaligned_width;
  }
  hidl_cb(err, unaligned_width);
  return Void();
}

Return<void> QtiMapperExtensions::getUnalignedHeight(void *buffer, getUnalignedHeight_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  int unaligned_height = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    unaligned_height = hnd->unaligned_height;
  }
  hidl_cb(err, unaligned_height);
  return Void();
}

Return<void> QtiMapperExtensions::getLayerCount(void *buffer, getLayerCount_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  unsigned int layer_count = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    layer_count = hnd->layer_count;
  }
  hidl_cb(err, layer_count);
  return Void();
}

Return<void> QtiMapperExtensions::getId(void *buffer, getId_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  uint64_t id = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    id = hnd->id;
  }
  hidl_cb(err, id);
  return Void();
}

Return<void> QtiMapperExtensions::getUsageFlags(void *buffer, getUsageFlags_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  uint64_t usage = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    usage = hnd->usage;
  }
  hidl_cb(err, usage);
  return Void();
}

Return<void> QtiMapperExtensions::getSize(void *buffer, getSize_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  unsigned int size = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    size = hnd->size;
  }
  hidl_cb(err, size);
  return Void();
}

Return<void> QtiMapperExtensions::getOffset(void *buffer, getOffset_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  unsigned int offset = 0;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = Error::NONE;
    offset = hnd->offset;
  }
  hidl_cb(err, offset);
  return Void();
}

Return<void> QtiMapperExtensions::getSurfaceMetadata(void *buffer, getSurfaceMetadata_cb hidl_cb) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  GraphicsMetadata surface_metadata;
  if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = static_cast<Error>(
        gralloc::GetMetaDataValue(hnd, QTI_GRAPHICS_METADATA, &surface_metadata));
  }
  if (err != Error::NONE) {
    hidl_cb(err, nullptr);
  } else {
    hidl_cb(err, &surface_metadata);
  }
  return Void();
}

// It will return size for single layer only i.e. layer count is always 1.
Return<void> QtiMapperExtensions::getFormatLayout(int32_t format, uint64_t usage, int32_t flags,
                                                  int32_t width, int32_t height,
                                                  getFormatLayout_cb hidl_cb) {
  ALOGD_IF(enable_logs_, "%s: Input parameters - wxh: %dx%d usage: 0x%" PRIu64 " format: %d",
           __FUNCTION__, width, height, usage, format);
  auto err = Error::NONE;
  hidl_vec<PlaneLayout> plane_info;
  unsigned int alignedw = 0, alignedh = 0;
  int plane_count = 0;
  uint32_t size = 0;
  int custom_format = gralloc::GetImplDefinedFormat(usage, format);
  BufferInfo info(width, height, custom_format, usage);
  int ret = gralloc::GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
  if (ret) {
    err = Error::BAD_BUFFER;
    hidl_cb(err, size, plane_info);
    return Void();
  }
  gralloc::PlaneLayoutInfo plane_layout[8] = {};
  ALOGD_IF(enable_logs_, "%s: Aligned width and height - wxh: %ux%u custom_format = %d",
           __FUNCTION__, alignedw, alignedh, custom_format);
  if (gralloc::IsYuvFormat(custom_format)) {
    // flags here only refers to layout (interlaced) flags, not private or buffer usage flags
    gralloc::GetYUVPlaneInfo(info, custom_format, alignedw, alignedh, flags, &plane_count,
                             plane_layout);
  } else if (gralloc::IsUncompressedRGBFormat(custom_format) ||
             gralloc::IsCompressedRGBFormat(custom_format)) {
    gralloc::GetRGBPlaneInfo(info, custom_format, alignedw, alignedh, flags, &plane_count,
                             plane_layout);
  } else {
    err = Error::BAD_BUFFER;
    hidl_cb(err, size, plane_info);
    return Void();
  }
  ALOGD_IF(enable_logs_, "%s: Number of plane - %d, custom_format - %d", __FUNCTION__, plane_count,
           custom_format);
  plane_info.resize(plane_count);
  for (int i = 0; i < plane_count; i++) {
    plane_info[i].component = plane_layout[i].component;
    plane_info[i].h_subsampling = plane_layout[i].h_subsampling;
    plane_info[i].v_subsampling = plane_layout[i].v_subsampling;
    plane_info[i].offset = plane_layout[i].offset;
    plane_info[i].pixel_increment = plane_layout[i].step;
    plane_info[i].stride = plane_layout[i].stride;
    plane_info[i].stride_bytes = plane_layout[i].stride_bytes;
    plane_info[i].scanlines = plane_layout[i].scanlines;
    plane_info[i].size = plane_layout[i].size;
    ALOGD_IF(enable_logs_, "%s: plane info: component - %d", __FUNCTION__, plane_info[i].component);
    ALOGD_IF(enable_logs_,
             "h_subsampling - %u, v_subsampling - %u, offset - %u, pixel_increment - %d",
             plane_info[i].h_subsampling, plane_info[i].v_subsampling, plane_info[i].offset,
             plane_info[i].pixel_increment);
    ALOGD_IF(enable_logs_, "stride_pixel - %d, stride_bytes - %d, scanlines - %d, size - %u",
             plane_info[i].stride, plane_info[i].stride_bytes, plane_info[i].scanlines,
             plane_info[i].size);
  }
  hidl_cb(err, size, plane_info);
  return Void();
}

Return<Error> QtiMapperExtensions::getSurfaceMetadata_V1(void *buffer, void *metadata) {
  auto err = Error::BAD_BUFFER;
  auto hnd = static_cast<private_handle_t *>(buffer);
  if (metadata != nullptr && buffer != nullptr && private_handle_t::validate(hnd) == 0) {
    err = static_cast<Error>(gralloc::GetMetaDataValue(hnd, QTI_GRAPHICS_METADATA, metadata));
    err = (err != Error::NONE) ? Error::UNSUPPORTED : err;
  } else {
    ALOGE("%s: buffer pointer: %p, metadata pointer: %p ", __FUNCTION__, buffer, metadata);
  }
  return err;
}

Return<Error> QtiMapperExtensions::copyMetaData(void *src, void *dst) {
  auto error = Error::BAD_BUFFER;
  auto src_hnd = static_cast<private_handle_t *>(src);
  auto dst_hnd = static_cast<private_handle_t *>(dst);
  if (src != nullptr && dst != nullptr && private_handle_t::validate(src_hnd) == 0 &&
      private_handle_t::validate(dst_hnd) == 0) {
    if (static_cast<IMapperExtensions_1_0_Error>(buf_mgr_->IsBufferImported(src_hnd)) ==
            Error::NONE &&
        static_cast<IMapperExtensions_1_0_Error>(buf_mgr_->IsBufferImported(dst_hnd)) ==
            Error::NONE) {
      MetaData_t *src_data = reinterpret_cast<MetaData_t *>(src_hnd->base_metadata);
      MetaData_t *dst_data = reinterpret_cast<MetaData_t *>(dst_hnd->base_metadata);
      *dst_data = *src_data;
      error = Error::NONE;
    }
  } else {
    ALOGE("%s: Copy Failed - src buffer: %p, dst buffer: %p", __FUNCTION__, src, dst);
  }
  return error;
}

Return<Error> QtiMapperExtensions::setMetadataBlob(const hidl_vec<uint8_t> &src, void *dst) {
  auto error = Error::BAD_BUFFER;
  if (src.data() == nullptr) {
    return error;
  }
  auto dst_hnd = static_cast<private_handle_t *>(dst);
  if (dst != nullptr && private_handle_t::validate(dst_hnd) == 0) {
    if (static_cast<IMapperExtensions_1_0_Error>(buf_mgr_->IsBufferImported(dst_hnd)) ==
        Error::NONE) {
      const MetaData_t *src_data = reinterpret_cast<const MetaData_t *>(src.data());
      MetaData_t *dst_data = reinterpret_cast<MetaData_t *>(dst_hnd->base_metadata);
      *dst_data = *src_data;
      error = Error::NONE;
    }
  } else {
    ALOGE("%s: Copy Failed - src buffer: %p, dst pointer: %p", __FUNCTION__, src.data(), dst);
  }
  return error;
}

Return<void> QtiMapperExtensions::getMetadataBlob(void *src, getMetadataBlob_cb _hidl_cb) {
  auto error = Error::BAD_BUFFER;
  hidl_vec<uint8_t> out;
  auto src_hnd = static_cast<private_handle_t *>(src);
  out.resize(sizeof(MetaData_t));

  if (src != nullptr && private_handle_t::validate(src_hnd) == 0) {
    if (static_cast<IMapperExtensions_1_0_Error>(buf_mgr_->IsBufferImported(src_hnd)) ==
        Error::NONE) {
      MetaData_t *src_data = reinterpret_cast<MetaData_t *>(src_hnd->base_metadata);
      MetaData_t *dst_data = reinterpret_cast<MetaData_t *>(out.data());
      memcpy(dst_data, src_data, sizeof(MetaData_t));
      error = Error::NONE;
      _hidl_cb(error, out);
    }
  } else {
    ALOGE("%s: Get Failed - src buffer: %p", __FUNCTION__, src);
  }
  _hidl_cb(error, out);
  return Void();
}

Return<Error> QtiMapperExtensions::getMetaDataValue(void *src, const MetadataType &type, void *in) {
  auto error = Error::BAD_BUFFER;
  if (src != nullptr) {
    if (type.name != GRALLOC4_STANDARD_METADATA_TYPE && type.name != qtigralloc::VENDOR_QTI) {
      return Error::UNSUPPORTED;
    }
    error = static_cast<IMapperExtensions_1_0_Error>(
        buf_mgr_->GetMetadataValue(static_cast<private_handle_t *>(src), type.value, in));
  }
  return error;
}

}  // namespace implementation
}  // namespace V1_1
}  // namespace mapperextensions
}  // namespace display
}  // namespace hardware
}  // namespace qti
}  // namespace vendor
