/*
 * Copyright (C) 2022 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.
 */

#define LOG_TAG "Gralloc5"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS

#include <ui/Gralloc5.h>

#include <aidlcommonsupport/NativeHandle.h>
#include <android/binder_manager.h>
#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
#include <binder/IPCThreadState.h>
#include <dlfcn.h>
#include <ui/FatVector.h>
#include <vndksupport/linker.h>

using namespace aidl::android::hardware::graphics::allocator;
using namespace aidl::android::hardware::graphics::common;
using namespace ::android::hardware::graphics::mapper;

namespace android {

static const auto kIAllocatorServiceName = IAllocator::descriptor + std::string("/default");
static const auto kIAllocatorMinimumVersion = 2;

// TODO(b/72323293, b/72703005): Remove these invalid bits from callers
static constexpr uint64_t kRemovedUsageBits = static_cast<uint64_t>((1 << 10) | (1 << 13));

typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper *_Nullable *_Nonnull outImplementation);

struct Gralloc5 {
    std::shared_ptr<IAllocator> allocator;
    AIMapper *mapper = nullptr;
};

static std::shared_ptr<IAllocator> waitForAllocator() {
    if (__builtin_available(android 31, *)) {
        if (!AServiceManager_isDeclared(kIAllocatorServiceName.c_str())) {
            return nullptr;
        }
        auto allocator = IAllocator::fromBinder(
                ndk::SpAIBinder(AServiceManager_waitForService(kIAllocatorServiceName.c_str())));
        if (!allocator) {
            ALOGE("AIDL IAllocator declared but failed to get service");
            return nullptr;
        }

        int32_t version = 0;
        if (!allocator->getInterfaceVersion(&version).isOk()) {
            ALOGE("Failed to query interface version");
            return nullptr;
        }
        if (version < kIAllocatorMinimumVersion) {
            return nullptr;
        }
        return allocator;
    } else {
        // TODO: LOG_ALWAYS_FATAL("libui is not backwards compatible");
        return nullptr;
    }
}

static void *loadIMapperLibrary() {
    static void *imapperLibrary = []() -> void * {
        auto allocator = waitForAllocator();
        std::string mapperSuffix;
        auto status = allocator->getIMapperLibrarySuffix(&mapperSuffix);
        if (!status.isOk()) {
            ALOGE("Failed to get IMapper library suffix");
            return nullptr;
        }

        std::string lib_name = "mapper." + mapperSuffix + ".so";
        void *so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
        if (!so) {
            ALOGE("Failed to load %s", lib_name.c_str());
        }
        return so;
    }();
    return imapperLibrary;
}

static const Gralloc5 &getInstance() {
    static Gralloc5 instance = []() {
        auto allocator = waitForAllocator();
        if (!allocator) {
            return Gralloc5{};
        }
        void *so = loadIMapperLibrary();
        if (!so) {
            return Gralloc5{};
        }
        auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
        AIMapper *mapper = nullptr;
        AIMapper_Error error = loadIMapper(&mapper);
        if (error != AIMAPPER_ERROR_NONE) {
            ALOGE("AIMapper_loadIMapper failed %d", error);
            return Gralloc5{};
        }
        return Gralloc5{std::move(allocator), mapper};
    }();
    return instance;
}

template <StandardMetadataType T>
static auto getStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle)
        -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
    using Value = typename StandardMetadata<T>::value;
    // TODO: Tune for common-case better
    FatVector<uint8_t, 128> buffer;
    int32_t sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
                                                          buffer.data(), buffer.size());
    if (sizeRequired < 0) {
        ALOGW_IF(-AIMAPPER_ERROR_UNSUPPORTED != sizeRequired,
                 "Unexpected error %d from valid getStandardMetadata call", -sizeRequired);
        return std::nullopt;
    }
    if ((size_t)sizeRequired > buffer.size()) {
        buffer.resize(sizeRequired);
        sizeRequired = mapper->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
                                                      buffer.data(), buffer.size());
    }
    if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
        ALOGW("getStandardMetadata failed, received %d with buffer size %zd", sizeRequired,
              buffer.size());
        // Generate a fail type
        return std::nullopt;
    }
    return Value::decode(buffer.data(), sizeRequired);
}

template <StandardMetadataType T>
static AIMapper_Error setStandardMetadata(AIMapper *mapper, buffer_handle_t bufferHandle,
                                          const typename StandardMetadata<T>::value_type &value) {
    using Value = typename StandardMetadata<T>::value;
    int32_t sizeRequired = Value::encode(value, nullptr, 0);
    if (sizeRequired < 0) {
        ALOGW("Failed to calculate required size");
        return static_cast<AIMapper_Error>(-sizeRequired);
    }
    FatVector<uint8_t, 128> buffer;
    buffer.resize(sizeRequired);
    sizeRequired = Value::encode(value, buffer.data(), buffer.size());
    if (sizeRequired < 0 || (size_t)sizeRequired > buffer.size()) {
        ALOGW("Failed to encode with calculated size %d; buffer size %zd", sizeRequired,
              buffer.size());
        return static_cast<AIMapper_Error>(-sizeRequired);
    }
    return mapper->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T), buffer.data(),
                                          sizeRequired);
}

Gralloc5Allocator::Gralloc5Allocator(const Gralloc5Mapper &mapper) : mMapper(mapper) {
    mAllocator = getInstance().allocator;
}

bool Gralloc5Allocator::isLoaded() const {
    return mAllocator != nullptr;
}

static uint64_t getValidUsageBits() {
    static const uint64_t validUsageBits = []() -> uint64_t {
        uint64_t bits = 0;
        for (const auto bit : ndk::enum_range<BufferUsage>{}) {
            bits |= static_cast<int64_t>(bit);
        }
        return bits;
    }();
    return validUsageBits | kRemovedUsageBits;
}

static std::optional<BufferDescriptorInfo> makeDescriptor(std::string requestorName, uint32_t width,
                                                          uint32_t height, PixelFormat format,
                                                          uint32_t layerCount, uint64_t usage) {
    uint64_t validUsageBits = getValidUsageBits();
    if (usage & ~validUsageBits) {
        ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, usage & ~validUsageBits);
        return std::nullopt;
    }

    BufferDescriptorInfo descriptorInfo{
            .width = static_cast<int32_t>(width),
            .height = static_cast<int32_t>(height),
            .layerCount = static_cast<int32_t>(layerCount),
            .format = static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format),
            .usage = static_cast<BufferUsage>(usage),
    };
    auto nameLength = std::min(requestorName.length(), descriptorInfo.name.size() - 1);
    memcpy(descriptorInfo.name.data(), requestorName.data(), nameLength);
    requestorName.data()[nameLength] = 0;
    return descriptorInfo;
}

std::string Gralloc5Allocator::dumpDebugInfo(bool less) const {
    return mMapper.dumpBuffers(less);
}

status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
                                     android::PixelFormat format, uint32_t layerCount,
                                     uint64_t usage, uint32_t bufferCount, uint32_t *outStride,
                                     buffer_handle_t *outBufferHandles, bool importBuffers) const {
    auto descriptorInfo = makeDescriptor(requestorName, width, height, format, layerCount, usage);
    if (!descriptorInfo) {
        return BAD_VALUE;
    }

    AllocationResult result;
    auto status = mAllocator->allocate2(*descriptorInfo, bufferCount, &result);
    if (!status.isOk()) {
        auto error = status.getExceptionCode();
        if (error == EX_SERVICE_SPECIFIC) {
            error = status.getServiceSpecificError();
        }
        if (error == OK) {
            error = UNKNOWN_ERROR;
        }
        return error;
    }

    if (importBuffers) {
        for (uint32_t i = 0; i < bufferCount; i++) {
            auto handle = makeFromAidl(result.buffers[i]);
            auto error = mMapper.importBuffer(handle, &outBufferHandles[i]);
            native_handle_delete(handle);
            if (error != NO_ERROR) {
                for (uint32_t j = 0; j < i; j++) {
                    mMapper.freeBuffer(outBufferHandles[j]);
                    outBufferHandles[j] = nullptr;
                }
                return error;
            }
        }
    } else {
        for (uint32_t i = 0; i < bufferCount; i++) {
            outBufferHandles[i] = dupFromAidl(result.buffers[i]);
            if (!outBufferHandles[i]) {
                for (uint32_t j = 0; j < i; j++) {
                    auto buffer = const_cast<native_handle_t *>(outBufferHandles[j]);
                    native_handle_close(buffer);
                    native_handle_delete(buffer);
                    outBufferHandles[j] = nullptr;
                }
                return NO_MEMORY;
            }
        }
    }

    *outStride = result.stride;

    // Release all the resources held by AllocationResult (specifically any remaining FDs)
    result = {};
    // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
    // TODO: Re-enable this at some point if it's necessary. We can't do it now because libui
    // is marked apex_available (b/214400477) and libbinder isn't (which of course is correct)
    // IPCThreadState::self()->flushCommands();

    return OK;
}

void Gralloc5Mapper::preload() {
    // TODO(b/261858155): Implement. We can't bounce off of IAllocator for this because zygote can't
    // use binder. So when an alternate strategy of retrieving the library prefix is available,
    // use that here.
}

Gralloc5Mapper::Gralloc5Mapper() {
    mMapper = getInstance().mapper;
}

bool Gralloc5Mapper::isLoaded() const {
    return mMapper != nullptr && mMapper->version >= AIMAPPER_VERSION_5;
}

std::string Gralloc5Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
    // TODO(b/261858392): Implement
    (void)bufferHandle;
    (void)less;
    return {};
}

std::string Gralloc5Mapper::dumpBuffers(bool less) const {
    // TODO(b/261858392): Implement
    (void)less;
    return {};
}

status_t Gralloc5Mapper::importBuffer(const native_handle_t *rawHandle,
                                      buffer_handle_t *outBufferHandle) const {
    return mMapper->v5.importBuffer(rawHandle, outBufferHandle);
}

void Gralloc5Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
    mMapper->v5.freeBuffer(bufferHandle);
}

status_t Gralloc5Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
                                            uint32_t height, PixelFormat format,
                                            uint32_t layerCount, uint64_t usage,
                                            uint32_t stride) const {
    {
        auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
        if (width != value) {
            ALOGW("Width didn't match, expected %d got %" PRId64, width, value.value_or(-1));
            return BAD_VALUE;
        }
    }
    {
        auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
        if (height != value) {
            ALOGW("Height didn't match, expected %d got %" PRId64, height, value.value_or(-1));
            return BAD_VALUE;
        }
    }
    {
        auto value =
                getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
                                                                                  bufferHandle);
        if (static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(format) !=
            value) {
            ALOGW("Format didn't match, expected %d got %s", format,
                  value.has_value() ? toString(*value).c_str() : "<null>");
            return BAD_VALUE;
        }
    }
    {
        auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
        if (layerCount != value) {
            ALOGW("Layer count didn't match, expected %d got %" PRId64, layerCount,
                  value.value_or(-1));
            return BAD_VALUE;
        }
    }
    {
        auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
        if (static_cast<BufferUsage>(usage) != value) {
            ALOGW("Usage didn't match, expected %" PRIu64 " got %" PRId64, usage,
                  static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
            return BAD_VALUE;
        }
    }
    {
        (void)stride;
        // TODO(b/261856851): Add StandardMetadataType::STRIDE && enable this
        //        auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper,
        //        bufferHandle); if (static_cast<BufferUsage>(usage) != value) {
        //            ALOGW("Layer count didn't match, expected %" PRIu64 " got %" PRId64, usage,
        //                  static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
        //            return BAD_VALUE;
        //        }
    }
    return OK;
}

void Gralloc5Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds,
                                      uint32_t *outNumInts) const {
    mMapper->v5.getTransportSize(bufferHandle, outNumFds, outNumInts);
}

status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
                              int acquireFence, void **outData, int32_t *outBytesPerPixel,
                              int32_t *outBytesPerStride) const {
    std::vector<ui::PlaneLayout> planeLayouts;
    status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);

    if (err == NO_ERROR && !planeLayouts.empty()) {
        if (outBytesPerPixel) {
            int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
            for (const auto &planeLayout : planeLayouts) {
                if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
                    bitsPerPixel = -1;
                }
            }
            if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
                *outBytesPerPixel = bitsPerPixel / 8;
            } else {
                *outBytesPerPixel = -1;
            }
        }
        if (outBytesPerStride) {
            int32_t bytesPerStride = planeLayouts.front().strideInBytes;
            for (const auto &planeLayout : planeLayouts) {
                if (bytesPerStride != planeLayout.strideInBytes) {
                    bytesPerStride = -1;
                }
            }
            if (bytesPerStride >= 0) {
                *outBytesPerStride = bytesPerStride;
            } else {
                *outBytesPerStride = -1;
            }
        }
    }

    auto status = mMapper->v5.lock(bufferHandle, usage, bounds, acquireFence, outData);

    ALOGW_IF(status != AIMAPPER_ERROR_NONE, "lock(%p, ...) failed: %d", bufferHandle, status);
    return static_cast<status_t>(status);
}

status_t Gralloc5Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect &bounds,
                              int acquireFence, android_ycbcr *outYcbcr) const {
    if (!outYcbcr) {
        return BAD_VALUE;
    }

    // TODO(b/262279301): Change the return type of ::unlock to unique_fd instead of int so that
    //  ignoring the return value "just works" instead
    auto unlock = [this](buffer_handle_t bufferHandle) {
        int fence = this->unlock(bufferHandle);
        if (fence != -1) {
            ::close(fence);
        }
    };

    std::vector<ui::PlaneLayout> planeLayouts;
    status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
    if (error != NO_ERROR) {
        return error;
    }

    void *data = nullptr;
    error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
    if (error != NO_ERROR) {
        return error;
    }

    android_ycbcr ycbcr;

    ycbcr.y = nullptr;
    ycbcr.cb = nullptr;
    ycbcr.cr = nullptr;
    ycbcr.ystride = 0;
    ycbcr.cstride = 0;
    ycbcr.chroma_step = 0;

    for (const auto &planeLayout : planeLayouts) {
        for (const auto &planeLayoutComponent : planeLayout.components) {
            if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
                continue;
            }

            uint8_t *tmpData = static_cast<uint8_t *>(data) + planeLayout.offsetInBytes;

            // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
            // but we still want to point to the start of the first byte.
            tmpData += (planeLayoutComponent.offsetInBits / 8);

            uint64_t sampleIncrementInBytes;

            auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
            switch (type) {
                case PlaneLayoutComponentType::Y:
                    if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
                        unlock(bufferHandle);
                        return BAD_VALUE;
                    }
                    ycbcr.y = tmpData;
                    ycbcr.ystride = planeLayout.strideInBytes;
                    break;

                case PlaneLayoutComponentType::CB:
                case PlaneLayoutComponentType::CR:
                    if (planeLayout.sampleIncrementInBits % 8 != 0) {
                        unlock(bufferHandle);
                        return BAD_VALUE;
                    }

                    sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
                    if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
                        (sampleIncrementInBytes != 4)) {
                        unlock(bufferHandle);
                        return BAD_VALUE;
                    }

                    if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
                        ycbcr.cstride = planeLayout.strideInBytes;
                        ycbcr.chroma_step = sampleIncrementInBytes;
                    } else {
                        if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
                            (ycbcr.chroma_step != sampleIncrementInBytes)) {
                            unlock(bufferHandle);
                            return BAD_VALUE;
                        }
                    }

                    if (type == PlaneLayoutComponentType::CB) {
                        if (ycbcr.cb != nullptr) {
                            unlock(bufferHandle);
                            return BAD_VALUE;
                        }
                        ycbcr.cb = tmpData;
                    } else {
                        if (ycbcr.cr != nullptr) {
                            unlock(bufferHandle);
                            return BAD_VALUE;
                        }
                        ycbcr.cr = tmpData;
                    }
                    break;
                default:
                    break;
            };
        }
    }

    *outYcbcr = ycbcr;
    return OK;
}

int Gralloc5Mapper::unlock(buffer_handle_t bufferHandle) const {
    int fence = -1;
    AIMapper_Error error = mMapper->v5.unlock(bufferHandle, &fence);
    if (error != AIMAPPER_ERROR_NONE) {
        ALOGW("unlock failed with error %d", error);
    }
    return fence;
}

status_t Gralloc5Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
                                     uint32_t layerCount, uint64_t usage,
                                     bool *outSupported) const {
    auto descriptorInfo = makeDescriptor("", width, height, format, layerCount, usage);
    if (!descriptorInfo) {
        *outSupported = false;
        return OK;
    }
    auto status = getInstance().allocator->isSupported(*descriptorInfo, outSupported);
    if (!status.isOk()) {
        ALOGW("IAllocator::isSupported error %d (%s)", status.getStatus(), status.getMessage());
        *outSupported = false;
    }
    return OK;
}

status_t Gralloc5Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t *outBufferId) const {
    auto value = getStandardMetadata<StandardMetadataType::BUFFER_ID>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outBufferId = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getName(buffer_handle_t bufferHandle, std::string *outName) const {
    auto value = getStandardMetadata<StandardMetadataType::NAME>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outName = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t *outWidth) const {
    auto value = getStandardMetadata<StandardMetadataType::WIDTH>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outWidth = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t *outHeight) const {
    auto value = getStandardMetadata<StandardMetadataType::HEIGHT>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outHeight = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getLayerCount(buffer_handle_t bufferHandle,
                                       uint64_t *outLayerCount) const {
    auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outLayerCount = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
                                                 ui::PixelFormat *outPixelFormatRequested) const {
    auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(mMapper,
                                                                                   bufferHandle);
    if (value.has_value()) {
        *outPixelFormatRequested = static_cast<ui::PixelFormat>(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
                                              uint32_t *outPixelFormatFourCC) const {
    auto value =
            getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outPixelFormatFourCC = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
                                                uint64_t *outPixelFormatModifier) const {
    auto value =
            getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outPixelFormatModifier = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t *outUsage) const {
    auto value = getStandardMetadata<StandardMetadataType::USAGE>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outUsage = static_cast<uint64_t>(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getAllocationSize(buffer_handle_t bufferHandle,
                                           uint64_t *outAllocationSize) const {
    auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outAllocationSize = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getProtectedContent(buffer_handle_t bufferHandle,
                                             uint64_t *outProtectedContent) const {
    auto value =
            getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outProtectedContent = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getCompression(
        buffer_handle_t bufferHandle,
        aidl::android::hardware::graphics::common::ExtendableType *outCompression) const {
    auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outCompression = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getCompression(buffer_handle_t bufferHandle,
                                        ui::Compression *outCompression) const {
    auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(mMapper, bufferHandle);
    if (!value.has_value()) {
        return UNKNOWN_TRANSACTION;
    }
    if (!gralloc4::isStandardCompression(*value)) {
        return BAD_TYPE;
    }
    *outCompression = gralloc4::getStandardCompressionValue(*value);
    return OK;
}

status_t Gralloc5Mapper::getInterlaced(
        buffer_handle_t bufferHandle,
        aidl::android::hardware::graphics::common::ExtendableType *outInterlaced) const {
    auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outInterlaced = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getInterlaced(buffer_handle_t bufferHandle,
                                       ui::Interlaced *outInterlaced) const {
    if (!outInterlaced) {
        return BAD_VALUE;
    }
    ExtendableType interlaced;
    status_t error = getInterlaced(bufferHandle, &interlaced);
    if (error) {
        return error;
    }
    if (!gralloc4::isStandardInterlaced(interlaced)) {
        return BAD_TYPE;
    }
    *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
    return NO_ERROR;
}

status_t Gralloc5Mapper::getChromaSiting(
        buffer_handle_t bufferHandle,
        aidl::android::hardware::graphics::common::ExtendableType *outChromaSiting) const {
    auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outChromaSiting = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getChromaSiting(buffer_handle_t bufferHandle,
                                         ui::ChromaSiting *outChromaSiting) const {
    if (!outChromaSiting) {
        return BAD_VALUE;
    }
    ExtendableType chromaSiting;
    status_t error = getChromaSiting(bufferHandle, &chromaSiting);
    if (error) {
        return error;
    }
    if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
        return BAD_TYPE;
    }
    *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
    return NO_ERROR;
}

status_t Gralloc5Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
                                         std::vector<ui::PlaneLayout> *outPlaneLayouts) const {
    auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outPlaneLayouts = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDataspace(buffer_handle_t bufferHandle,
                                      ui::Dataspace *outDataspace) const {
    auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outDataspace = static_cast<ui::Dataspace>(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
    return setStandardMetadata<StandardMetadataType::DATASPACE>(mMapper, bufferHandle,
                                                                static_cast<Dataspace>(dataspace));
}

status_t Gralloc5Mapper::getBlendMode(buffer_handle_t bufferHandle,
                                      ui::BlendMode *outBlendMode) const {
    auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outBlendMode = static_cast<ui::BlendMode>(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getSmpte2086(buffer_handle_t bufferHandle,
                                      std::optional<ui::Smpte2086> *outSmpte2086) const {
    auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outSmpte2086 = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::setSmpte2086(buffer_handle_t bufferHandle,
                                      std::optional<ui::Smpte2086> smpte2086) const {
    return setStandardMetadata<StandardMetadataType::SMPTE2086>(mMapper, bufferHandle, smpte2086);
}

status_t Gralloc5Mapper::getCta861_3(buffer_handle_t bufferHandle,
                                     std::optional<ui::Cta861_3> *outCta861_3) const {
    auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outCta861_3 = *value;
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::setCta861_3(buffer_handle_t bufferHandle,
                                     std::optional<ui::Cta861_3> cta861_3) const {
    return setStandardMetadata<StandardMetadataType::CTA861_3>(mMapper, bufferHandle, cta861_3);
}

status_t Gralloc5Mapper::getSmpte2094_40(
        buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_40) const {
    auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outSmpte2094_40 = std::move(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
                                         std::optional<std::vector<uint8_t>> smpte2094_40) const {
    return setStandardMetadata<StandardMetadataType::SMPTE2094_40>(mMapper, bufferHandle,
                                                                   smpte2094_40);
}

status_t Gralloc5Mapper::getSmpte2094_10(
        buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>> *outSmpte2094_10) const {
    auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle);
    if (value.has_value()) {
        *outSmpte2094_10 = std::move(*value);
        return OK;
    }
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
                                         std::optional<std::vector<uint8_t>> smpte2094_10) const {
    return setStandardMetadata<StandardMetadataType::SMPTE2094_10>(mMapper, bufferHandle,
                                                                   smpte2094_10);
}

status_t Gralloc5Mapper::getDefaultPixelFormatFourCC(uint32_t, uint32_t, PixelFormat, uint32_t,
                                                     uint64_t, uint32_t *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultPixelFormatModifier(uint32_t, uint32_t, PixelFormat, uint32_t,
                                                       uint64_t, uint64_t *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultAllocationSize(uint32_t, uint32_t, PixelFormat, uint32_t,
                                                  uint64_t, uint64_t *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultProtectedContent(uint32_t, uint32_t, PixelFormat, uint32_t,
                                                    uint64_t, uint64_t *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultCompression(
        uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
        aidl::android::hardware::graphics::common::ExtendableType *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultCompression(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
                                               ui::Compression *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultInterlaced(
        uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
        aidl::android::hardware::graphics::common::ExtendableType *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultInterlaced(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
                                              ui::Interlaced *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultChromaSiting(
        uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
        aidl::android::hardware::graphics::common::ExtendableType *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultChromaSiting(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
                                                ui::ChromaSiting *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

status_t Gralloc5Mapper::getDefaultPlaneLayouts(uint32_t, uint32_t, PixelFormat, uint32_t, uint64_t,
                                                std::vector<ui::PlaneLayout> *) const {
    // TODO(b/261857910): Remove
    return UNKNOWN_TRANSACTION;
}

} // namespace android