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

#pragma once

#include <android-base/unique_fd.h>
#include <cutils/ashmem.h>
#include <fmq/EventFlag.h>
#include <sys/mman.h>
#include <sys/user.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <atomic>
#include <new>

using android::hardware::kSynchronizedReadWrite;
using android::hardware::kUnsynchronizedWrite;
using android::hardware::MQFlavor;

namespace android {

template <template <typename, MQFlavor> class MQDescriptorType, typename T, MQFlavor flavor>
struct MessageQueueBase {
    typedef MQDescriptorType<T, flavor> Descriptor;

    /**
     * @param Desc MQDescriptor describing the FMQ.
     * @param resetPointers bool indicating whether the read/write pointers
     * should be reset or not.
     */
    MessageQueueBase(const Descriptor& Desc, bool resetPointers = true);

    ~MessageQueueBase();

    /**
     * This constructor uses Ashmem shared memory to create an FMQ
     * that can contain a maximum of 'numElementsInQueue' elements of type T.
     *
     * @param numElementsInQueue Capacity of the MessageQueue in terms of T.
     * @param configureEventFlagWord Boolean that specifies if memory should
     * also be allocated and mapped for an EventFlag word.
     * @param bufferFd User-supplied file descriptor to map the memory for the ringbuffer
     * By default, bufferFd=-1 means library will allocate ashmem region for ringbuffer.
     * MessageQueue takes ownership of the file descriptor.
     * @param bufferSize size of buffer in bytes that bufferFd represents. This
     * size must be larger than or equal to (numElementsInQueue * sizeof(T)).
     * Otherwise, operations will cause out-of-bounds memory access.
     */

    MessageQueueBase(size_t numElementsInQueue, bool configureEventFlagWord,
                     android::base::unique_fd bufferFd, size_t bufferSize);

    MessageQueueBase(size_t numElementsInQueue, bool configureEventFlagWord = false)
        : MessageQueueBase(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(),
                           0) {}

    /**
     * @return Number of items of type T that can be written into the FMQ
     * without a read.
     */
    size_t availableToWrite() const;

    /**
     * @return Number of items of type T that are waiting to be read from the
     * FMQ.
     */
    size_t availableToRead() const;

    /**
     * Returns the size of type T in bytes.
     *
     * @param Size of T.
     */
    size_t getQuantumSize() const;

    /**
     * Returns the size of the FMQ in terms of the size of type T.
     *
     * @return Number of items of type T that will fit in the FMQ.
     */
    size_t getQuantumCount() const;

    /**
     * @return Whether the FMQ is configured correctly.
     */
    bool isValid() const;

    /**
     * Non-blocking write to FMQ.
     *
     * @param data Pointer to the object of type T to be written into the FMQ.
     *
     * @return Whether the write was successful.
     */
    bool write(const T* data);

    /**
     * Non-blocking read from FMQ.
     *
     * @param data Pointer to the memory where the object read from the FMQ is
     * copied to.
     *
     * @return Whether the read was successful.
     */
    bool read(T* data);

    /**
     * Write some data into the FMQ without blocking.
     *
     * @param data Pointer to the array of items of type T.
     * @param count Number of items in array.
     *
     * @return Whether the write was successful.
     */
    bool write(const T* data, size_t count);

    /**
     * Perform a blocking write of 'count' items into the FMQ using EventFlags.
     * Does not support partial writes.
     *
     * If 'evFlag' is nullptr, it is checked whether there is an EventFlag object
     * associated with the FMQ and it is used in that case.
     *
     * The application code must ensure that 'evFlag' used by the
     * reader(s)/writer is based upon the same EventFlag word.
     *
     * The method will return false without blocking if any of the following
     * conditions are true:
     * - If 'evFlag' is nullptr and the FMQ does not own an EventFlag object.
     * - If the 'readNotification' bit mask is zero.
     * - If 'count' is greater than the FMQ size.
     *
     * If the there is insufficient space available to write into it, the
     * EventFlag bit mask 'readNotification' is is waited upon.
     *
     * This method should only be used with a MessageQueue of the flavor
     * 'kSynchronizedReadWrite'.
     *
     * Upon a successful write, wake is called on 'writeNotification' (if
     * non-zero).
     *
     * @param data Pointer to the array of items of type T.
     * @param count Number of items in array.
     * @param readNotification The EventFlag bit mask to wait on if there is not
     * enough space in FMQ to write 'count' items.
     * @param writeNotification The EventFlag bit mask to call wake on
     * a successful write. No wake is called if 'writeNotification' is zero.
     * @param timeOutNanos Number of nanoseconds after which the blocking
     * write attempt is aborted.
     * @param evFlag The EventFlag object to be used for blocking. If nullptr,
     * it is checked whether the FMQ owns an EventFlag object and that is used
     * for blocking instead.
     *
     * @return Whether the write was successful.
     */
    bool writeBlocking(const T* data, size_t count, uint32_t readNotification,
                       uint32_t writeNotification, int64_t timeOutNanos = 0,
                       android::hardware::EventFlag* evFlag = nullptr);

    bool writeBlocking(const T* data, size_t count, int64_t timeOutNanos = 0);

    /**
     * Read some data from the FMQ without blocking.
     *
     * @param data Pointer to the array to which read data is to be written.
     * @param count Number of items to be read.
     *
     * @return Whether the read was successful.
     */
    bool read(T* data, size_t count);

    /**
     * Perform a blocking read operation of 'count' items from the FMQ. Does not
     * perform a partial read.
     *
     * If 'evFlag' is nullptr, it is checked whether there is an EventFlag object
     * associated with the FMQ and it is used in that case.
     *
     * The application code must ensure that 'evFlag' used by the
     * reader(s)/writer is based upon the same EventFlag word.
     *
     * The method will return false without blocking if any of the following
     * conditions are true:
     * -If 'evFlag' is nullptr and the FMQ does not own an EventFlag object.
     * -If the 'writeNotification' bit mask is zero.
     * -If 'count' is greater than the FMQ size.
     *
     * This method should only be used with a MessageQueue of the flavor
     * 'kSynchronizedReadWrite'.

     * If FMQ does not contain 'count' items, the eventFlag bit mask
     * 'writeNotification' is waited upon. Upon a successful read from the FMQ,
     * wake is called on 'readNotification' (if non-zero).
     *
     * @param data Pointer to the array to which read data is to be written.
     * @param count Number of items to be read.
     * @param readNotification The EventFlag bit mask to call wake on after
     * a successful read. No wake is called if 'readNotification' is zero.
     * @param writeNotification The EventFlag bit mask to call a wait on
     * if there is insufficient data in the FMQ to be read.
     * @param timeOutNanos Number of nanoseconds after which the blocking
     * read attempt is aborted.
     * @param evFlag The EventFlag object to be used for blocking.
     *
     * @return Whether the read was successful.
     */
    bool readBlocking(T* data, size_t count, uint32_t readNotification, uint32_t writeNotification,
                      int64_t timeOutNanos = 0, android::hardware::EventFlag* evFlag = nullptr);

    bool readBlocking(T* data, size_t count, int64_t timeOutNanos = 0);

    /**
     * Get a pointer to the MQDescriptor object that describes this FMQ.
     *
     * @return Pointer to the MQDescriptor associated with the FMQ.
     */
    const Descriptor* getDesc() const { return mDesc.get(); }

    /**
     * Get a pointer to the EventFlag word if there is one associated with this FMQ.
     *
     * @return Pointer to an EventFlag word, will return nullptr if not
     * configured. This method does not transfer ownership. The EventFlag
     * word will be unmapped by the MessageQueue destructor.
     */
    std::atomic<uint32_t>* getEventFlagWord() const { return mEvFlagWord; }

    /**
     * Describes a memory region in the FMQ.
     */
    struct MemRegion {
        MemRegion() : MemRegion(nullptr, 0) {}

        MemRegion(T* base, size_t size) : address(base), length(size) {}

        MemRegion& operator=(const MemRegion& other) {
            address = other.address;
            length = other.length;
            return *this;
        }

        /**
         * Gets a pointer to the base address of the MemRegion.
         */
        inline T* getAddress() const { return address; }

        /**
         * Gets the length of the MemRegion. This would equal to the number
         * of items of type T that can be read from/written into the MemRegion.
         */
        inline size_t getLength() const { return length; }

        /**
         * Gets the length of the MemRegion in bytes.
         */
        inline size_t getLengthInBytes() const { return length * sizeof(T); }

      private:
        /* Base address */
        T* address;

        /*
         * Number of items of type T that can be written to/read from the base
         * address.
         */
        size_t length;
    };

    /**
     * Describes the memory regions to be used for a read or write.
     * The struct contains two MemRegion objects since the FMQ is a ring
     * buffer and a read or write operation can wrap around. A single message
     * of type T will never be broken between the two MemRegions.
     */
    struct MemTransaction {
        MemTransaction() : MemTransaction(MemRegion(), MemRegion()) {}

        MemTransaction(const MemRegion& regionFirst, const MemRegion& regionSecond)
            : first(regionFirst), second(regionSecond) {}

        MemTransaction& operator=(const MemTransaction& other) {
            first = other.first;
            second = other.second;
            return *this;
        }

        /**
         * Helper method to calculate the address for a particular index for
         * the MemTransaction object.
         *
         * @param idx Index of the slot to be read/written. If the
         * MemTransaction object is representing the memory region to read/write
         * N items of type T, the valid range of idx is between 0 and N-1.
         *
         * @return Pointer to the slot idx. Will be nullptr for an invalid idx.
         */
        T* getSlot(size_t idx);

        /**
         * Helper method to write 'nMessages' items of type T into the memory
         * regions described by the object starting from 'startIdx'. This method
         * uses memcpy() and is not to meant to be used for a zero copy operation.
         * Partial writes are not supported.
         *
         * @param data Pointer to the source buffer.
         * @param nMessages Number of items of type T.
         * @param startIdx The slot number to begin the write from. If the
         * MemTransaction object is representing the memory region to read/write
         * N items of type T, the valid range of startIdx is between 0 and N-1;
         *
         * @return Whether the write operation of size 'nMessages' succeeded.
         */
        bool copyTo(const T* data, size_t startIdx, size_t nMessages = 1);

        /*
         * Helper method to read 'nMessages' items of type T from the memory
         * regions described by the object starting from 'startIdx'. This method uses
         * memcpy() and is not meant to be used for a zero copy operation. Partial reads
         * are not supported.
         *
         * @param data Pointer to the destination buffer.
         * @param nMessages Number of items of type T.
         * @param startIdx The slot number to begin the read from. If the
         * MemTransaction object is representing the memory region to read/write
         * N items of type T, the valid range of startIdx is between 0 and N-1.
         *
         * @return Whether the read operation of size 'nMessages' succeeded.
         */
        bool copyFrom(T* data, size_t startIdx, size_t nMessages = 1);

        /**
         * Returns a const reference to the first MemRegion in the
         * MemTransaction object.
         */
        inline const MemRegion& getFirstRegion() const { return first; }

        /**
         * Returns a const reference to the second MemRegion in the
         * MemTransaction object.
         */
        inline const MemRegion& getSecondRegion() const { return second; }

      private:
        /*
         * Given a start index and the number of messages to be
         * read/written, this helper method calculates the
         * number of messages that should should be written to both the first
         * and second MemRegions and the base addresses to be used for
         * the read/write operation.
         *
         * Returns false if the 'startIdx' and 'nMessages' is
         * invalid for the MemTransaction object.
         */
        bool inline getMemRegionInfo(size_t idx, size_t nMessages, size_t& firstCount,
                                     size_t& secondCount, T** firstBaseAddress,
                                     T** secondBaseAddress);
        MemRegion first;
        MemRegion second;
    };

    /**
     * Get a MemTransaction object to write 'nMessages' items of type T.
     * Once the write is performed using the information from MemTransaction,
     * the write operation is to be committed using a call to commitWrite().
     *
     * @param nMessages Number of messages of type T.
     * @param Pointer to MemTransaction struct that describes memory to write 'nMessages'
     * items of type T. If a write of size 'nMessages' is not possible, the base
     * addresses in the MemTransaction object would be set to nullptr.
     *
     * @return Whether it is possible to write 'nMessages' items of type T
     * into the FMQ.
     */
    bool beginWrite(size_t nMessages, MemTransaction* memTx) const;

    /**
     * Commit a write of size 'nMessages'. To be only used after a call to beginWrite().
     *
     * @param nMessages number of messages of type T to be written.
     *
     * @return Whether the write operation of size 'nMessages' succeeded.
     */
    bool commitWrite(size_t nMessages);

    /**
     * Get a MemTransaction object to read 'nMessages' items of type T.
     * Once the read is performed using the information from MemTransaction,
     * the read operation is to be committed using a call to commitRead().
     *
     * @param nMessages Number of messages of type T.
     * @param pointer to MemTransaction struct that describes memory to read 'nMessages'
     * items of type T. If a read of size 'nMessages' is not possible, the base
     * pointers in the MemTransaction object returned will be set to nullptr.
     *
     * @return bool Whether it is possible to read 'nMessages' items of type T
     * from the FMQ.
     */
    bool beginRead(size_t nMessages, MemTransaction* memTx) const;

    /**
     * Commit a read of size 'nMessages'. To be only used after a call to beginRead().
     * For the unsynchronized flavor of FMQ, this method will return a failure
     * if a write overflow happened after beginRead() was invoked.
     *
     * @param nMessages number of messages of type T to be read.
     *
     * @return bool Whether the read operation of size 'nMessages' succeeded.
     */
    bool commitRead(size_t nMessages);

  private:
    size_t availableToWriteBytes() const;
    size_t availableToReadBytes() const;

    MessageQueueBase(const MessageQueueBase& other) = delete;
    MessageQueueBase& operator=(const MessageQueueBase& other) = delete;

    void* mapGrantorDescr(uint32_t grantorIdx);
    void unmapGrantorDescr(void* address, uint32_t grantorIdx);
    void initMemory(bool resetPointers);

    enum DefaultEventNotification : uint32_t {
        /*
         * These are only used internally by the readBlocking()/writeBlocking()
         * methods and hence once other bit combinations are not required.
         */
        FMQ_NOT_FULL = 0x01,
        FMQ_NOT_EMPTY = 0x02
    };
    std::unique_ptr<Descriptor> mDesc;
    uint8_t* mRing = nullptr;
    /*
     * TODO(b/31550092): Change to 32 bit read and write pointer counters.
     */
    std::atomic<uint64_t>* mReadPtr = nullptr;
    std::atomic<uint64_t>* mWritePtr = nullptr;

    std::atomic<uint32_t>* mEvFlagWord = nullptr;

    /*
     * This EventFlag object will be owned by the FMQ and will have the same
     * lifetime.
     */
    android::hardware::EventFlag* mEventFlag = nullptr;
};

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
T* MessageQueueBase<MQDescriptorType, T, flavor>::MemTransaction::getSlot(size_t idx) {
    size_t firstRegionLength = first.getLength();
    size_t secondRegionLength = second.getLength();

    if (idx > firstRegionLength + secondRegionLength) {
        return nullptr;
    }

    if (idx < firstRegionLength) {
        return first.getAddress() + idx;
    }

    return second.getAddress() + idx - firstRegionLength;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::MemTransaction::getMemRegionInfo(
        size_t startIdx, size_t nMessages, size_t& firstCount, size_t& secondCount,
        T** firstBaseAddress, T** secondBaseAddress) {
    size_t firstRegionLength = first.getLength();
    size_t secondRegionLength = second.getLength();

    if (startIdx + nMessages > firstRegionLength + secondRegionLength) {
        /*
         * Return false if 'nMessages' starting at 'startIdx' cannot be
         * accommodated by the MemTransaction object.
         */
        return false;
    }

    /* Number of messages to be read/written to the first MemRegion. */
    firstCount =
            startIdx < firstRegionLength ? std::min(nMessages, firstRegionLength - startIdx) : 0;

    /* Number of messages to be read/written to the second MemRegion. */
    secondCount = nMessages - firstCount;

    if (firstCount != 0) {
        *firstBaseAddress = first.getAddress() + startIdx;
    }

    if (secondCount != 0) {
        size_t secondStartIdx = startIdx > firstRegionLength ? startIdx - firstRegionLength : 0;
        *secondBaseAddress = second.getAddress() + secondStartIdx;
    }

    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::MemTransaction::copyFrom(T* data,
                                                                             size_t startIdx,
                                                                             size_t nMessages) {
    if (data == nullptr) {
        return false;
    }

    size_t firstReadCount = 0, secondReadCount = 0;
    T *firstBaseAddress = nullptr, *secondBaseAddress = nullptr;

    if (getMemRegionInfo(startIdx, nMessages, firstReadCount, secondReadCount, &firstBaseAddress,
                         &secondBaseAddress) == false) {
        /*
         * Returns false if 'startIdx' and 'nMessages' are invalid for this
         * MemTransaction object.
         */
        return false;
    }

    if (firstReadCount != 0) {
        memcpy(data, firstBaseAddress, firstReadCount * sizeof(T));
    }

    if (secondReadCount != 0) {
        memcpy(data + firstReadCount, secondBaseAddress, secondReadCount * sizeof(T));
    }

    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::MemTransaction::copyTo(const T* data,
                                                                           size_t startIdx,
                                                                           size_t nMessages) {
    if (data == nullptr) {
        return false;
    }

    size_t firstWriteCount = 0, secondWriteCount = 0;
    T *firstBaseAddress = nullptr, *secondBaseAddress = nullptr;

    if (getMemRegionInfo(startIdx, nMessages, firstWriteCount, secondWriteCount, &firstBaseAddress,
                         &secondBaseAddress) == false) {
        /*
         * Returns false if 'startIdx' and 'nMessages' are invalid for this
         * MemTransaction object.
         */
        return false;
    }

    if (firstWriteCount != 0) {
        memcpy(firstBaseAddress, data, firstWriteCount * sizeof(T));
    }

    if (secondWriteCount != 0) {
        memcpy(secondBaseAddress, data + firstWriteCount, secondWriteCount * sizeof(T));
    }

    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
void MessageQueueBase<MQDescriptorType, T, flavor>::initMemory(bool resetPointers) {
    /*
     * Verify that the Descriptor contains the minimum number of grantors
     * the native_handle is valid and T matches quantum size.
     */
    if ((mDesc == nullptr) || !mDesc->isHandleValid() ||
        (mDesc->countGrantors() < hardware::details::kMinGrantorCount)) {
        return;
    }
    if (mDesc->getQuantum() != sizeof(T)) {
        hardware::details::logError(
                "Payload size differs between the queue instantiation and the "
                "MQDescriptor.");
        return;
    }

    const auto& grantors = mDesc->grantors();
    for (const auto& grantor : grantors) {
        hardware::details::check(hardware::details::isAlignedToWordBoundary(grantor.offset) == true,
                                 "Grantor offsets need to be aligned");
    }

    if (flavor == kSynchronizedReadWrite) {
        mReadPtr = reinterpret_cast<std::atomic<uint64_t>*>(
                mapGrantorDescr(hardware::details::READPTRPOS));
    } else {
        /*
         * The unsynchronized write flavor of the FMQ may have multiple readers
         * and each reader would have their own read pointer counter.
         */
        mReadPtr = new (std::nothrow) std::atomic<uint64_t>;
    }
    hardware::details::check(mReadPtr != nullptr, "mReadPtr is null");

    mWritePtr = reinterpret_cast<std::atomic<uint64_t>*>(
            mapGrantorDescr(hardware::details::WRITEPTRPOS));
    hardware::details::check(mWritePtr != nullptr, "mWritePtr is null");

    if (resetPointers) {
        mReadPtr->store(0, std::memory_order_release);
        mWritePtr->store(0, std::memory_order_release);
    } else if (flavor != kSynchronizedReadWrite) {
        // Always reset the read pointer.
        mReadPtr->store(0, std::memory_order_release);
    }

    mRing = reinterpret_cast<uint8_t*>(mapGrantorDescr(hardware::details::DATAPTRPOS));
    hardware::details::check(mRing != nullptr, "mRing is null");

    if (mDesc->countGrantors() > hardware::details::EVFLAGWORDPOS) {
        mEvFlagWord = static_cast<std::atomic<uint32_t>*>(
                mapGrantorDescr(hardware::details::EVFLAGWORDPOS));
        hardware::details::check(mEvFlagWord != nullptr, "mEvFlagWord is null");
        android::hardware::EventFlag::createEventFlag(mEvFlagWord, &mEventFlag);
    }
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
MessageQueueBase<MQDescriptorType, T, flavor>::MessageQueueBase(const Descriptor& Desc,
                                                                bool resetPointers) {
    mDesc = std::unique_ptr<Descriptor>(new (std::nothrow) Descriptor(Desc));
    if (mDesc == nullptr) {
        return;
    }

    initMemory(resetPointers);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
MessageQueueBase<MQDescriptorType, T, flavor>::MessageQueueBase(size_t numElementsInQueue,
                                                                bool configureEventFlagWord,
                                                                android::base::unique_fd bufferFd,
                                                                size_t bufferSize) {
    // Check if the buffer size would not overflow size_t
    if (numElementsInQueue > SIZE_MAX / sizeof(T)) {
        hardware::details::logError("Requested message queue size too large. Size of elements: " +
                                    std::to_string(sizeof(T)) +
                                    ". Number of elements: " + std::to_string(numElementsInQueue));
        return;
    }
    if (bufferFd != -1 && numElementsInQueue * sizeof(T) > bufferSize) {
        hardware::details::logError("The supplied buffer size(" + std::to_string(bufferSize) +
                                    ") is smaller than the required size(" +
                                    std::to_string(numElementsInQueue * sizeof(T)) + ").");
        return;
    }
    /*
     * The FMQ needs to allocate memory for the ringbuffer as well as for the
     * read and write pointer counters. If an EventFlag word is to be configured,
     * we also need to allocate memory for the same/
     */
    size_t kQueueSizeBytes = numElementsInQueue * sizeof(T);
    size_t kMetaDataSize = 2 * sizeof(android::hardware::details::RingBufferPosition);

    if (configureEventFlagWord) {
        kMetaDataSize += sizeof(std::atomic<uint32_t>);
    }

    /*
     * Ashmem memory region size needs to be specified in page-aligned bytes.
     * kQueueSizeBytes needs to be aligned to word boundary so that all offsets
     * in the grantorDescriptor will be word aligned.
     */
    size_t kAshmemSizePageAligned;
    if (bufferFd != -1) {
        // Allocate read counter and write counter only. User-supplied memory will be used for the
        // ringbuffer.
        kAshmemSizePageAligned = (kMetaDataSize + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
    } else {
        // Allocate ringbuffer, read counter and write counter.
        kAshmemSizePageAligned = (hardware::details::alignToWordBoundary(kQueueSizeBytes) +
                                  kMetaDataSize + PAGE_SIZE - 1) &
                                 ~(PAGE_SIZE - 1);
    }

    /*
     * The native handle will contain the fds to be mapped.
     */
    int numFds = (bufferFd != -1) ? 2 : 1;
    native_handle_t* mqHandle = native_handle_create(numFds, 0 /* numInts */);
    if (mqHandle == nullptr) {
        return;
    }

    /*
     * Create an ashmem region to map the memory.
     */
    int ashmemFd = ashmem_create_region("MessageQueue", kAshmemSizePageAligned);
    ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
    mqHandle->data[0] = ashmemFd;

    if (bufferFd != -1) {
        // Use user-supplied file descriptor for fdIndex 1
        mqHandle->data[1] = bufferFd.get();
        // release ownership of fd. mqHandle owns it now.
        if (bufferFd.release() < 0) {
            hardware::details::logError("Error releasing supplied bufferFd");
        }

        std::vector<android::hardware::GrantorDescriptor> grantors;
        grantors.resize(configureEventFlagWord ? hardware::details::kMinGrantorCountForEvFlagSupport
                                               : hardware::details::kMinGrantorCount);

        size_t memSize[] = {
                sizeof(hardware::details::RingBufferPosition), /* memory to be allocated for read
                                                                  pointer counter */
                sizeof(hardware::details::RingBufferPosition), /* memory to be allocated for write
                                                                  pointer counter */
                kQueueSizeBytes,              /* memory to be allocated for data buffer */
                sizeof(std::atomic<uint32_t>) /* memory to be allocated for EventFlag word */
        };

        for (size_t grantorPos = 0, offset = 0; grantorPos < grantors.size(); grantorPos++) {
            uint32_t grantorFdIndex;
            size_t grantorOffset;
            if (grantorPos == hardware::details::DATAPTRPOS) {
                grantorFdIndex = 1;
                grantorOffset = 0;
            } else {
                grantorFdIndex = 0;
                grantorOffset = offset;
                offset += memSize[grantorPos];
            }
            grantors[grantorPos] = {
                    0 /* grantor flags */, grantorFdIndex,
                    static_cast<uint32_t>(hardware::details::alignToWordBoundary(grantorOffset)),
                    memSize[grantorPos]};
        }

        mDesc = std::unique_ptr<Descriptor>(new (std::nothrow)
                                                    Descriptor(grantors, mqHandle, sizeof(T)));
    } else {
        mDesc = std::unique_ptr<Descriptor>(new (std::nothrow) Descriptor(
                kQueueSizeBytes, mqHandle, sizeof(T), configureEventFlagWord));
    }
    if (mDesc == nullptr) {
        native_handle_close(mqHandle);
        native_handle_delete(mqHandle);
        return;
    }
    initMemory(true);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
MessageQueueBase<MQDescriptorType, T, flavor>::~MessageQueueBase() {
    if (flavor == kUnsynchronizedWrite && mReadPtr != nullptr) {
        delete mReadPtr;
    } else if (mReadPtr != nullptr) {
        unmapGrantorDescr(mReadPtr, hardware::details::READPTRPOS);
    }
    if (mWritePtr != nullptr) {
        unmapGrantorDescr(mWritePtr, hardware::details::WRITEPTRPOS);
    }
    if (mRing != nullptr) {
        unmapGrantorDescr(mRing, hardware::details::DATAPTRPOS);
    }
    if (mEvFlagWord != nullptr) {
        unmapGrantorDescr(mEvFlagWord, hardware::details::EVFLAGWORDPOS);
        android::hardware::EventFlag::deleteEventFlag(&mEventFlag);
    }
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::write(const T* data) {
    return write(data, 1);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::read(T* data) {
    return read(data, 1);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::write(const T* data, size_t nMessages) {
    MemTransaction tx;
    return beginWrite(nMessages, &tx) && tx.copyTo(data, 0 /* startIdx */, nMessages) &&
           commitWrite(nMessages);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::writeBlocking(
        const T* data, size_t count, uint32_t readNotification, uint32_t writeNotification,
        int64_t timeOutNanos, android::hardware::EventFlag* evFlag) {
    static_assert(flavor == kSynchronizedReadWrite,
                  "writeBlocking can only be used with the "
                  "kSynchronizedReadWrite flavor.");
    /*
     * If evFlag is null and the FMQ does not have its own EventFlag object
     * return false;
     * If the flavor is kSynchronizedReadWrite and the readNotification
     * bit mask is zero return false;
     * If the count is greater than queue size, return false
     * to prevent blocking until timeOut.
     */
    if (evFlag == nullptr) {
        evFlag = mEventFlag;
        if (evFlag == nullptr) {
            hardware::details::logError(
                    "writeBlocking failed: called on MessageQueue with no Eventflag"
                    "configured or provided");
            return false;
        }
    }

    if (readNotification == 0 || (count > getQuantumCount())) {
        return false;
    }

    /*
     * There is no need to wait for a readNotification if there is sufficient
     * space to write is already present in the FMQ. The latter would be the case when
     * read operations read more number of messages than write operations write.
     * In other words, a single large read may clear the FMQ after multiple small
     * writes. This would fail to clear a pending readNotification bit since
     * EventFlag bits can only be cleared by a wait() call, however the bit would
     * be correctly cleared by the next writeBlocking() call.
     */

    bool result = write(data, count);
    if (result) {
        if (writeNotification) {
            evFlag->wake(writeNotification);
        }
        return result;
    }

    bool shouldTimeOut = timeOutNanos != 0;
    int64_t prevTimeNanos = shouldTimeOut ? android::elapsedRealtimeNano() : 0;

    while (true) {
        /* It is not required to adjust 'timeOutNanos' if 'shouldTimeOut' is false */
        if (shouldTimeOut) {
            /*
             * The current time and 'prevTimeNanos' are both CLOCK_BOOTTIME clock values(converted
             * to Nanoseconds)
             */
            int64_t currentTimeNs = android::elapsedRealtimeNano();
            /*
             * Decrement 'timeOutNanos' to account for the time taken to complete the last
             * iteration of the while loop.
             */
            timeOutNanos -= currentTimeNs - prevTimeNanos;
            prevTimeNanos = currentTimeNs;

            if (timeOutNanos <= 0) {
                /*
                 * Attempt write in case a context switch happened outside of
                 * evFlag->wait().
                 */
                result = write(data, count);
                break;
            }
        }

        /*
         * wait() will return immediately if there was a pending read
         * notification.
         */
        uint32_t efState = 0;
        status_t status = evFlag->wait(readNotification, &efState, timeOutNanos,
                                       true /* retry on spurious wake */);

        if (status != android::TIMED_OUT && status != android::NO_ERROR) {
            hardware::details::logError("Unexpected error code from EventFlag Wait status " +
                                        std::to_string(status));
            break;
        }

        if (status == android::TIMED_OUT) {
            break;
        }

        /*
         * If there is still insufficient space to write to the FMQ,
         * keep waiting for another readNotification.
         */
        if ((efState & readNotification) && write(data, count)) {
            result = true;
            break;
        }
    }

    if (result && writeNotification != 0) {
        evFlag->wake(writeNotification);
    }

    return result;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::writeBlocking(const T* data, size_t count,
                                                                  int64_t timeOutNanos) {
    return writeBlocking(data, count, FMQ_NOT_FULL, FMQ_NOT_EMPTY, timeOutNanos);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::readBlocking(
        T* data, size_t count, uint32_t readNotification, uint32_t writeNotification,
        int64_t timeOutNanos, android::hardware::EventFlag* evFlag) {
    static_assert(flavor == kSynchronizedReadWrite,
                  "readBlocking can only be used with the "
                  "kSynchronizedReadWrite flavor.");

    /*
     * If evFlag is null and the FMQ does not own its own EventFlag object
     * return false;
     * If the writeNotification bit mask is zero return false;
     * If the count is greater than queue size, return false to prevent
     * blocking until timeOut.
     */
    if (evFlag == nullptr) {
        evFlag = mEventFlag;
        if (evFlag == nullptr) {
            hardware::details::logError(
                    "readBlocking failed: called on MessageQueue with no Eventflag"
                    "configured or provided");
            return false;
        }
    }

    if (writeNotification == 0 || count > getQuantumCount()) {
        return false;
    }

    /*
     * There is no need to wait for a write notification if sufficient
     * data to read is already present in the FMQ. This would be the
     * case when read operations read lesser number of messages than
     * a write operation and multiple reads would be required to clear the queue
     * after a single write operation. This check would fail to clear a pending
     * writeNotification bit since EventFlag bits can only be cleared
     * by a wait() call, however the bit would be correctly cleared by the next
     * readBlocking() call.
     */

    bool result = read(data, count);
    if (result) {
        if (readNotification) {
            evFlag->wake(readNotification);
        }
        return result;
    }

    bool shouldTimeOut = timeOutNanos != 0;
    int64_t prevTimeNanos = shouldTimeOut ? android::elapsedRealtimeNano() : 0;

    while (true) {
        /* It is not required to adjust 'timeOutNanos' if 'shouldTimeOut' is false */
        if (shouldTimeOut) {
            /*
             * The current time and 'prevTimeNanos' are both CLOCK_BOOTTIME clock values(converted
             * to Nanoseconds)
             */
            int64_t currentTimeNs = android::elapsedRealtimeNano();
            /*
             * Decrement 'timeOutNanos' to account for the time taken to complete the last
             * iteration of the while loop.
             */
            timeOutNanos -= currentTimeNs - prevTimeNanos;
            prevTimeNanos = currentTimeNs;

            if (timeOutNanos <= 0) {
                /*
                 * Attempt read in case a context switch happened outside of
                 * evFlag->wait().
                 */
                result = read(data, count);
                break;
            }
        }

        /*
         * wait() will return immediately if there was a pending write
         * notification.
         */
        uint32_t efState = 0;
        status_t status = evFlag->wait(writeNotification, &efState, timeOutNanos,
                                       true /* retry on spurious wake */);

        if (status != android::TIMED_OUT && status != android::NO_ERROR) {
            hardware::details::logError("Unexpected error code from EventFlag Wait status " +
                                        std::to_string(status));
            break;
        }

        if (status == android::TIMED_OUT) {
            break;
        }

        /*
         * If the data in FMQ is still insufficient, go back to waiting
         * for another write notification.
         */
        if ((efState & writeNotification) && read(data, count)) {
            result = true;
            break;
        }
    }

    if (result && readNotification != 0) {
        evFlag->wake(readNotification);
    }
    return result;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::readBlocking(T* data, size_t count,
                                                                 int64_t timeOutNanos) {
    return readBlocking(data, count, FMQ_NOT_FULL, FMQ_NOT_EMPTY, timeOutNanos);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToWriteBytes() const {
    return mDesc->getSize() - availableToReadBytes();
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToWrite() const {
    return availableToWriteBytes() / sizeof(T);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToRead() const {
    return availableToReadBytes() / sizeof(T);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::beginWrite(size_t nMessages,
                                                               MemTransaction* result) const {
    /*
     * If nMessages is greater than size of FMQ or in case of the synchronized
     * FMQ flavor, if there is not enough space to write nMessages, then return
     * result with null addresses.
     */
    if ((flavor == kSynchronizedReadWrite && (availableToWrite() < nMessages)) ||
        nMessages > getQuantumCount()) {
        *result = MemTransaction();
        return false;
    }

    auto writePtr = mWritePtr->load(std::memory_order_relaxed);
    if (writePtr % sizeof(T) != 0) {
        hardware::details::logError(
                "The write pointer has become misaligned. Writing to the queue is no longer "
                "possible.");
        hardware::details::errorWriteLog(0x534e4554, "184963385");
        return false;
    }
    size_t writeOffset = writePtr % mDesc->getSize();

    /*
     * From writeOffset, the number of messages that can be written
     * contiguously without wrapping around the ring buffer are calculated.
     */
    size_t contiguousMessages = (mDesc->getSize() - writeOffset) / sizeof(T);

    if (contiguousMessages < nMessages) {
        /*
         * Wrap around is required. Both result.first and result.second are
         * populated.
         */
        *result = MemTransaction(
                MemRegion(reinterpret_cast<T*>(mRing + writeOffset), contiguousMessages),
                MemRegion(reinterpret_cast<T*>(mRing), nMessages - contiguousMessages));
    } else {
        /*
         * A wrap around is not required to write nMessages. Only result.first
         * is populated.
         */
        *result = MemTransaction(MemRegion(reinterpret_cast<T*>(mRing + writeOffset), nMessages),
                                 MemRegion());
    }

    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
/*
 * Disable integer sanitization since integer overflow here is allowed
 * and legal.
 */
__attribute__((no_sanitize("integer"))) bool
MessageQueueBase<MQDescriptorType, T, flavor>::commitWrite(size_t nMessages) {
    size_t nBytesWritten = nMessages * sizeof(T);
    auto writePtr = mWritePtr->load(std::memory_order_relaxed);
    writePtr += nBytesWritten;
    mWritePtr->store(writePtr, std::memory_order_release);
    /*
     * This method cannot fail now since we are only incrementing the writePtr
     * counter.
     */
    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToReadBytes() const {
    /*
     * This method is invoked by implementations of both read() and write() and
     * hence requires a memory_order_acquired load for both mReadPtr and
     * mWritePtr.
     */
    return mWritePtr->load(std::memory_order_acquire) - mReadPtr->load(std::memory_order_acquire);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::read(T* data, size_t nMessages) {
    MemTransaction tx;
    return beginRead(nMessages, &tx) && tx.copyFrom(data, 0 /* startIdx */, nMessages) &&
           commitRead(nMessages);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
/*
 * Disable integer sanitization since integer overflow here is allowed
 * and legal.
 */
__attribute__((no_sanitize("integer"))) bool
MessageQueueBase<MQDescriptorType, T, flavor>::beginRead(size_t nMessages,
                                                         MemTransaction* result) const {
    *result = MemTransaction();
    /*
     * If it is detected that the data in the queue was overwritten
     * due to the reader process being too slow, the read pointer counter
     * is set to the same as the write pointer counter to indicate error
     * and the read returns false;
     * Need acquire/release memory ordering for mWritePtr.
     */
    auto writePtr = mWritePtr->load(std::memory_order_acquire);
    /*
     * A relaxed load is sufficient for mReadPtr since there will be no
     * stores to mReadPtr from a different thread.
     */
    auto readPtr = mReadPtr->load(std::memory_order_relaxed);
    if (writePtr % sizeof(T) != 0 || readPtr % sizeof(T) != 0) {
        hardware::details::logError(
                "The write or read pointer has become misaligned. Reading from the queue is no "
                "longer possible.");
        hardware::details::errorWriteLog(0x534e4554, "184963385");
        return false;
    }

    if (writePtr - readPtr > mDesc->getSize()) {
        mReadPtr->store(writePtr, std::memory_order_release);
        return false;
    }

    size_t nBytesDesired = nMessages * sizeof(T);
    /*
     * Return if insufficient data to read in FMQ.
     */
    if (writePtr - readPtr < nBytesDesired) {
        return false;
    }

    size_t readOffset = readPtr % mDesc->getSize();
    /*
     * From readOffset, the number of messages that can be read contiguously
     * without wrapping around the ring buffer are calculated.
     */
    size_t contiguousMessages = (mDesc->getSize() - readOffset) / sizeof(T);

    if (contiguousMessages < nMessages) {
        /*
         * A wrap around is required. Both result.first and result.second
         * are populated.
         */
        *result = MemTransaction(
                MemRegion(reinterpret_cast<T*>(mRing + readOffset), contiguousMessages),
                MemRegion(reinterpret_cast<T*>(mRing), nMessages - contiguousMessages));
    } else {
        /*
         * A wrap around is not required. Only result.first need to be
         * populated.
         */
        *result = MemTransaction(MemRegion(reinterpret_cast<T*>(mRing + readOffset), nMessages),
                                 MemRegion());
    }

    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
/*
 * Disable integer sanitization since integer overflow here is allowed
 * and legal.
 */
__attribute__((no_sanitize("integer"))) bool
MessageQueueBase<MQDescriptorType, T, flavor>::commitRead(size_t nMessages) {
    // TODO: Use a local copy of readPtr to avoid relazed mReadPtr loads.
    auto readPtr = mReadPtr->load(std::memory_order_relaxed);
    auto writePtr = mWritePtr->load(std::memory_order_acquire);
    /*
     * If the flavor is unsynchronized, it is possible that a write overflow may
     * have occurred between beginRead() and commitRead().
     */
    if (writePtr - readPtr > mDesc->getSize()) {
        mReadPtr->store(writePtr, std::memory_order_release);
        return false;
    }

    size_t nBytesRead = nMessages * sizeof(T);
    readPtr += nBytesRead;
    mReadPtr->store(readPtr, std::memory_order_release);
    return true;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::getQuantumSize() const {
    return mDesc->getQuantum();
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
size_t MessageQueueBase<MQDescriptorType, T, flavor>::getQuantumCount() const {
    return mDesc->getSize() / mDesc->getQuantum();
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
bool MessageQueueBase<MQDescriptorType, T, flavor>::isValid() const {
    return mRing != nullptr && mReadPtr != nullptr && mWritePtr != nullptr;
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
void* MessageQueueBase<MQDescriptorType, T, flavor>::mapGrantorDescr(uint32_t grantorIdx) {
    const native_handle_t* handle = mDesc->handle();
    auto grantors = mDesc->grantors();
    if (handle == nullptr) {
        hardware::details::logError("mDesc->handle is null");
        return nullptr;
    }

    if (grantorIdx >= grantors.size()) {
        hardware::details::logError(std::string("grantorIdx must be less than ") +
                                    std::to_string(grantors.size()));
        return nullptr;
    }

    int fdIndex = grantors[grantorIdx].fdIndex;
    /*
     * Offset for mmap must be a multiple of PAGE_SIZE.
     */
    int mapOffset = (grantors[grantorIdx].offset / PAGE_SIZE) * PAGE_SIZE;
    int mapLength = grantors[grantorIdx].offset - mapOffset + grantors[grantorIdx].extent;

    void* address = mmap(0, mapLength, PROT_READ | PROT_WRITE, MAP_SHARED, handle->data[fdIndex],
                         mapOffset);
    if (address == MAP_FAILED) {
        hardware::details::logError(std::string("mmap failed: ") + std::to_string(errno));
        return nullptr;
    }
    return reinterpret_cast<uint8_t*>(address) + (grantors[grantorIdx].offset - mapOffset);
}

template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor>
void MessageQueueBase<MQDescriptorType, T, flavor>::unmapGrantorDescr(void* address,
                                                                      uint32_t grantorIdx) {
    auto grantors = mDesc->grantors();
    if ((address == nullptr) || (grantorIdx >= grantors.size())) {
        return;
    }

    int mapOffset = (grantors[grantorIdx].offset / PAGE_SIZE) * PAGE_SIZE;
    int mapLength = grantors[grantorIdx].offset - mapOffset + grantors[grantorIdx].extent;
    void* baseAddress =
            reinterpret_cast<uint8_t*>(address) - (grantors[grantorIdx].offset - mapOffset);
    if (baseAddress) munmap(baseAddress, mapLength);
}

}  // namespace hardware
