/*
 * Copyright (C) 2020 Arm Limited.
 *
 * Copyright 2016 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.
 */

#include "MapperMetadata.h"
#include "SharedMetadata.h"
#include "core/format_info.h"
#include "core/mali_gralloc_bufferallocation.h"
#include "mali_gralloc_buffer.h"
#include "mali_gralloc_log.h"
#include "drmutils.h"
#include "gralloctypes/Gralloc4.h"

#include "exynos_format.h"
#include "mali_gralloc_formats.h"

#include <pixel-gralloc/metadata.h>
#include <pixel-gralloc/utils.h>

#include <vector>

namespace arm
{
namespace mapper
{
namespace common
{

using aidl::android::hardware::graphics::common::PlaneLayout;
using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
using aidl::android::hardware::graphics::common::Rect;
using aidl::android::hardware::graphics::common::Dataspace;
using aidl::android::hardware::graphics::common::BlendMode;
using aidl::android::hardware::graphics::common::StandardMetadataType;
using aidl::android::hardware::graphics::common::XyColor;
using aidl::android::hardware::graphics::common::Smpte2086;
using aidl::android::hardware::graphics::common::Cta861_3;
#if 0
using aidl::arm::graphics::ArmMetadataType;
#endif

bool isStandardMetadataType(const MetadataType &metadataType) {
	return !std::strncmp(metadataType.name.c_str(),
			     GRALLOC4_STANDARD_METADATA_TYPE,
			     metadataType.name.size());
}

int get_num_planes(const private_handle_t *hnd)
{
	if (is_exynos_format(hnd->get_alloc_format()))
	{
		switch (hnd->get_alloc_format())
		{
			case HAL_PIXEL_FORMAT_YCrCb_420_SP:
			case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
				return 3;

			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
			case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
			case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
			case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
				return 2;
		}
	}

	return hnd->is_multi_plane() ? (hnd->plane_info[2].offset == 0 ? 2 : 3) : 1;
}

static std::vector<std::vector<PlaneLayoutComponent>> plane_layout_components_from_handle(const private_handle_t *hnd)
{
	/* Re-define the component constants to make the table easier to read. */
	const ExtendableType R = android::gralloc4::PlaneLayoutComponentType_R;
	const ExtendableType G = android::gralloc4::PlaneLayoutComponentType_G;
	const ExtendableType B = android::gralloc4::PlaneLayoutComponentType_B;
	const ExtendableType A = android::gralloc4::PlaneLayoutComponentType_A;
	const ExtendableType CB = android::gralloc4::PlaneLayoutComponentType_CB;
	const ExtendableType CR = android::gralloc4::PlaneLayoutComponentType_CR;
	const ExtendableType Y = android::gralloc4::PlaneLayoutComponentType_Y;
	const ExtendableType RAW = android::gralloc4::PlaneLayoutComponentType_RAW;

	struct table_entry
	{
		uint32_t drm_fourcc;
		std::vector<std::vector<PlaneLayoutComponent>> components;
	};

	/* clang-format off */
	static table_entry table[] = {
		/* 16 bit RGB(A) */
		{
			.drm_fourcc = DRM_FORMAT_RGB565,
			.components = { { { B, 0, 5 }, { G, 5, 6 }, { R, 11, 5 } } }
		},
		{
			.drm_fourcc = DRM_FORMAT_BGR565,
			.components = { { { R, 0, 5 }, { G, 5, 6 }, { B, 11, 5 } } }
		},
		/* 24 bit RGB(A) */
		{
			.drm_fourcc = DRM_FORMAT_BGR888,
			.components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } }
		},
		/* 32 bit RGB(A) */
		{
			.drm_fourcc = DRM_FORMAT_ARGB8888,
			.components = { { { B, 0, 8 }, { G, 8, 8 }, { R, 16, 8 }, { A, 24, 8 } } }
		},
		{
			.drm_fourcc = DRM_FORMAT_ABGR8888,
			.components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 }, { A, 24, 8 } } }
		},
		{
			.drm_fourcc = DRM_FORMAT_XBGR8888,
			.components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } }
		},
		{
			.drm_fourcc = DRM_FORMAT_ABGR2101010,
			.components = { { { R, 0, 10 }, { G, 10, 10 }, { B, 20, 10 }, { A, 30, 2 } } }
		},
		/* 64 bit RGB(A) */
		{
			.drm_fourcc = DRM_FORMAT_ABGR16161616F,
			.components = { { { R, 0, 16 }, { G, 16, 16 }, { B, 32, 16 }, { A, 48, 16 } } }
		},
		/* Single plane 8 bit YUV 4:2:2 */
		{
			.drm_fourcc = DRM_FORMAT_YUYV,
			.components = { { { Y, 0, 8 }, { CB, 8, 8 }, { Y, 16, 8 }, { CR, 24, 8 } } }
		},
		/* Single plane 10 bit YUV 4:4:4 */
		{
			.drm_fourcc = DRM_FORMAT_Y410,
			.components = { { { CB, 0, 10 }, { Y, 10, 10 }, { CR, 20, 10 }, { A, 30, 2 } } }
		},
		/* Single plane 10 bit YUV 4:2:2 */
		{
			.drm_fourcc = DRM_FORMAT_Y210,
			.components = { { { Y, 6, 10 }, { CB, 22, 10 }, { Y, 38, 10 }, { CR, 54, 10 } } }
		},
		/* Single plane 10 bit YUV 4:2:0 */
		{
			.drm_fourcc = DRM_FORMAT_Y0L2,
			.components = { {
				{ Y, 0, 10 }, { CB, 10, 10 }, { Y, 20, 10 }, { A, 30, 1 }, { A, 31, 1 },
				{ Y, 32, 10 }, { CR, 42, 10 }, { Y, 52, 10 }, { A, 62, 1 }, { A, 63, 1 }
			} }
		},
		/* Semi-planar 8 bit YUV 4:2:2 */
		{
			.drm_fourcc = DRM_FORMAT_NV16,
			.components = {
				{ { Y, 0, 8 } },
				{ { CB, 0, 8 }, { CR, 8, 8 } }
			}
		},
		/* Semi-planar 8 bit YUV 4:2:0 */
		{
			.drm_fourcc = DRM_FORMAT_NV12,
			.components = {
				{ { Y, 0, 8 } },
				{ { CB, 0, 8 }, { CR, 8, 8 } }
			}
		},
		{
			.drm_fourcc = DRM_FORMAT_NV21,
			.components = {
				{ { Y, 0, 8 } },
				{ { CR, 0, 8 }, { CB, 8, 8 } }
			}
		},
		/* Semi-planar 10 bit YUV 4:2:2 */
		{
			.drm_fourcc = DRM_FORMAT_P210,
			.components = {
				{ { Y, 6, 10 } },
				{ { CB, 6, 10 }, { CB, 22, 10 } }
			}
		},
		/* Semi-planar 10 bit YUV 4:2:0 */
		{
			.drm_fourcc = DRM_FORMAT_P010,
			.components = {
				{ { Y, 6, 10 } },
				{ { CB, 6, 10 }, { CR, 22, 10 } }
			}
		},
		/* Planar 8 bit YUV 4:2:0 */
		{
			.drm_fourcc = DRM_FORMAT_YVU420,
			.components = {
				{ { Y, 0, 8 } },
				{ { CR, 0, 8 } },
				{ { CB, 0, 8 } }
			}
		},
		/* Planar 8 bit YUV 4:4:4 */
		{
			.drm_fourcc = DRM_FORMAT_YUV444,
			.components = {
				{ { Y, 0, 8 } },
				{ { CB, 0, 8 } },
				{ { CR, 0, 8 } }
			}
		},

		/* AFBC Only FourCC */
		{.drm_fourcc = DRM_FORMAT_YUV420_8BIT, .components = { {} } },
		{.drm_fourcc = DRM_FORMAT_YUV420_10BIT, .components = { {} } },

		/* Google specific formats */
		{
			.drm_fourcc = DRM_FORMAT_R8,
			.components = {
				{ { R, 0, 8 } }
			}
		},
		{
			.drm_fourcc = DRM_FORMAT_RG88,
			.components = {
				{ { R, 0, 8 }, { G, 8, 8 } }
			}
		},
	};
	/* clang-format on */

	const uint32_t drm_fourcc = drm_fourcc_from_handle(hnd);
	if (drm_fourcc != DRM_FORMAT_INVALID)
	{
		for (const auto& entry : table)
		{
			if (entry.drm_fourcc == drm_fourcc)
			{
				return entry.components;
			}
		}
	}

	switch (hnd->get_alloc_format())
	{
		case HAL_PIXEL_FORMAT_RAW10:
			return {{{RAW, 0, -1}}};
		case HAL_PIXEL_FORMAT_RAW12:
			return {{{RAW, 0, -1}}};
		case HAL_PIXEL_FORMAT_BLOB:
			break;
		default:
			MALI_GRALLOC_LOGW("Could not find component description for Format(%#x) FourCC value(%#x)",
				hnd->get_alloc_format(), drm_fourcc);
	}

	return std::vector<std::vector<PlaneLayoutComponent>>(0);
}

android::status_t get_plane_layouts(const private_handle_t *handle, std::vector<PlaneLayout> *layouts)
{
	const int num_planes = get_num_planes(handle);
	uint32_t base_format = handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
	int32_t format_index = get_format_index(base_format);
	if (format_index < 0)
	{
		MALI_GRALLOC_LOGE("Negative format index in get_plane_layouts");
		return android::BAD_VALUE;
	}
	const format_info_t format_info = formats[format_index];
	layouts->reserve(num_planes);

	if (is_exynos_format(handle->get_alloc_format()))
	{
		std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle);
		for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
		{
			int64_t plane_size = handle->plane_info[plane_index].size;
			int64_t sample_increment_in_bits = format_info.bpp[plane_index];
			int64_t offset = handle->plane_info[plane_index].offset;

			static bool warn_multifd = true;
			if (warn_multifd) {
				uint8_t fd_count = get_exynos_fd_count(base_format);
				if (fd_count != 1) {
					warn_multifd = false;
					MALI_GRALLOC_LOGW("Offsets in plane layouts of multi-fd format (%s %" PRIu64
							") are not reliable. This can lead to image corruption.",
							format_name(base_format), handle->alloc_format);
				}
			}

			PlaneLayout layout = {.offsetInBytes = offset,
				                  .sampleIncrementInBits = sample_increment_in_bits,
				                  .strideInBytes = static_cast<int64_t>(handle->plane_info[plane_index].byte_stride),
				                  .widthInSamples = static_cast<int64_t>(handle->plane_info[plane_index].alloc_width),
				                  .heightInSamples = static_cast<int64_t>(handle->plane_info[plane_index].alloc_height),
				                  .totalSizeInBytes = plane_size,
				                  .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub),
				                  .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub),
				                  .components = components.size() > plane_index ? components[plane_index] :
				                                                                  std::vector<PlaneLayoutComponent>(0) };
			layouts->push_back(layout);
		}
	}
	else
	{
		std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle);
		for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
		{
			int64_t plane_size;
			if (plane_index < num_planes - 1)
			{
				plane_size = handle->plane_info[plane_index + 1].offset;
			}
			else
			{
				int64_t layer_size = handle->alloc_sizes[0] / handle->layer_count;
				plane_size = layer_size - handle->plane_info[plane_index].offset;
			}

			if (handle->fd_count > 1 && handle->plane_info[plane_index].fd_idx == plane_index)
			{
				plane_size = handle->plane_info[plane_index].size;
			}

			int64_t sample_increment_in_bits = 0;
			if (handle->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
			{
				sample_increment_in_bits = format_info.bpp_afbc[plane_index];
			}
			else
			{
				sample_increment_in_bits = format_info.bpp[plane_index];
			}

			switch (handle->get_alloc_format())
			{
				case HAL_PIXEL_FORMAT_RAW10:
				case HAL_PIXEL_FORMAT_RAW12:
					sample_increment_in_bits = 0;
					break;
				default:
					break;
			}

			PlaneLayout layout = {.offsetInBytes = handle->plane_info[plane_index].offset,
				                  .sampleIncrementInBits = sample_increment_in_bits,
				                  .strideInBytes = static_cast<int64_t>(handle->plane_info[plane_index].byte_stride),
				                  .widthInSamples = static_cast<int64_t>(handle->plane_info[plane_index].alloc_width),
				                  .heightInSamples = static_cast<int64_t>(handle->plane_info[plane_index].alloc_height),
				                  .totalSizeInBytes = plane_size,
				                  .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub),
				                  .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub),
				                  .components = components.size() > plane_index ? components[plane_index] :
				                                                                  std::vector<PlaneLayoutComponent>(0) };
			layouts->push_back(layout);
		}
	}

	return android::OK;
}

static frameworks_vec<uint8_t> encodePointer(void* ptr) {
	constexpr uint8_t kPtrSize = sizeof(void*);

	frameworks_vec<uint8_t> output(kPtrSize);
	std::memcpy(output.data(), &ptr, kPtrSize);

	return output;
}

Error get_metadata(const private_handle_t *handle, const MetadataType &metadataType, std::vector<uint8_t> &outVec)
{
	android::status_t err = android::OK;
	frameworks_vec<uint8_t> vec;

	if (isStandardMetadataType(metadataType))
	{
		switch (static_cast<StandardMetadataType>(metadataType.value))
		{
		case StandardMetadataType::BUFFER_ID:
			err = android::gralloc4::encodeBufferId(handle->backing_store_id, &vec);
			break;
		case StandardMetadataType::NAME:
		{
			std::string name;
			get_name(handle, &name);
			err = android::gralloc4::encodeName(name, &vec);
			break;
		}
		case StandardMetadataType::WIDTH:
			err = android::gralloc4::encodeWidth(handle->width, &vec);
			break;
		case StandardMetadataType::HEIGHT:
			err = android::gralloc4::encodeHeight(handle->height, &vec);
			break;
		case StandardMetadataType::LAYER_COUNT:
			err = android::gralloc4::encodeLayerCount(handle->layer_count, &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
			err = android::gralloc4::encodePixelFormatRequested(static_cast<hidl::PixelFormat>(handle->req_format), &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_FOURCC:
			err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(handle), &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
			err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(handle), &vec);
			break;
		case StandardMetadataType::USAGE:
			err = android::gralloc4::encodeUsage(handle->consumer_usage | handle->producer_usage, &vec);
			break;
		case StandardMetadataType::ALLOCATION_SIZE:
		{
			uint64_t total_size = 0;
			for (int fidx = 0; fidx < handle->fd_count; fidx++)
			{
				total_size += handle->alloc_sizes[fidx];
			}
			err = android::gralloc4::encodeAllocationSize(total_size, &vec);
			break;
		}
		case StandardMetadataType::PROTECTED_CONTENT:
		{
			/* This is set to 1 if the buffer has protected content. */
			const int is_protected =
			    (((handle->consumer_usage | handle->producer_usage) & static_cast<uint64_t>(BufferUsage::PROTECTED)) == 0) ? 0 : 1;
			err = android::gralloc4::encodeProtectedContent(is_protected, &vec);
			break;
		}
		case StandardMetadataType::COMPRESSION:
		{
			ExtendableType compression;
			if (handle->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
			{
				compression = Compression_AFBC;
			}
			else
			{
				compression = android::gralloc4::Compression_None;
			}
			err = android::gralloc4::encodeCompression(compression, &vec);
			break;
		}
		case StandardMetadataType::INTERLACED:
			err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec);
			break;
		case StandardMetadataType::CHROMA_SITING:
		{
			int format_index = get_format_index(handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
			if (format_index < 0)
			{
				err = android::BAD_VALUE;
				break;
			}
			ExtendableType siting = android::gralloc4::ChromaSiting_None;
			if (formats[format_index].is_yuv)
			{
				siting = android::gralloc4::ChromaSiting_Unknown;
			}
			err = android::gralloc4::encodeChromaSiting(siting, &vec);
			break;
		}
		case StandardMetadataType::PLANE_LAYOUTS:
		{
			std::vector<PlaneLayout> layouts;
			err = get_plane_layouts(handle, &layouts);
			if (!err)
			{
				err = android::gralloc4::encodePlaneLayouts(layouts, &vec);
			}
			break;
		}
		case StandardMetadataType::DATASPACE:
		{
			std::optional<Dataspace> dataspace;
			get_dataspace(handle, &dataspace);
			err = android::gralloc4::encodeDataspace(dataspace.value_or(Dataspace::UNKNOWN), &vec);
			break;
		}
		case StandardMetadataType::BLEND_MODE:
		{
			std::optional<BlendMode> blend_mode;
			get_blend_mode(handle, &blend_mode);
			err = android::gralloc4::encodeBlendMode(blend_mode.value_or(BlendMode::INVALID), &vec);
			break;
		}
		case StandardMetadataType::CROP:
		{
			const int num_planes = get_num_planes(handle);
			std::vector<Rect> crops(num_planes);
			for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
			{
				/* Set the default crop rectangle. Android mandates that it must fit [0, 0, widthInSamples, heightInSamples]
				 * We always require using the requested width and height for the crop rectangle size.
				 * For planes > 0 the size might need to be scaled, but since we only use plane[0] for crop set it to the
				 * Android default of [0, 0, widthInSamples, heightInSamples] for other planes.
				 */
				Rect rect = {.top = 0,
				             .left = 0,
				             .right = static_cast<int32_t>(handle->plane_info[plane_index].alloc_width),
				             .bottom = static_cast<int32_t>(handle->plane_info[plane_index].alloc_height) };
				if (plane_index == 0)
				{
					std::optional<Rect> crop_rect;
					get_crop_rect(handle, &crop_rect);
					if (crop_rect.has_value())
					{
						rect = crop_rect.value();
					}
					else
					{
						rect = {.top = 0, .left = 0, .right = handle->width, .bottom = handle->height };
					}
				}
				crops[plane_index] = rect;
			}
			err = android::gralloc4::encodeCrop(crops, &vec);
			break;
		}
		case StandardMetadataType::SMPTE2086:
		{
			std::optional<Smpte2086> smpte2086;
			get_smpte2086(handle, &smpte2086);
			err = android::gralloc4::encodeSmpte2086(smpte2086, &vec);
			break;
		}
		case StandardMetadataType::CTA861_3:
		{
			std::optional<Cta861_3> cta861_3;
			get_cta861_3(handle, &cta861_3);
			err = android::gralloc4::encodeCta861_3(cta861_3, &vec);
			break;
		}
		case StandardMetadataType::SMPTE2094_40:
		{
			std::optional<std::vector<uint8_t>> smpte2094_40;
			get_smpte2094_40(handle, &smpte2094_40);
			err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec);
			break;
		}
		case StandardMetadataType::INVALID:
		default:
			err = android::BAD_VALUE;
		}
	}
	else if (metadataType.name == ::pixel::graphics::kPixelMetadataTypeName) {
		switch (static_cast<::pixel::graphics::MetadataType>(metadataType.value)) {
			case ::pixel::graphics::MetadataType::VIDEO_HDR:
				vec = ::pixel::graphics::utils::encode(get_video_hdr(handle));
				break;
			case ::pixel::graphics::MetadataType::VIDEO_ROI:
			{
				auto roi = get_video_roiinfo(handle);
				if (roi == nullptr) {
					err = android::BAD_VALUE;
				} else {
					vec = ::pixel::graphics::utils::encode(roi);
				}
				break;
			}
			case ::pixel::graphics::MetadataType::PLANE_DMA_BUFS:
			{
				std::vector<int> plane_fds(MAX_BUFFER_FDS, -1);
				for (int i = 0; i < get_num_planes(handle); i++) {
					plane_fds[i] = handle->fds[handle->plane_info[i].fd_idx];
				}
				vec = ::pixel::graphics::utils::encode(plane_fds);
				break;
			}
			default:
				err = android::BAD_VALUE;
		}
	}
	else
	{
		err = android::BAD_VALUE;
	}

	outVec = std::vector<uint8_t>(vec);
	return ((err) ? Error::UNSUPPORTED : Error::NONE);
}

Error set_metadata(const private_handle_t *handle, const MetadataType &metadataType, const frameworks_vec<uint8_t> &metadata)
{
	if (isStandardMetadataType(metadataType))
	{
		android::status_t err = android::OK;
		switch (static_cast<StandardMetadataType>(metadataType.value))
		{
		case StandardMetadataType::DATASPACE:
		{
			Dataspace dataspace;
			err = android::gralloc4::decodeDataspace(metadata, &dataspace);
			if (!err)
			{
				set_dataspace(handle, dataspace);
			}
			break;
		}
		case StandardMetadataType::BLEND_MODE:
		{
			BlendMode blend_mode;
			err = android::gralloc4::decodeBlendMode(metadata, &blend_mode);
			if (!err)
			{
				set_blend_mode(handle, blend_mode);
			}
			break;
		}
		case StandardMetadataType::SMPTE2086:
		{
			std::optional<Smpte2086> smpte2086;
			err = android::gralloc4::decodeSmpte2086(metadata, &smpte2086);
			if (!err)
			{
				err = set_smpte2086(handle, smpte2086);
			}
			break;
		}
		case StandardMetadataType::CTA861_3:
		{
			std::optional<Cta861_3> cta861_3;
			err = android::gralloc4::decodeCta861_3(metadata, &cta861_3);
			if (!err)
			{
				err = set_cta861_3(handle, cta861_3);
			}
			break;
		}
		case StandardMetadataType::SMPTE2094_40:
		{
			std::optional<std::vector<uint8_t>> smpte2094_40;
			err = android::gralloc4::decodeSmpte2094_40(metadata, &smpte2094_40);
			if (!err)
			{
				err = set_smpte2094_40(handle, smpte2094_40);
			}
			break;
		}
		case StandardMetadataType::CROP:
		{
			std::vector<Rect> crops;
			err = android::gralloc4::decodeCrop(metadata, &crops);
			if (!err)
			{
				err = set_crop_rect(handle, crops[0]);
			}
			break;
		}
		/* The following meta data types cannot be changed after allocation. */
		case StandardMetadataType::BUFFER_ID:
		case StandardMetadataType::NAME:
		case StandardMetadataType::WIDTH:
		case StandardMetadataType::HEIGHT:
		case StandardMetadataType::LAYER_COUNT:
		case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
		case StandardMetadataType::USAGE:
			return Error::BAD_VALUE;
		/* Changing other metadata types is unsupported. */
		case StandardMetadataType::PLANE_LAYOUTS:
		case StandardMetadataType::PIXEL_FORMAT_FOURCC:
		case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
		case StandardMetadataType::ALLOCATION_SIZE:
		case StandardMetadataType::PROTECTED_CONTENT:
		case StandardMetadataType::COMPRESSION:
		case StandardMetadataType::INTERLACED:
		case StandardMetadataType::CHROMA_SITING:
		case StandardMetadataType::INVALID:
		default:
			return Error::UNSUPPORTED;
		}
		return ((err) ? Error::UNSUPPORTED : Error::NONE);
	}
	else
	{
		/* None of the vendor types support set. */
		return Error::UNSUPPORTED;
	}
}

#ifdef GRALLOC_MAPPER_4
Error getFromBufferDescriptorInfo(IMapper::BufferDescriptorInfo const &description,
                                 MetadataType const &metadataType, std::vector<uint8_t> &outVec)
{
	/* This will hold the metadata that is returned. */
	frameworks_vec<uint8_t> vec;

	buffer_descriptor_t descriptor;
	descriptor.width = description.width;
	descriptor.height = description.height;
	descriptor.layer_count = description.layerCount;
	descriptor.hal_format = static_cast<uint64_t>(description.format);
	descriptor.producer_usage = static_cast<uint64_t>(description.usage);
	descriptor.consumer_usage = descriptor.producer_usage;
	descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;

	/* Check if it is possible to allocate a buffer for the given description */
	const int alloc_result = mali_gralloc_derive_format_and_size(&descriptor);
	if (alloc_result != 0)
	{
		MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", alloc_result);
		outVec = vec;
		return Error::BAD_VALUE;
	}
	/* Create buffer handle from the initialized descriptor without a backing store or shared metadata region.
	 * Used to share functionality with the normal metadata get function that can only use the allocated buffer handle
	 * and does not have the buffer descriptor available. */
	private_handle_t partial_handle(0, descriptor.alloc_sizes, descriptor.consumer_usage, descriptor.producer_usage,
			                nullptr, descriptor.fd_count,
	                                descriptor.hal_format, descriptor.alloc_format,
	                                descriptor.width, descriptor.height, descriptor.pixel_stride,
	                                descriptor.layer_count, descriptor.plane_info);
	if (isStandardMetadataType(metadataType))
	{
		android::status_t err = android::OK;

		switch (static_cast<StandardMetadataType>(metadataType.value))
		{
		case StandardMetadataType::NAME:
			err = android::gralloc4::encodeName(description.name, &vec);
			break;
		case StandardMetadataType::WIDTH:
			err = android::gralloc4::encodeWidth(description.width, &vec);
			break;
		case StandardMetadataType::HEIGHT:
			err = android::gralloc4::encodeHeight(description.height, &vec);
			break;
		case StandardMetadataType::LAYER_COUNT:
			err = android::gralloc4::encodeLayerCount(description.layerCount, &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
			err = android::gralloc4::encodePixelFormatRequested(static_cast<hidl::PixelFormat>(description.format), &vec);
			break;
		case StandardMetadataType::USAGE:
			err = android::gralloc4::encodeUsage(description.usage, &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_FOURCC:
			err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(&partial_handle), &vec);
			break;
		case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
			err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(&partial_handle), &vec);
			break;
		case StandardMetadataType::ALLOCATION_SIZE:
		{
			/* TODO: Returns expetected size if the buffer was actually allocated.
			 * Is this the right behavior?
			 */
			uint64_t total_size = 0;
			for (int fidx = 0; fidx < descriptor.fd_count; fidx++)
			{
				total_size += descriptor.alloc_sizes[fidx];
			}
			err = android::gralloc4::encodeAllocationSize(total_size, &vec);
			break;
		}
		case StandardMetadataType::PROTECTED_CONTENT:
		{
			/* This is set to 1 if the buffer has protected content. */
			const int is_protected =
			    (((partial_handle.consumer_usage | partial_handle.producer_usage) & static_cast<uint64_t>(BufferUsage::PROTECTED))) ? 1 : 0;
			err = android::gralloc4::encodeProtectedContent(is_protected, &vec);
			break;
		}
		case StandardMetadataType::COMPRESSION:
		{
			ExtendableType compression;
			if (partial_handle.alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
			{
				compression = Compression_AFBC;
			}
			else
			{
				compression = android::gralloc4::Compression_None;
			}
			err = android::gralloc4::encodeCompression(compression, &vec);
			break;
		}
		case StandardMetadataType::INTERLACED:
			err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec);
			break;
		case StandardMetadataType::CHROMA_SITING:
		{
			int format_index = get_format_index(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
			if (format_index < 0)
			{
				err = android::BAD_VALUE;
				break;
			}
			ExtendableType siting = android::gralloc4::ChromaSiting_None;
			if (formats[format_index].is_yuv)
			{
				siting = android::gralloc4::ChromaSiting_Unknown;
			}
			err = android::gralloc4::encodeChromaSiting(siting, &vec);
			break;
		}
		case StandardMetadataType::PLANE_LAYOUTS:
		{
			std::vector<PlaneLayout> layouts;
			err = get_plane_layouts(&partial_handle, &layouts);
			if (!err)
			{
				err = android::gralloc4::encodePlaneLayouts(layouts, &vec);
			}
			break;
		}
		case StandardMetadataType::DATASPACE:
		{
			android_dataspace_t dataspace;
			get_format_dataspace(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK,
			                     partial_handle.consumer_usage | partial_handle.producer_usage, partial_handle.width,
			                     partial_handle.height, &dataspace);
			err = android::gralloc4::encodeDataspace(static_cast<Dataspace>(dataspace), &vec);
			break;
		}
		case StandardMetadataType::BLEND_MODE:
			err = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &vec);
			break;
		case StandardMetadataType::CROP:
		{
			const int num_planes = get_num_planes(&partial_handle);
			std::vector<Rect> crops(num_planes);
			for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
			{
				Rect rect = {.top = 0,
					         .left = 0,
					         .right = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_width),
					         .bottom = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_height) };
				if (plane_index == 0)
				{
					rect = {.top = 0, .left = 0, .right = partial_handle.width, .bottom = partial_handle.height };
				}
				crops[plane_index] = rect;
			}
			err = android::gralloc4::encodeCrop(crops, &vec);
			break;
		}
		case StandardMetadataType::SMPTE2086:
		{
			std::optional<Smpte2086> smpte2086{};
			err = android::gralloc4::encodeSmpte2086(smpte2086, &vec);
			break;
		}
		case StandardMetadataType::CTA861_3:
		{
			std::optional<Cta861_3> cta861_3{};
			err = android::gralloc4::encodeCta861_3(cta861_3, &vec);
			break;
		}
		case StandardMetadataType::SMPTE2094_40:
		{
			std::optional<std::vector<uint8_t>> smpte2094_40{};
			err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec);
			break;
		}

		case StandardMetadataType::BUFFER_ID:
		case StandardMetadataType::INVALID:
		default:
			err = android::BAD_VALUE;
		}
		outVec = vec;
		return ((err) ? Error::UNSUPPORTED : Error::NONE);
	}
	else
	{
		outVec = vec;
		return Error::UNSUPPORTED;
	}
}

#endif // GRALLOC_MAPPER_4
} // namespace common
} // namespace mapper
} // namespace arm
