diff --git a/Android.bp b/Android.bp
index e2cb961..5889a9c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library {
     name: "libfmq",
     shared_libs: [
@@ -31,6 +35,12 @@
     ],
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
+    header_libs: [
+        "libfmq-base",
+    ],
+    export_header_lib_headers: [
+        "libfmq-base",
+    ],
     srcs: [
         "EventFlag.cpp",
         "FmqInternal.cpp",
@@ -40,6 +50,7 @@
         "-Werror",
     ],
     vendor_available: true,
+    product_available: true,
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
     vndk: {
@@ -47,4 +58,21 @@
     },
     double_loadable: true,
     min_sdk_version: "29",
+    host_supported: true,
+}
+
+// Header only lib to share type between HIDL and AIDL MQDescriptor
+cc_library_headers {
+    name: "libfmq-base",
+    host_supported: true,
+    vendor_available: true,
+    product_available: true,
+    native_bridge_supported: true,
+    recovery_available: true,
+    apex_available: [
+        "//apex_available:anyapex",
+        "//apex_available:platform",
+    ],
+    export_include_dirs: ["base"],
+    min_sdk_version: "29",
 }
diff --git a/EventFlag.cpp b/EventFlag.cpp
index cb101bd..96f9519 100644
--- a/EventFlag.cpp
+++ b/EventFlag.cpp
@@ -22,6 +22,7 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
+#include <limits>
 #include <new>
 
 #include <fmq/EventFlag.h>
@@ -120,9 +121,9 @@
      * No need to call FUTEX_WAKE_BITSET if there were deferred wakes
      * already available for all set bits from bitmask.
      */
+    constexpr size_t kIntMax = std::numeric_limits<int>::max();
     if ((~old & bitmask) != 0) {
-        int ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAKE_BITSET,
-                          INT_MAX, NULL, NULL, bitmask);
+        int ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAKE_BITSET, kIntMax, NULL, NULL, bitmask);
         if (ret == -1) {
             status = -errno;
             ALOGE("Error in event flag wake attempt: %s\n", strerror(errno));
diff --git a/FmqInternal.cpp b/FmqInternal.cpp
index 6b95def..886d155 100644
--- a/FmqInternal.cpp
+++ b/FmqInternal.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "FMQ"
 #include <android-base/logging.h>
+#include <utils/Log.h>
 
 namespace android {
 namespace hardware {
@@ -29,6 +30,10 @@
     LOG(ERROR) << message;
 }
 
+void errorWriteLog(int tag, const char* info) {
+    android_errorWriteLog(tag, info);
+}
+
 }  // namespace details
 }  // namespace hardware
 }  // namespace android
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 213c93a..18b0a1b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -3,3 +3,4 @@
 
 [Builtin Hooks]
 clang_format = true
+bpfmt = true
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..dfa7071
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "fmq_unit_tests"
+    },
+    {
+      "name": "fmq_test"
+    }
+  ]
+}
diff --git a/base/fmq/MQDescriptorBase.h b/base/fmq/MQDescriptorBase.h
new file mode 100644
index 0000000..0d18d4c
--- /dev/null
+++ b/base/fmq/MQDescriptorBase.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 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 <assert.h>
+#include <string>
+
+namespace android {
+namespace hardware {
+
+enum MQFlavor : uint32_t {
+    /*
+     * kSynchronizedReadWrite represents the wait-free synchronized flavor of the
+     * FMQ. It is intended to be have a single reader and single writer.
+     * Attempts to overflow/underflow returns a failure.
+     */
+    kSynchronizedReadWrite = 0x01,
+    /*
+     * kUnsynchronizedWrite represents the flavor of FMQ where writes always
+     * succeed. This flavor allows one writer and many readers. A read operation
+     * can detect an overwrite and reset the read counter.
+     */
+    kUnsynchronizedWrite = 0x02
+};
+
+struct GrantorDescriptor {
+    uint32_t flags __attribute__((aligned(4)));
+    uint32_t fdIndex __attribute__((aligned(4)));
+    uint32_t offset __attribute__((aligned(4)));
+    uint64_t extent __attribute__((aligned(8)));
+};
+
+static_assert(offsetof(GrantorDescriptor, flags) == 0, "wrong offset");
+static_assert(offsetof(GrantorDescriptor, fdIndex) == 4, "wrong offset");
+static_assert(offsetof(GrantorDescriptor, offset) == 8, "wrong offset");
+static_assert(offsetof(GrantorDescriptor, extent) == 16, "wrong offset");
+static_assert(sizeof(GrantorDescriptor) == 24, "wrong size");
+static_assert(__alignof(GrantorDescriptor) == 8, "wrong alignment");
+
+namespace details {
+
+void logError(const std::string& message);
+void errorWriteLog(int tag, const char* message);
+
+typedef uint64_t RingBufferPosition;
+enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS };
+/*
+ * There should at least be GrantorDescriptors for the read counter, write
+ * counter and data buffer. A GrantorDescriptor for an EventFlag word is
+ * not required if there is no need for blocking FMQ operations.
+ */
+static constexpr int32_t kMinGrantorCount = DATAPTRPOS + 1;
+
+/*
+ * Minimum number of GrantorDescriptors required if EventFlag support is
+ * needed for blocking FMQ operations.
+ */
+static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1;
+
+static inline size_t alignToWordBoundary(size_t length) {
+    constexpr size_t kAlignmentSize = 64;
+    if (kAlignmentSize % __WORDSIZE != 0) {
+#ifdef __BIONIC__
+        __assert(__FILE__, __LINE__, "Incompatible word size");
+#endif
+    }
+
+    /*
+     * Check if alignment to word boundary would cause an overflow.
+     */
+    if (length > SIZE_MAX - kAlignmentSize / 8 + 1) {
+#ifdef __BIONIC__
+        __assert(__FILE__, __LINE__, "Queue size too large");
+#endif
+    }
+
+    return (length + kAlignmentSize / 8 - 1) & ~(kAlignmentSize / 8 - 1U);
+}
+
+static inline size_t isAlignedToWordBoundary(size_t offset) {
+    constexpr size_t kAlignmentSize = 64;
+    return (offset & (kAlignmentSize / 8 - 1)) == 0;
+}
+
+}  // namespace details
+}  // namespace hardware
+}  // namespace android
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index d82c0a3..3cae117 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -31,10 +31,11 @@
 LOCAL_REQUIRED_MODULES := android.hardware.tests.msgq@1.0-impl
 
 ifneq ($(TARGET_2ND_ARCH),)
-LOCAL_REQUIRED_MODULES += android.hardware.tests.msgq@1.0-impl$(TARGET_2ND_ARCH_MODULE_SUFFIX)
+LOCAL_REQUIRED_MODULES += android.hardware.tests.msgq@1.0-impl:32
 endif
 
 LOCAL_SHARED_LIBRARIES += android.hardware.tests.msgq@1.0 libfmq
 LOCAL_MODULE := mq_benchmark_client
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 include $(BUILD_NATIVE_TEST)
-
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..6b41e3f
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,66 @@
+// Copyright (C) 2021 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_fuzz {
+    name: "fmq_fuzzer",
+
+    defaults: [
+        "libbinder_ndk_host_user",
+    ],
+
+    srcs: [
+        "fmq_fuzzer.cpp",
+    ],
+
+    static_libs: [
+        "libfmq",
+        "android.hardware.common.fmq-V1-ndk_platform",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "devinmoore@google.com",
+            "smoreland@google.com",
+        ],
+        componentid: 655781,
+        libfuzzer_options: [
+            "max_len=50000",
+        ],
+    },
+
+    host_supported: true,
+
+    sanitize: {
+        hwaddress: true,
+        scs: true,
+        cfi: true,
+        memtag_heap: true,
+        // undefined behavior is expected
+        all_undefined: false,
+        // integer overflow is expected
+        integer_overflow: false,
+    },
+}
diff --git a/fuzzer/fmq_fuzzer.cpp b/fuzzer/fmq_fuzzer.cpp
new file mode 100644
index 0000000..844188f
--- /dev/null
+++ b/fuzzer/fmq_fuzzer.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 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 <stddef.h>
+#include <stdint.h>
+#include <iostream>
+#include <limits>
+#include <thread>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/ConvertMQDescriptors.h>
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
+
+#include "fuzzer/FuzzedDataProvider.h"
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::kUnsynchronizedWrite;
+
+typedef int32_t payload_t;
+
+/*
+ * MessageQueueBase.h contains asserts when memory allocation fails. So we need
+ * to set a reasonable limit if we want to avoid those asserts.
+ */
+static constexpr size_t kAlignment = 8;
+static constexpr size_t kMaxNumElements = PAGE_SIZE * 10 / sizeof(payload_t) - kAlignment + 1;
+
+/*
+ * The read counter can be found in the shared memory 16 bytes before the start
+ * of the ring buffer.
+ */
+static constexpr int kReadCounterOffsetBytes = 16;
+/*
+ * The write counter can be found in the shared memory 8 bytes before the start
+ * of the ring buffer.
+ */
+static constexpr int kWriteCounterOffsetBytes = 8;
+
+static constexpr int kMaxNumSyncReaders = 1;
+static constexpr int kMaxNumUnsyncReaders = 5;
+
+typedef android::AidlMessageQueue<payload_t, SynchronizedReadWrite> AidlMessageQueueSync;
+typedef android::AidlMessageQueue<payload_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
+typedef android::hardware::MessageQueue<payload_t, kSynchronizedReadWrite> MessageQueueSync;
+typedef android::hardware::MessageQueue<payload_t, kUnsynchronizedWrite> MessageQueueUnsync;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<payload_t, SynchronizedReadWrite>
+        AidlMQDescSync;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<payload_t, UnsynchronizedWrite>
+        AidlMQDescUnsync;
+typedef android::hardware::MQDescriptorSync<payload_t> MQDescSync;
+typedef android::hardware::MQDescriptorUnsync<payload_t> MQDescUnsync;
+
+template <typename Queue, typename Desc>
+void reader(const Desc& desc, std::vector<uint8_t> readerData) {
+    Queue readMq(desc);
+    if (!readMq.isValid()) {
+        LOG(ERROR) << "read mq invalid";
+        return;
+    }
+    FuzzedDataProvider fdp(&readerData[0], readerData.size());
+    while (fdp.remaining_bytes()) {
+        typename Queue::MemTransaction tx;
+        size_t numElements = fdp.ConsumeIntegralInRange<size_t>(0, kMaxNumElements);
+        if (!readMq.beginRead(numElements, &tx)) {
+            continue;
+        }
+        const auto& region = tx.getFirstRegion();
+        payload_t* firstStart = region.getAddress();
+
+        // TODO add the debug function to get pointer to the ring buffer
+        uint64_t* writeCounter = reinterpret_cast<uint64_t*>(
+                reinterpret_cast<uint8_t*>(firstStart) - kWriteCounterOffsetBytes);
+        *writeCounter = fdp.ConsumeIntegral<uint64_t>();
+
+        (void)std::to_string(*firstStart);
+
+        readMq.commitRead(numElements);
+    }
+}
+
+template <typename Queue>
+void writer(Queue& writeMq, FuzzedDataProvider& fdp) {
+    while (fdp.remaining_bytes()) {
+        typename Queue::MemTransaction tx;
+        size_t numElements = 1;
+        if (!writeMq.beginWrite(numElements, &tx)) {
+            // need to consume something so we don't end up looping forever
+            fdp.ConsumeIntegral<uint8_t>();
+            continue;
+        }
+
+        const auto& region = tx.getFirstRegion();
+        payload_t* firstStart = region.getAddress();
+
+        // TODO add the debug function to get pointer to the ring buffer
+        uint64_t* readCounter = reinterpret_cast<uint64_t*>(reinterpret_cast<uint8_t*>(firstStart) -
+                                                            kReadCounterOffsetBytes);
+        *readCounter = fdp.ConsumeIntegral<uint64_t>();
+
+        *firstStart = fdp.ConsumeIntegral<payload_t>();
+
+        writeMq.commitWrite(numElements);
+    }
+}
+
+template <typename Queue, typename Desc>
+void fuzzAidlWithReaders(std::vector<uint8_t>& writerData,
+                         std::vector<std::vector<uint8_t>>& readerData) {
+    FuzzedDataProvider fdp(&writerData[0], writerData.size());
+    Queue writeMq(fdp.ConsumeIntegralInRange<size_t>(1, kMaxNumElements), fdp.ConsumeBool());
+    if (!writeMq.isValid()) {
+        LOG(ERROR) << "AIDL write mq invalid";
+        return;
+    }
+    const auto desc = writeMq.dupeDesc();
+    CHECK(desc.handle.fds[0].get() != -1);
+
+    std::vector<std::thread> clients;
+    for (int i = 0; i < readerData.size(); i++) {
+        clients.emplace_back(reader<Queue, Desc>, std::ref(desc), std::ref(readerData[i]));
+    }
+
+    writer<Queue>(writeMq, fdp);
+
+    for (auto& client : clients) {
+        client.join();
+    }
+}
+
+template <typename Queue, typename Desc>
+void fuzzHidlWithReaders(std::vector<uint8_t>& writerData,
+                         std::vector<std::vector<uint8_t>>& readerData) {
+    FuzzedDataProvider fdp(&writerData[0], writerData.size());
+    Queue writeMq(fdp.ConsumeIntegralInRange<size_t>(1, kMaxNumElements), fdp.ConsumeBool());
+    if (!writeMq.isValid()) {
+        LOG(ERROR) << "HIDL write mq invalid";
+        return;
+    }
+    const auto desc = writeMq.getDesc();
+    CHECK(desc->isHandleValid());
+
+    std::vector<std::thread> clients;
+    for (int i = 0; i < readerData.size(); i++) {
+        clients.emplace_back(reader<Queue, Desc>, std::ref(*desc), std::ref(readerData[i]));
+    }
+
+    writer<Queue>(writeMq, fdp);
+
+    for (auto& client : clients) {
+        client.join();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < 1 || size > 50000) {
+        return 0;
+    }
+    FuzzedDataProvider fdp(data, size);
+
+    bool fuzzSync = fdp.ConsumeBool();
+    std::vector<std::vector<uint8_t>> readerData;
+    uint8_t numReaders = fuzzSync ? fdp.ConsumeIntegralInRange<uint8_t>(0, kMaxNumSyncReaders)
+                                  : fdp.ConsumeIntegralInRange<uint8_t>(0, kMaxNumUnsyncReaders);
+    for (int i = 0; i < numReaders; i++) {
+        readerData.emplace_back(fdp.ConsumeBytes<uint8_t>(5));
+    }
+    std::vector<uint8_t> writerData = fdp.ConsumeRemainingBytes<uint8_t>();
+
+    if (fuzzSync) {
+        fuzzHidlWithReaders<MessageQueueSync, MQDescSync>(writerData, readerData);
+        fuzzAidlWithReaders<AidlMessageQueueSync, AidlMQDescSync>(writerData, readerData);
+    } else {
+        fuzzHidlWithReaders<MessageQueueUnsync, MQDescUnsync>(writerData, readerData);
+        fuzzAidlWithReaders<AidlMessageQueueUnsync, AidlMQDescUnsync>(writerData, readerData);
+    }
+
+    return 0;
+}
diff --git a/include/fmq/AidlMQDescriptorShim.h b/include/fmq/AidlMQDescriptorShim.h
new file mode 100644
index 0000000..e3d3cb9
--- /dev/null
+++ b/include/fmq/AidlMQDescriptorShim.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2020 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 <aidl/android/hardware/common/fmq/MQDescriptor.h>
+#include <cutils/native_handle.h>
+#include <fmq/MQDescriptorBase.h>
+#include <limits>
+#include <type_traits>
+
+namespace android {
+namespace details {
+
+using aidl::android::hardware::common::fmq::GrantorDescriptor;
+using aidl::android::hardware::common::fmq::MQDescriptor;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using android::hardware::MQFlavor;
+
+template <typename T, MQFlavor flavor>
+struct AidlMQDescriptorShim {
+    // Takes ownership of handle
+    AidlMQDescriptorShim(const std::vector<android::hardware::GrantorDescriptor>& grantors,
+                         native_handle_t* nHandle, size_t size);
+
+    // Takes ownership of handle
+    AidlMQDescriptorShim(
+            const MQDescriptor<
+                    T, typename std::conditional<flavor == hardware::kSynchronizedReadWrite,
+                                                 SynchronizedReadWrite, UnsynchronizedWrite>::type>&
+                    desc);
+
+    // Takes ownership of handle
+    AidlMQDescriptorShim(size_t bufferSize, native_handle_t* nHandle, size_t messageSize,
+                         bool configureEventFlag = false);
+
+    explicit AidlMQDescriptorShim(const AidlMQDescriptorShim& other)
+        : AidlMQDescriptorShim(0, nullptr, 0) {
+        *this = other;
+    }
+    AidlMQDescriptorShim& operator=(const AidlMQDescriptorShim& other);
+
+    ~AidlMQDescriptorShim();
+
+    size_t getSize() const;
+
+    size_t getQuantum() const;
+
+    uint32_t getFlags() const;
+
+    bool isHandleValid() const { return mHandle != nullptr; }
+    size_t countGrantors() const { return mGrantors.size(); }
+
+    inline const std::vector<android::hardware::GrantorDescriptor>& grantors() const {
+        return mGrantors;
+    }
+
+    inline const ::native_handle_t* handle() const { return mHandle; }
+
+    inline ::native_handle_t* handle() { return mHandle; }
+
+    static const size_t kOffsetOfGrantors;
+    static const size_t kOffsetOfHandle;
+
+  private:
+    std::vector<android::hardware::GrantorDescriptor> mGrantors;
+    native_handle_t* mHandle = nullptr;
+    uint32_t mQuantum = 0;
+    uint32_t mFlags = 0;
+};
+
+template <typename T, MQFlavor flavor>
+AidlMQDescriptorShim<T, flavor>::AidlMQDescriptorShim(
+        const MQDescriptor<T, typename std::conditional<flavor == hardware::kSynchronizedReadWrite,
+                                                        SynchronizedReadWrite,
+                                                        UnsynchronizedWrite>::type>& desc)
+    : mQuantum(desc.quantum), mFlags(desc.flags) {
+    if (desc.quantum < 0 || desc.flags < 0) {
+        // MQDescriptor uses signed integers, but the values must be positive.
+        hardware::details::logError("Invalid MQDescriptor. Values must be positive. quantum: " +
+                                    std::to_string(desc.quantum) +
+                                    ". flags: " + std::to_string(desc.flags));
+        return;
+    }
+
+    mGrantors.resize(desc.grantors.size());
+    for (size_t i = 0; i < desc.grantors.size(); ++i) {
+        if (desc.grantors[i].offset < 0 || desc.grantors[i].extent < 0 ||
+            desc.grantors[i].fdIndex < 0) {
+            // GrantorDescriptor uses signed integers, but the values must be positive.
+            // Return before setting up the native_handle to make this invalid.
+            hardware::details::logError(
+                    "Invalid MQDescriptor grantors. Values must be positive. Grantor index: " +
+                    std::to_string(i) + ". offset: " + std::to_string(desc.grantors[i].offset) +
+                    ". extent: " + std::to_string(desc.grantors[i].extent));
+            return;
+        }
+        mGrantors[i].flags = 0;
+        mGrantors[i].fdIndex = desc.grantors[i].fdIndex;
+        mGrantors[i].offset = desc.grantors[i].offset;
+        mGrantors[i].extent = desc.grantors[i].extent;
+    }
+
+    mHandle = native_handle_create(desc.handle.fds.size() /* num fds */,
+                                   desc.handle.ints.size() /* num ints */);
+    if (mHandle == nullptr) {
+        hardware::details::logError("Null native_handle_t");
+        return;
+    }
+    int data_index = 0;
+    for (const auto& fd : desc.handle.fds) {
+        mHandle->data[data_index] = dup(fd.get());
+        data_index++;
+    }
+    for (const auto& data_int : desc.handle.ints) {
+        mHandle->data[data_index] = data_int;
+        data_index++;
+    }
+}
+
+template <typename T, MQFlavor flavor>
+AidlMQDescriptorShim<T, flavor>::AidlMQDescriptorShim(
+        const std::vector<android::hardware::GrantorDescriptor>& grantors, native_handle_t* nhandle,
+        size_t size)
+    : mGrantors(grantors),
+      mHandle(nhandle),
+      mQuantum(static_cast<uint32_t>(size)),
+      mFlags(flavor) {}
+
+template <typename T, MQFlavor flavor>
+AidlMQDescriptorShim<T, flavor>& AidlMQDescriptorShim<T, flavor>::operator=(
+        const AidlMQDescriptorShim& other) {
+    mGrantors = other.mGrantors;
+    if (mHandle != nullptr) {
+        native_handle_close(mHandle);
+        native_handle_delete(mHandle);
+        mHandle = nullptr;
+    }
+    mQuantum = other.mQuantum;
+    mFlags = other.mFlags;
+
+    if (other.mHandle != nullptr) {
+        mHandle = native_handle_create(other.mHandle->numFds, other.mHandle->numInts);
+
+        for (int i = 0; i < other.mHandle->numFds; ++i) {
+            mHandle->data[i] = dup(other.mHandle->data[i]);
+        }
+
+        memcpy(&mHandle->data[other.mHandle->numFds], &other.mHandle->data[other.mHandle->numFds],
+               static_cast<size_t>(other.mHandle->numInts) * sizeof(int));
+    }
+
+    return *this;
+}
+
+template <typename T, MQFlavor flavor>
+AidlMQDescriptorShim<T, flavor>::AidlMQDescriptorShim(size_t bufferSize, native_handle_t* nHandle,
+                                                      size_t messageSize, bool configureEventFlag)
+    : mHandle(nHandle), mQuantum(messageSize), mFlags(flavor) {
+    /*
+     * TODO(b/165674950) Since AIDL does not support unsigned integers, it can only support
+     * The offset of EventFlag word needs to fit into an int32_t in MQDescriptor. This word comes
+     * after the readPtr, writePtr, and dataBuffer.
+     */
+    bool overflow = bufferSize > std::numeric_limits<uint64_t>::max() -
+                                         (sizeof(hardware::details::RingBufferPosition) +
+                                          sizeof(hardware::details::RingBufferPosition));
+    uint64_t largestOffset = hardware::details::alignToWordBoundary(
+            sizeof(hardware::details::RingBufferPosition) +
+            sizeof(hardware::details::RingBufferPosition) + bufferSize);
+    if (overflow || largestOffset > std::numeric_limits<int32_t>::max() ||
+        messageSize > std::numeric_limits<int32_t>::max()) {
+        hardware::details::logError(
+                "Queue size is too large. Message size: " + std::to_string(messageSize) +
+                " bytes. Data buffer size: " + std::to_string(bufferSize) + " bytes. Max size: " +
+                std::to_string(std::numeric_limits<int32_t>::max()) + " bytes.");
+        return;
+    }
+
+    /*
+     * If configureEventFlag is true, allocate an additional spot in mGrantor
+     * for containing the fd and offset for mmapping the EventFlag word.
+     */
+    mGrantors.resize(configureEventFlag ? 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 */
+            bufferSize,                   /* memory to be allocated for data buffer */
+            sizeof(std::atomic<uint32_t>) /* memory to be allocated for EventFlag word */
+    };
+
+    /*
+     * Create a default grantor descriptor for read, write pointers and
+     * the data buffer. fdIndex parameter is set to 0 by default and
+     * the offset for each grantor is contiguous.
+     */
+    for (size_t grantorPos = 0, offset = 0; grantorPos < mGrantors.size();
+         offset += memSize[grantorPos++]) {
+        mGrantors[grantorPos] = {
+                0 /* grantor flags */, 0 /* fdIndex */,
+                static_cast<uint32_t>(hardware::details::alignToWordBoundary(offset)),
+                memSize[grantorPos]};
+    }
+}
+
+template <typename T, MQFlavor flavor>
+AidlMQDescriptorShim<T, flavor>::~AidlMQDescriptorShim() {
+    if (mHandle != nullptr) {
+        native_handle_close(mHandle);
+        native_handle_delete(mHandle);
+    }
+}
+
+template <typename T, MQFlavor flavor>
+size_t AidlMQDescriptorShim<T, flavor>::getSize() const {
+    return mGrantors[hardware::details::DATAPTRPOS].extent;
+}
+
+template <typename T, MQFlavor flavor>
+size_t AidlMQDescriptorShim<T, flavor>::getQuantum() const {
+    return mQuantum;
+}
+
+template <typename T, MQFlavor flavor>
+uint32_t AidlMQDescriptorShim<T, flavor>::getFlags() const {
+    return mFlags;
+}
+
+template <typename T, MQFlavor flavor>
+std::string toString(const AidlMQDescriptorShim<T, flavor>& q) {
+    std::string os;
+    if (flavor & hardware::kSynchronizedReadWrite) {
+        os += "fmq_sync";
+    }
+    if (flavor & hardware::kUnsynchronizedWrite) {
+        os += "fmq_unsync";
+    }
+    os += " {" + toString(q.grantors().size()) + " grantor(s), " +
+          "size = " + toString(q.getSize()) + ", .handle = " + toString(q.handle()) +
+          ", .quantum = " + toString(q.getQuantum()) + "}";
+    return os;
+}
+
+}  // namespace details
+}  // namespace android
diff --git a/include/fmq/AidlMessageQueue.h b/include/fmq/AidlMessageQueue.h
new file mode 100644
index 0000000..0536d6a
--- /dev/null
+++ b/include/fmq/AidlMessageQueue.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2020 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 <aidl/android/hardware/common/fmq/MQDescriptor.h>
+#include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
+#include <aidl/android/hardware/common/fmq/UnsynchronizedWrite.h>
+#include <cutils/native_handle.h>
+#include <fmq/AidlMQDescriptorShim.h>
+#include <fmq/MessageQueueBase.h>
+#include <utils/Log.h>
+#include <type_traits>
+
+namespace android {
+
+using aidl::android::hardware::common::fmq::MQDescriptor;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using android::details::AidlMQDescriptorShim;
+using android::hardware::MQFlavor;
+
+template <typename T>
+struct FlavorTypeToValue;
+
+template <>
+struct FlavorTypeToValue<SynchronizedReadWrite> {
+    static constexpr MQFlavor value = hardware::kSynchronizedReadWrite;
+};
+
+template <>
+struct FlavorTypeToValue<UnsynchronizedWrite> {
+    static constexpr MQFlavor value = hardware::kUnsynchronizedWrite;
+};
+
+typedef uint64_t RingBufferPosition;
+
+/*
+ * AIDL parcelables will have the typedef fixed_size. It is std::true_type when the
+ * parcelable is annotated with @FixedSize, and std::false_type when not. Other types
+ * should not have the fixed_size typedef, so they will always resolve to std::false_type.
+ */
+template <typename T, typename = void>
+struct has_typedef_fixed_size : std::false_type {};
+
+template <typename T>
+struct has_typedef_fixed_size<T, std::void_t<typename T::fixed_size>> : T::fixed_size {};
+
+#define STATIC_AIDL_TYPE_CHECK(T)                                                                  \
+    static_assert(has_typedef_fixed_size<T>::value == true || std::is_fundamental<T>::value ||     \
+                          std::is_enum<T>::value,                                                  \
+                  "Only fundamental types, enums, and AIDL parcelables annotated with @FixedSize " \
+                  "and built for the NDK backend are supported as payload types(T).");
+
+template <typename T, typename U>
+struct AidlMessageQueue final
+    : public MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value> {
+    STATIC_AIDL_TYPE_CHECK(T);
+    typedef AidlMQDescriptorShim<T, FlavorTypeToValue<U>::value> Descriptor;
+    /**
+     * This constructor uses the external descriptor used with AIDL interfaces.
+     * It will create an FMQ based on the descriptor that was obtained from
+     * another FMQ instance for communication.
+     *
+     * @param desc Descriptor from another FMQ that contains all of the
+     * information required to create a new instance of that queue.
+     * @param resetPointers Boolean indicating whether the read/write pointers
+     * should be reset or not.
+     */
+    AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers = true);
+    ~AidlMessageQueue() = default;
+
+    /**
+     * 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 AidlMessageQueue 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.
+     */
+    AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
+                     android::base::unique_fd bufferFd, size_t bufferSize);
+
+    AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false)
+        : AidlMessageQueue(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(),
+                           0) {}
+
+    MQDescriptor<T, U> dupeDesc();
+
+  private:
+    AidlMessageQueue(const AidlMessageQueue& other) = delete;
+    AidlMessageQueue& operator=(const AidlMessageQueue& other) = delete;
+    AidlMessageQueue() = delete;
+};
+
+template <typename T, typename U>
+AidlMessageQueue<T, U>::AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers)
+    : MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>(Descriptor(desc),
+                                                                             resetPointers) {}
+
+template <typename T, typename U>
+AidlMessageQueue<T, U>::AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
+                                         android::base::unique_fd bufferFd, size_t bufferSize)
+    : MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>(
+              numElementsInQueue, configureEventFlagWord, std::move(bufferFd), bufferSize) {}
+
+template <typename T, typename U>
+MQDescriptor<T, U> AidlMessageQueue<T, U>::dupeDesc() {
+    auto* shim = MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>::getDesc();
+    if (shim) {
+        std::vector<aidl::android::hardware::common::fmq::GrantorDescriptor> grantors;
+        for (const auto& grantor : shim->grantors()) {
+            grantors.push_back(aidl::android::hardware::common::fmq::GrantorDescriptor{
+                    .fdIndex = static_cast<int32_t>(grantor.fdIndex),
+                    .offset = static_cast<int32_t>(grantor.offset),
+                    .extent = static_cast<int64_t>(grantor.extent)});
+        }
+        std::vector<ndk::ScopedFileDescriptor> fds;
+        std::vector<int> ints;
+        int data_index = 0;
+        for (; data_index < shim->handle()->numFds; data_index++) {
+            fds.push_back(ndk::ScopedFileDescriptor(dup(shim->handle()->data[data_index])));
+        }
+        for (; data_index < shim->handle()->numFds + shim->handle()->numInts; data_index++) {
+            ints.push_back(shim->handle()->data[data_index]);
+        }
+        return MQDescriptor<T, U>{
+                .quantum = static_cast<int32_t>(shim->getQuantum()),
+                .grantors = grantors,
+                .flags = static_cast<int32_t>(shim->getFlags()),
+                .handle = {std::move(fds), std::move(ints)},
+        };
+    } else {
+        return MQDescriptor<T, U>();
+    }
+}
+
+}  // namespace android
diff --git a/include/fmq/ConvertMQDescriptors.h b/include/fmq/ConvertMQDescriptors.h
new file mode 100644
index 0000000..6534ebe
--- /dev/null
+++ b/include/fmq/ConvertMQDescriptors.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2020 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 <aidl/android/hardware/common/fmq/MQDescriptor.h>
+#include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
+#include <aidl/android/hardware/common/fmq/UnsynchronizedWrite.h>
+#include <cutils/native_handle.h>
+#include <fmq/AidlMessageQueue.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+using aidl::android::hardware::common::fmq::GrantorDescriptor;
+using aidl::android::hardware::common::fmq::MQDescriptor;
+using hardware::details::logError;
+
+/**
+ * This function converts a HIDL hardware::MQDescriptor to an AIDL
+ * aidl::android::hardware::common::fmq::MQDescriptor for Fast
+ * Message Queue.
+ *
+ * This is considered UNSAFE because it is not checking the offsets of each of the
+ * paylod types' fields. In order for these objects to be passed through shared memory safely,
+ * they must have the exact same memory layout. Same size, same alignment, and same
+ * offsets for each field. Make sure this is the case before using this!
+ * Same sized C++ fundamental types and enums with same sized backing types are OK.
+ * Ex 1: uint64_t is compatible with int64_t
+ * Ex 2:
+ * @FixedSize parcelable Foo {
+ *   int a;
+ *   long b;
+ *   MyEnum c; // backed by int32_t
+ * }
+ * struct Bar {
+ *   int a;
+ *   long b;
+ *   YourEnum c; // backed by uint32_t
+ * }
+ * The two types above are compatible with each other as long as the fields have
+ * the same offsets.
+ *
+ * Template params:
+ *    HidlPayload - the type of the payload used for the HIDL MessageQueue
+ *    AidlPayload - the type of the payload used for the AIDL AidlMessageQueue
+ *    AidlFlavor - the flavor of the queues. Either SynchronizedReadWrite,
+ *                 or UnsynchronizedWrite
+ * Function params:
+ *    hidlDesc - reference to the HIDL MQDescriptor to be copied from
+ *    aidlDesc - pointer to the AIDL MQDescriptor to be copied to
+ */
+template <typename HidlPayload, typename AidlPayload, typename AidlFlavor>
+bool unsafeHidlToAidlMQDescriptor(
+        const hardware::MQDescriptor<HidlPayload, FlavorTypeToValue<AidlFlavor>::value>& hidlDesc,
+        MQDescriptor<AidlPayload, AidlFlavor>* aidlDesc) {
+    static_assert(sizeof(HidlPayload) == sizeof(AidlPayload),
+                  "Payload types are definitely incompatible");
+    static_assert(alignof(HidlPayload) == alignof(AidlPayload),
+                  "Payload types are definitely incompatible");
+    STATIC_AIDL_TYPE_CHECK(AidlPayload);
+    if (!aidlDesc->grantors.empty()) {
+        logError("Destination AIDL MQDescriptor should be empty, but already contains grantors.");
+        return false;
+    }
+
+    for (const auto& grantor : hidlDesc.grantors()) {
+        if (static_cast<int32_t>(grantor.offset) < 0 || static_cast<int64_t>(grantor.extent) < 0 ||
+            static_cast<int64_t>(grantor.fdIndex) < 0) {
+            logError(
+                    "Unsafe static_cast of grantor fields. Either the hardware::MQDescriptor is "
+                    "invalid, or the MessageQueue is too large to be described by AIDL.");
+            return false;
+        }
+        aidlDesc->grantors.push_back(
+                GrantorDescriptor{.fdIndex = static_cast<int32_t>(grantor.fdIndex),
+                                  .offset = static_cast<int32_t>(grantor.offset),
+                                  .extent = static_cast<int64_t>(grantor.extent)});
+    }
+
+    std::vector<ndk::ScopedFileDescriptor> fds;
+    std::vector<int> ints;
+    int data_index = 0;
+    for (; data_index < hidlDesc.handle()->numFds; data_index++) {
+        fds.push_back(ndk::ScopedFileDescriptor(dup(hidlDesc.handle()->data[data_index])));
+    }
+    for (; data_index < hidlDesc.handle()->numFds + hidlDesc.handle()->numInts; data_index++) {
+        ints.push_back(hidlDesc.handle()->data[data_index]);
+    }
+
+    aidlDesc->handle = {std::move(fds), std::move(ints)};
+    if (static_cast<int32_t>(hidlDesc.getQuantum()) < 0 ||
+        static_cast<int32_t>(hidlDesc.getFlags()) < 0) {
+        logError(
+                "Unsafe static_cast of quantum or flags. Either the hardware::MQDescriptor is "
+                "invalid, or the MessageQueue is too large to be described by AIDL.");
+        return false;
+    }
+    if (hidlDesc.getFlags() != FlavorTypeToValue<AidlFlavor>::value) {
+        logError("hardware::MQDescriptor hidlDesc is invalid. Unexpected getFlags() value: " +
+                 std::to_string(hidlDesc.getFlags()) +
+                 ". Expected value: " + std::to_string(FlavorTypeToValue<AidlFlavor>::value));
+        return false;
+    }
+    aidlDesc->quantum = static_cast<int32_t>(hidlDesc.getQuantum());
+    aidlDesc->flags = static_cast<int32_t>(hidlDesc.getFlags());
+    return true;
+}
+
+}  // namespace android
diff --git a/include/fmq/MessageQueue.h b/include/fmq/MessageQueue.h
index ca031aa..8ff0739 100644
--- a/include/fmq/MessageQueue.h
+++ b/include/fmq/MessageQueue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,38 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef HIDL_MQ_H
-#define HIDL_MQ_H
+#pragma once
 
-#include <atomic>
-#include <cutils/ashmem.h>
-#include <fmq/EventFlag.h>
 #include <hidl/MQDescriptor.h>
-#include <new>
-#include <sys/mman.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
+#include "MessageQueueBase.h"
 
 namespace android {
 namespace hardware {
 
-namespace details {
-void check(bool exp);
-void logError(const std::string &message);
-}  // namespace details
-
 template <typename T, MQFlavor flavor>
-struct MessageQueue {
+struct MessageQueue final : public MessageQueueBase<MQDescriptor, T, flavor> {
     typedef MQDescriptor<T, flavor> Descriptor;
-
-    /**
-     * @param Desc MQDescriptor describing the FMQ.
-     * @param resetPointers bool indicating whether the read/write pointers
-     * should be reset or not.
-     */
-    MessageQueue(const Descriptor& Desc, bool resetPointers = true);
-
-    ~MessageQueue();
+    MessageQueue(const Descriptor& Desc, bool resetPointers = true)
+        : MessageQueueBase<MQDescriptor, T, flavor>(Desc, resetPointers) {}
+    ~MessageQueue() = default;
 
     /**
      * This constructor uses Ashmem shared memory to create an FMQ
@@ -54,1165 +36,27 @@
      * @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.
      */
-    MessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false);
+    MessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
+                 android::base::unique_fd bufferFd, size_t bufferSize)
+        : MessageQueueBase<MQDescriptor, T, flavor>(numElementsInQueue, configureEventFlagWord,
+                                                    std::move(bufferFd), bufferSize) {}
 
-    /**
-     * @return Number of items of type T that can be written into the FMQ
-     * without a read.
-     */
-    size_t availableToWrite() const;
+    MessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false)
+        : MessageQueueBase<MQDescriptor, T, flavor>(numElementsInQueue, configureEventFlagWord,
+                                                    android::base::unique_fd(), 0) {}
 
-    /**
-     * @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;
-
+  private:
     MessageQueue(const MessageQueue& other) = delete;
     MessageQueue& operator=(const MessageQueue& other) = delete;
-    MessageQueue();
-
-    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;
+    MessageQueue() = delete;
 };
 
-template <typename T, MQFlavor flavor>
-T* MessageQueue<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 <typename T, MQFlavor flavor>
-bool MessageQueue<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
-         * accomodated 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 <typename T, MQFlavor flavor>
-bool MessageQueue<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 <typename T, MQFlavor flavor>
-bool MessageQueue<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 <typename T, MQFlavor flavor>
-void MessageQueue<T, flavor>::initMemory(bool resetPointers) {
-    /*
-     * Verify that the 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() < Descriptor::kMinGrantorCount) ||
-        (mDesc->getQuantum() != sizeof(T))) {
-        return;
-    }
-
-    if (flavor == kSynchronizedReadWrite) {
-        mReadPtr = reinterpret_cast<std::atomic<uint64_t>*>(
-                mapGrantorDescr(Descriptor::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>;
-    }
-
-    details::check(mReadPtr != nullptr);
-
-    mWritePtr =
-            reinterpret_cast<std::atomic<uint64_t>*>(mapGrantorDescr(Descriptor::WRITEPTRPOS));
-    details::check(mWritePtr != nullptr);
-
-    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(Descriptor::DATAPTRPOS));
-    details::check(mRing != nullptr);
-
-    mEvFlagWord = static_cast<std::atomic<uint32_t>*>(mapGrantorDescr(Descriptor::EVFLAGWORDPOS));
-    if (mEvFlagWord != nullptr) {
-        android::hardware::EventFlag::createEventFlag(mEvFlagWord, &mEventFlag);
-    }
-}
-
-template <typename T, MQFlavor flavor>
-MessageQueue<T, flavor>::MessageQueue(const Descriptor& Desc, bool resetPointers) {
-    mDesc = std::unique_ptr<Descriptor>(new (std::nothrow) Descriptor(Desc));
-    if (mDesc == nullptr) {
-        return;
-    }
-
-    initMemory(resetPointers);
-}
-
-template <typename T, MQFlavor flavor>
-MessageQueue<T, flavor>::MessageQueue(size_t numElementsInQueue, bool configureEventFlagWord) {
-
-    // Check if the buffer size would not overflow size_t
-    if (numElementsInQueue > SIZE_MAX / 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::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 =
-            (Descriptor::alignToWordBoundary(kQueueSizeBytes) + kMetaDataSize + PAGE_SIZE - 1) &
-            ~(PAGE_SIZE - 1);
-
-    /*
-     * Create an ashmem region to map the memory for the ringbuffer,
-     * read counter and write counter.
-     */
-    int ashmemFd = ashmem_create_region("MessageQueue", kAshmemSizePageAligned);
-    ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
-
-    /*
-     * The native handle will contain the fds to be mapped.
-     */
-    native_handle_t* mqHandle =
-            native_handle_create(1 /* numFds */, 0 /* numInts */);
-    if (mqHandle == nullptr) {
-        return;
-    }
-
-    mqHandle->data[0] = ashmemFd;
-    mDesc = std::unique_ptr<Descriptor>(new (std::nothrow) Descriptor(kQueueSizeBytes,
-                                                                      mqHandle,
-                                                                      sizeof(T),
-                                                                      configureEventFlagWord));
-    if (mDesc == nullptr) {
-        return;
-    }
-    initMemory(true);
-}
-
-template <typename T, MQFlavor flavor>
-MessageQueue<T, flavor>::~MessageQueue() {
-    if (flavor == kUnsynchronizedWrite) {
-        delete mReadPtr;
-    } else {
-        unmapGrantorDescr(mReadPtr, Descriptor::READPTRPOS);
-    }
-    if (mWritePtr != nullptr) {
-        unmapGrantorDescr(mWritePtr, Descriptor::WRITEPTRPOS);
-    }
-    if (mRing != nullptr) {
-        unmapGrantorDescr(mRing, Descriptor::DATAPTRPOS);
-    }
-    if (mEvFlagWord != nullptr) {
-        unmapGrantorDescr(mEvFlagWord, Descriptor::EVFLAGWORDPOS);
-        android::hardware::EventFlag::deleteEventFlag(&mEventFlag);
-    }
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::write(const T* data) {
-    return write(data, 1);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::read(T* data) {
-    return read(data, 1);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::write(const T* data, size_t nMessages) {
-    MemTransaction tx;
-    return beginWrite(nMessages, &tx) &&
-            tx.copyTo(data, 0 /* startIdx */, nMessages) &&
-            commitWrite(nMessages);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<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) {
-            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) {
-            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 <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::writeBlocking(const T* data,
-                   size_t count,
-                   int64_t timeOutNanos) {
-    return writeBlocking(data, count, FMQ_NOT_FULL, FMQ_NOT_EMPTY, timeOutNanos);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<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) {
-            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) {
-            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 <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::readBlocking(T* data, size_t count, int64_t timeOutNanos) {
-    return readBlocking(data, count, FMQ_NOT_FULL, FMQ_NOT_EMPTY, timeOutNanos);
-}
-
-template <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::availableToWriteBytes() const {
-    return mDesc->getSize() - availableToReadBytes();
-}
-
-template <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::availableToWrite() const {
-    return availableToWriteBytes() / sizeof(T);
-}
-
-template <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::availableToRead() const {
-    return availableToReadBytes() / sizeof(T);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<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);
-    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 <typename T, MQFlavor flavor>
-/*
- * Disable integer sanitization since integer overflow here is allowed
- * and legal.
- */
-__attribute__((no_sanitize("integer")))
-bool MessageQueue<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 <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::availableToReadBytes() const {
-    /*
-     * This method is invoked by implementations of both read() and write() and
-     * hence requries a memory_order_acquired load for both mReadPtr and
-     * mWritePtr.
-     */
-    return mWritePtr->load(std::memory_order_acquire) -
-            mReadPtr->load(std::memory_order_acquire);
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::read(T* data, size_t nMessages) {
-    MemTransaction tx;
-    return beginRead(nMessages, &tx) &&
-            tx.copyFrom(data, 0 /* startIdx */, nMessages) &&
-            commitRead(nMessages);
-}
-
-template <typename T, MQFlavor flavor>
-/*
- * Disable integer sanitization since integer overflow here is allowed
- * and legal.
- */
-__attribute__((no_sanitize("integer")))
-bool MessageQueue<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 - 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 <typename T, MQFlavor flavor>
-/*
- * Disable integer sanitization since integer overflow here is allowed
- * and legal.
- */
-__attribute__((no_sanitize("integer")))
-bool MessageQueue<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 occured 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 <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::getQuantumSize() const {
-    return mDesc->getQuantum();
-}
-
-template <typename T, MQFlavor flavor>
-size_t MessageQueue<T, flavor>::getQuantumCount() const {
-    return mDesc->getSize() / mDesc->getQuantum();
-}
-
-template <typename T, MQFlavor flavor>
-bool MessageQueue<T, flavor>::isValid() const {
-    return mRing != nullptr && mReadPtr != nullptr && mWritePtr != nullptr;
-}
-
-template <typename T, MQFlavor flavor>
-void* MessageQueue<T, flavor>::mapGrantorDescr(uint32_t grantorIdx) {
-    const native_handle_t* handle = mDesc->handle();
-    auto grantors = mDesc->grantors();
-    if (handle == nullptr) {
-        details::logError("mDesc->handle is null");
-        return nullptr;
-    }
-
-    if (grantorIdx >= grantors.size()) {
-        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) {
-        details::logError(std::string("mmap failed: ") + std::to_string(errno));
-        return nullptr;
-    }
-    return reinterpret_cast<uint8_t*>(address) + (grantors[grantorIdx].offset - mapOffset);
-}
-
-template <typename T, MQFlavor flavor>
-void MessageQueue<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
 }  // namespace android
-#endif  // HIDL_MQ_H
diff --git a/include/fmq/MessageQueueBase.h b/include/fmq/MessageQueueBase.h
new file mode 100644
index 0000000..b932317
--- /dev/null
+++ b/include/fmq/MessageQueueBase.h
@@ -0,0 +1,1300 @@
+/*
+ * 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) {
+        if (hardware::details::isAlignedToWordBoundary(grantor.offset) == false) {
+#ifdef __BIONIC__
+            __assert(__FILE__, __LINE__, "Grantor offsets need to be aligned");
+#endif
+        }
+    }
+
+    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>;
+    }
+    if (mReadPtr == nullptr) {
+#ifdef __BIONIC__
+        __assert(__FILE__, __LINE__, "mReadPtr is null");
+#endif
+    }
+
+    mWritePtr = reinterpret_cast<std::atomic<uint64_t>*>(
+            mapGrantorDescr(hardware::details::WRITEPTRPOS));
+    if (mWritePtr == nullptr) {
+#ifdef __BIONIC__
+        __assert(__FILE__, __LINE__, "mWritePtr is null");
+#endif
+    }
+
+    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));
+    if (mRing == nullptr) {
+#ifdef __BIONIC__
+        __assert(__FILE__, __LINE__, "mRing is null");
+#endif
+    }
+
+    if (mDesc->countGrantors() > hardware::details::EVFLAGWORDPOS) {
+        mEvFlagWord = static_cast<std::atomic<uint32_t>*>(
+                mapGrantorDescr(hardware::details::EVFLAGWORDPOS));
+        if (mEvFlagWord != nullptr) {
+            android::hardware::EventFlag::createEventFlag(mEvFlagWord, &mEventFlag);
+        } else {
+#ifdef __BIONIC__
+            __assert(__FILE__, __LINE__, "mEvFlagWord is null");
+#endif
+        }
+    }
+}
+
+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
diff --git a/tests/Android.bp b/tests/Android.bp
index b85aa16..ec38cea 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -14,14 +14,36 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+python_test_host {
+    name: "fmq_test",
+    main: "fmq_test.py",
+    srcs: ["fmq_test.py"],
+    test_config: "fmq_test.xml",
+    target_required: [
+        "android.hardware.tests.msgq@1.0-service-test",
+        "fmq_test_client",
+    ],
+    test_suites: ["general-tests", "vts"],
+    test_options: {
+        unit_test: false,
+    },
+}
+
 cc_test {
-    name: "mq_test_client",
+    name: "fmq_test_client",
     srcs: ["msgq_test_client.cpp"],
 
     cflags: [
         "-Wall",
         "-Werror",
     ],
+    sanitize: {
+        misc_undefined: ["integer"],
+    },
 
     shared_libs: [
         "libbase",
@@ -30,32 +52,58 @@
         "libhidlbase",
         "liblog",
         "libutils",
+        "libbinder_ndk",
+    ],
+
+    // These are static libs only for testing purposes and portability. Shared
+    // libs should be used on device.
+    static_libs: [
+        "android.hardware.common-V2-ndk_platform",
+        "android.hardware.common.fmq-V1-ndk_platform",
+        "android.hardware.tests.msgq@1.0",
+        "android.fmq.test-ndk_platform",
+    ],
+    whole_static_libs: [
+        "android.hardware.tests.msgq@1.0-impl",
+        "android.fmq.test-impl"
+    ],
+
+    compile_multilib: "both",
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            suffix: "64",
+        },
+    },
+    test_suites: ["general-tests", "vts"],
+    auto_gen_config: false,
+}
+
+cc_test {
+    name: "fmq_unit_tests",
+
+    srcs: ["fmq_unit_tests.cpp"],
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "liblog",
+        "libutils",
     ],
-
-    // Allow dlsym'ing self for statically linked passthrough implementations
-    ldflags: ["-rdynamic"],
-
-    // These are static libs only for testing purposes and portability. Shared
-    // libs should be used on device.
-    static_libs: ["android.hardware.tests.msgq@1.0"],
-    whole_static_libs: ["android.hardware.tests.msgq@1.0-impl"],
-}
-
-cc_test {
-    name: "mq_test",
-
-    srcs: ["mq_test.cpp"],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "libfmq",
-        "libhidlbase",
-        "liblog",
-        "libutils",
+    static_libs: [
+        "android.hardware.common.fmq-V1-ndk_platform",
     ],
 
     cflags: [
         "-Wall",
         "-Werror",
     ],
+    sanitize: {
+        misc_undefined: ["integer"],
+    },
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
 }
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 6efe7c2..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := fmq_test
-LOCAL_MODULE_CLASS := NATIVE_TESTS
-LOCAL_SRC_FILES := fmq_test
-LOCAL_REQUIRED_MODULES :=                           \
-    mq_test_client                                  \
-    android.hardware.tests.msgq@1.0-service-test    \
-    hidl_test_helper
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest64
-
-ifneq ($(TARGET_2ND_ARCH),)
-LOCAL_REQUIRED_MODULES += android.hardware.tests.msgq@1.0-service-test$(TARGET_2ND_ARCH_MODULE_SUFFIX)
-LOCAL_REQUIRED_MODULES += mq_test_client$(TARGET_2ND_ARCH_MODULE_SUFFIX)
-endif
-
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := VtsFmqUnitTests
--include test/vts/tools/build/Android.host_config.mk
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
deleted file mode 100644
index 9e5df01..0000000
--- a/tests/AndroidTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Config for VTS FMQ unit tests">
-    <option name="config-descriptor:metadata" key="plan" value="vts-library" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
-        <option name="push-group" value="HostDrivenTest.push" />
-        <option name="cleanup" value="true" />
-        <option name="push" value="DATA/nativetest/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test->/data/nativetest/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" />
-        <option name="push" value="DATA/nativetest64/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test->/data/nativetest64/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" />
-        <option name="push" value="DATA/nativetest/mq_test_client/mq_test_client->/data/nativetest/mq_test_client/mq_test_client" />
-        <option name="push" value="DATA/nativetest64/mq_test_client/mq_test_client->/data/nativetest64/mq_test_client/mq_test_client" />
-        <option name="push" value="DATA/nativetest64/hidl_test_helper->/data/nativetest64/hidl_test_helper" />
-    </target_preparer>
-    <multi_target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
-    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
-        <option name="test-module-name" value="VtsFmqUnitTests" />
-        <option name="binary-test-type" value="binary_test" />
-        <option name="binary-test-source" value="DATA/nativetest64/fmq_test->/data/nativetest64/fmq_test" />
-        <option name="test-timeout" value="1m"/>
-    </test>
-</configuration>
diff --git a/tests/aidl/Android.bp b/tests/aidl/Android.bp
new file mode 100644
index 0000000..e210fda
--- /dev/null
+++ b/tests/aidl/Android.bp
@@ -0,0 +1,29 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.fmq.test",
+    host_supported: true,
+    vendor_available: true,
+    unstable: true,
+    srcs: [
+        "android/fmq/test/*.aidl",
+    ],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+    ],
+    gen_trace: true,
+    backend: {
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+        },
+        cpp: {
+            enabled: false,
+        }
+    },
+}
diff --git a/tests/aidl/android/fmq/test/EventFlagBits.aidl b/tests/aidl/android/fmq/test/EventFlagBits.aidl
new file mode 100644
index 0000000..202a67c
--- /dev/null
+++ b/tests/aidl/android/fmq/test/EventFlagBits.aidl
@@ -0,0 +1,9 @@
+// FIXME: license file if you have one
+
+package android.fmq.test;
+
+@Backing(type="int")
+enum EventFlagBits {
+    FMQ_NOT_EMPTY = 1 << 0,
+    FMQ_NOT_FULL = 1 << 1,
+}
diff --git a/tests/aidl/android/fmq/test/FixedParcelable.aidl b/tests/aidl/android/fmq/test/FixedParcelable.aidl
new file mode 100644
index 0000000..acb54f2
--- /dev/null
+++ b/tests/aidl/android/fmq/test/FixedParcelable.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package android.fmq.test;
+
+import android.fmq.test.EventFlagBits;
+
+@FixedSize
+parcelable FixedParcelable {
+  int a;
+  EventFlagBits b;
+}
diff --git a/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl b/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
new file mode 100644
index 0000000..7f1f8b7
--- /dev/null
+++ b/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package android.fmq.test;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.common.fmq.UnsynchronizedWrite;
+
+/**
+ * Test interface for MQDescriptor.
+ */
+interface ITestAidlMsgQ {
+    /**
+     * This method requests the service to set up a synchronous read/write
+     * wait-free FMQ using the input descriptor with the client as reader.
+     *
+     * @param mqDesc This structure describes the FMQ that was set up by the
+     * client. Server uses this descriptor to set up a FMQ object at its end.
+     *
+     * @return True if the setup is successful.
+     */
+    boolean configureFmqSyncReadWrite(in MQDescriptor<int, SynchronizedReadWrite> mqDesc);
+
+    /**
+     * This method requests the service to return an MQDescriptor to
+     * an unsynchronized FMQ set up by the server. If 'configureFmq' is
+     * true, then the server sets up a new unsynchronized FMQ. This
+     * method is to be used to test multiple reader processes.
+     *
+     * @param configureFmq The server sets up a new unsynchronized FMQ if
+     * this parameter is true.
+     * @param userFd True to initialize the message queue with a user supplied
+     * file descriptor for the ring buffer.
+     * False to let the message queue use a single FD for everything.
+     *
+     * @param out ret True if successful.
+     * @param out mqDesc This structure describes the unsynchronized FMQ that was
+     * set up by the service. Client can use it to set up the FMQ at its end.
+     */
+    boolean getFmqUnsyncWrite(in boolean configureFmq, in boolean userFd,
+        out MQDescriptor<int, UnsynchronizedWrite> mqDesc);
+
+    /**
+     * This method requests the service to trigger a blocking read.
+     *
+     * @param count Number of messages to read.
+     *
+     */
+    oneway void requestBlockingRead(in int count);
+
+    /**
+     * This method requests the service to trigger a blocking read using
+     * default Event Flag notification bits defined by the MessageQueue class.
+     *
+     * @param count Number of messages to read.
+     *
+     */
+    oneway void requestBlockingReadDefaultEventFlagBits(in int count);
+
+    /**
+     * This method requests the service to repeatedly trigger blocking reads.
+     *
+     * @param count Number of messages to read in a single blocking read.
+     * @param numIter Number of blocking reads to trigger.
+     *
+     */
+    oneway void requestBlockingReadRepeat(in int count, in int numIter);
+
+    /**
+     * This method request the service to read from the synchronized read/write
+     * FMQ.
+     *
+     * @param count Number to messages to read.
+     *
+     * @return True if the read operation was successful.
+     */
+    boolean requestReadFmqSync(in int count);
+
+    /**
+     * This method request the service to read from the unsynchronized flavor of
+     * FMQ.
+     *
+     * @param count Number to messages to read.
+     *
+     * @return Will be True if the read operation was successful.
+     */
+    boolean requestReadFmqUnsync(in int count);
+
+    /**
+     * This method request the service to write into the synchronized read/write
+     * flavor of the FMQ.
+     *
+     * @param count Number to messages to write.
+     *
+     * @return True if the write operation was successful.
+     */
+    boolean requestWriteFmqSync(in int count);
+
+    /**
+     * This method request the service to write into the unsynchronized flavor
+     * of FMQ.
+     *
+     * @param count Number to messages to write.
+     *
+     * @return True if the write operation was successful.
+     */
+    boolean requestWriteFmqUnsync(in int count);
+}
diff --git a/tests/aidl/default/Android.bp b/tests/aidl/default/Android.bp
new file mode 100644
index 0000000..71a5533
--- /dev/null
+++ b/tests/aidl/default/Android.bp
@@ -0,0 +1,19 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+    name: "android.fmq.test-impl",
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libfmq",
+    ],
+    static_libs: [
+        "android.fmq.test-ndk_platform",
+    ],
+    export_include_dirs: ["."],
+    srcs: [
+        "TestAidlMsgQ.cpp",
+    ],
+}
diff --git a/tests/aidl/default/TestAidlMsgQ.cpp b/tests/aidl/default/TestAidlMsgQ.cpp
new file mode 100644
index 0000000..485e75b
--- /dev/null
+++ b/tests/aidl/default/TestAidlMsgQ.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2020 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 "TestAidlMsgQ.h"
+
+namespace aidl {
+namespace android {
+namespace fmq {
+namespace test {
+
+// Methods from ::aidl::android::fmq::test::ITestAidlMsgQ follow.
+ndk::ScopedAStatus TestAidlMsgQ::configureFmqSyncReadWrite(
+        const MQDescriptor<int32_t, SynchronizedReadWrite>& mqDesc, bool* _aidl_return) {
+    mFmqSynchronized.reset(new (std::nothrow) TestAidlMsgQ::MessageQueueSync(mqDesc));
+    if ((mFmqSynchronized == nullptr) || (mFmqSynchronized->isValid() == false)) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    /*
+     * Initialize the EventFlag word with bit FMQ_NOT_FULL.
+     */
+    auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord();
+    if (evFlagWordPtr != nullptr) {
+        std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL));
+    }
+    *_aidl_return = true;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::getFmqUnsyncWrite(
+        bool configureFmq, bool userFd, MQDescriptor<int32_t, UnsynchronizedWrite>* mqDesc,
+        bool* _aidl_return) {
+    if (configureFmq) {
+        static constexpr size_t kNumElementsInQueue = 1024;
+        static constexpr size_t kElementSizeBytes = sizeof(int32_t);
+        ::android::base::unique_fd ringbufferFd;
+        if (userFd) {
+            ringbufferFd.reset(
+                    ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kElementSizeBytes));
+        }
+        mFmqUnsynchronized.reset(new (std::nothrow) TestAidlMsgQ::MessageQueueUnsync(
+                kNumElementsInQueue, false, std::move(ringbufferFd),
+                kNumElementsInQueue * kElementSizeBytes));
+    }
+
+    if ((mFmqUnsynchronized == nullptr) || (mFmqUnsynchronized->isValid() == false) ||
+        (mqDesc == nullptr)) {
+        *_aidl_return = false;
+    } else {
+        *mqDesc = std::move(mFmqUnsynchronized->dupeDesc());
+        *_aidl_return = true;
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestBlockingRead(int32_t count) {
+    std::vector<int32_t> data(count);
+    bool result = mFmqSynchronized->readBlocking(
+            &data[0], count, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL),
+            static_cast<uint32_t>(EventFlagBits::FMQ_NOT_EMPTY), 5000000000 /* timeOutNanos */);
+
+    if (result == false) {
+        ALOGE("Blocking read fails");
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestBlockingReadDefaultEventFlagBits(int32_t count) {
+    std::vector<int32_t> data(count);
+    bool result = mFmqSynchronized->readBlocking(&data[0], count);
+
+    if (result == false) {
+        ALOGE("Blocking read fails");
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestBlockingReadRepeat(int32_t count, int32_t numIter) {
+    std::vector<int32_t> data(count);
+    for (int i = 0; i < numIter; i++) {
+        bool result = mFmqSynchronized->readBlocking(
+                &data[0], count, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(EventFlagBits::FMQ_NOT_EMPTY), 5000000000 /* timeOutNanos */);
+
+        if (result == false) {
+            ALOGE("Blocking read fails");
+            break;
+        }
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestReadFmqSync(int32_t count, bool* _aidl_return) {
+    std::vector<int32_t> data(count);
+    bool result = mFmqSynchronized->read(&data[0], count) && verifyData(&data[0], count);
+    *_aidl_return = result;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestReadFmqUnsync(int32_t count, bool* _aidl_return) {
+    std::vector<int32_t> data(count);
+    bool result = mFmqUnsynchronized->read(&data[0], count) && verifyData(&data[0], count);
+    *_aidl_return = result;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestWriteFmqSync(int32_t count, bool* _aidl_return) {
+    std::vector<int32_t> data(count);
+    for (int i = 0; i < count; i++) {
+        data[i] = i;
+    }
+    bool result = mFmqSynchronized->write(&data[0], count);
+    *_aidl_return = result;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus TestAidlMsgQ::requestWriteFmqUnsync(int32_t count, bool* _aidl_return) {
+    std::vector<int32_t> data(count);
+    for (int i = 0; i < count; i++) {
+        data[i] = i;
+    }
+    if (!mFmqUnsynchronized) {
+        ALOGE("Unsynchronized queue is not configured.");
+        *_aidl_return = false;
+        return ndk::ScopedAStatus::ok();
+    }
+    bool result = mFmqUnsynchronized->write(&data[0], count);
+    *_aidl_return = result;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace test
+}  // namespace fmq
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/aidl/default/TestAidlMsgQ.h b/tests/aidl/default/TestAidlMsgQ.h
new file mode 100644
index 0000000..6e7c859
--- /dev/null
+++ b/tests/aidl/default/TestAidlMsgQ.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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 <aidl/android/fmq/test/BnTestAidlMsgQ.h>
+#include <aidl/android/fmq/test/EventFlagBits.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
+
+namespace aidl {
+namespace android {
+namespace fmq {
+namespace test {
+
+using ::aidl::android::fmq::test::EventFlagBits;
+using ::aidl::android::fmq::test::ITestAidlMsgQ;
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::kUnsynchronizedWrite;
+using ::android::hardware::MQFlavor;
+
+using ::android::AidlMessageQueue;
+
+struct TestAidlMsgQ : public BnTestAidlMsgQ {
+    typedef AidlMessageQueue<int32_t, SynchronizedReadWrite> MessageQueueSync;
+    typedef AidlMessageQueue<int32_t, UnsynchronizedWrite> MessageQueueUnsync;
+
+    TestAidlMsgQ() : mFmqSynchronized(nullptr), mFmqUnsynchronized(nullptr) {}
+
+    // Methods from ::aidl::android::fmq::test::ITestAidlMsgQ follow.
+    ndk::ScopedAStatus configureFmqSyncReadWrite(
+            const MQDescriptor<int32_t, SynchronizedReadWrite>& mqDesc,
+            bool* _aidl_return) override;
+    ndk::ScopedAStatus getFmqUnsyncWrite(bool configureFmq, bool userFd,
+                                         MQDescriptor<int32_t, UnsynchronizedWrite>* mqDesc,
+                                         bool* _aidl_return) override;
+    ndk::ScopedAStatus requestBlockingRead(int32_t count) override;
+    ndk::ScopedAStatus requestBlockingReadDefaultEventFlagBits(int32_t count) override;
+    ndk::ScopedAStatus requestBlockingReadRepeat(int32_t count, int32_t numIter) override;
+    ndk::ScopedAStatus requestReadFmqSync(int32_t count, bool* _aidl_return) override;
+    ndk::ScopedAStatus requestReadFmqUnsync(int32_t count, bool* _aidl_return) override;
+    ndk::ScopedAStatus requestWriteFmqSync(int32_t count, bool* _aidl_return) override;
+    ndk::ScopedAStatus requestWriteFmqUnsync(int32_t count, bool* _aidl_return) override;
+
+  private:
+    std::unique_ptr<MessageQueueSync> mFmqSynchronized;
+    std::unique_ptr<MessageQueueUnsync> mFmqUnsynchronized;
+
+    /*
+     * Utility function to verify data read from the fast message queue.
+     */
+    bool verifyData(int32_t* data, int count) {
+        for (int i = 0; i < count; i++) {
+            if (data[i] != i) return false;
+        }
+        return true;
+    }
+};
+
+}  // namespace test
+}  // namespace fmq
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/fmq_test b/tests/fmq_test
deleted file mode 100644
index 02683c9..0000000
--- a/tests/fmq_test
+++ /dev/null
@@ -1,9 +0,0 @@
-source /data/nativetest64/hidl_test_helper
-
-TREBLE_TESTING_OVERRIDE=true run_all_tests \
-    "/data/nativetest/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" \
-    "/data/nativetest64/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" \
-    "/data/nativetest/mq_test_client/mq_test_client" \
-    "/data/nativetest64/mq_test_client/mq_test_client" \
-    "fmq_test" \
-    "$@"
diff --git a/tests/fmq_test.py b/tests/fmq_test.py
new file mode 100644
index 0000000..68114ad
--- /dev/null
+++ b/tests/fmq_test.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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.
+#
+
+import subprocess
+import unittest
+
+def run_cmd(cmd, ignore_error=False):
+    print("Running command:", cmd)
+    p = subprocess.Popen(cmd, shell=True)
+    p.communicate()
+    if not ignore_error and p.returncode:
+        raise subprocess.CalledProcessError(p.returncode, cmd)
+    return p.returncode
+
+class TestFmq(unittest.TestCase):
+    pass
+
+def make_test(client, server):
+    def test(self):
+        try:
+            run_cmd("adb shell killall %s >/dev/null 2>&1" % client, ignore_error=True)
+            run_cmd("adb shell killall %s >/dev/null 2>&1" % server, ignore_error=True)
+            run_cmd("adb shell \"( %s ) </dev/null >/dev/null 2>&1 &\"" % server)
+            run_cmd("adb shell %s" % client)
+        finally:
+            run_cmd("adb shell killall %s >/dev/null 2>&1" % client, ignore_error=True)
+            run_cmd("adb shell killall %s >/dev/null 2>&1" % server, ignore_error=True)
+    return test
+
+def has_bitness(bitness):
+    return 0 == run_cmd("echo '[[ \"$(getprop ro.product.cpu.abilist%s)\" != \"\" ]]' | adb shell sh" % bitness, ignore_error=True)
+
+if __name__ == '__main__':
+    clients = []
+    servers = []
+
+    if has_bitness(32):
+        clients += ["/data/nativetest/fmq_test_client/fmq_test_client"]
+        servers += ["/data/nativetest/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test"]
+
+    if has_bitness(64):
+        clients += ["/data/nativetest64/fmq_test_client/fmq_test_client"]
+        servers += ["/data/nativetest64/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test"]
+
+    assert len(clients) > 0
+    assert len(servers) > 0
+
+    def short_name(binary):
+        if "64" in binary:
+            return "64"
+        return "32"
+
+    for client in clients:
+        for server in servers:
+            test_name = 'test_%s_to_%s' % (short_name(client), short_name(server))
+            test = make_test(client, server)
+            setattr(TestFmq, test_name, test)
+
+    suite = unittest.TestLoader().loadTestsFromTestCase(TestFmq)
+    unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/tests/fmq_test.xml b/tests/fmq_test.xml
new file mode 100644
index 0000000..f7b1f16
--- /dev/null
+++ b/tests/fmq_test.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs FMQ on-device integration tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+      <!-- We would like to abort, but currently there is not a simple way to specify installation of both bitnesses of targets. -->
+      <option name="abort-on-push-failure" value="false"/>
+
+      <option name="push" value="fmq_test_client32->/data/nativetest/fmq_test_client/fmq_test_client" />
+      <option name="push" value="fmq_test_client64->/data/nativetest64/fmq_test_client/fmq_test_client" />
+
+      <option name="push" value="android.hardware.tests.msgq@1.0-service-test32->/data/nativetest/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" />
+      <option name="push" value="android.hardware.tests.msgq@1.0-service-test64->/data/nativetest64/android.hardware.tests.msgq@1.0-service-test/android.hardware.tests.msgq@1.0-service-test" />
+
+      <option name="cleanup" value="true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" >
+        <option name="par-file-name" value="fmq_test" />
+        <option name="test-timeout" value="2m" />
+    </test>
+</configuration>
+
diff --git a/tests/fmq_unit_tests.cpp b/tests/fmq_unit_tests.cpp
new file mode 100644
index 0000000..be866ec
--- /dev/null
+++ b/tests/fmq_unit_tests.cpp
@@ -0,0 +1,1147 @@
+/*
+ * 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.
+ */
+
+#include <asm-generic/mman.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/ConvertMQDescriptors.h>
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
+#include <gtest/gtest-death-test.h>
+#include <gtest/gtest.h>
+#include <sys/resource.h>
+#include <atomic>
+#include <cstdlib>
+#include <sstream>
+#include <thread>
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::kUnsynchronizedWrite;
+
+enum EventFlagBits : uint32_t {
+    kFmqNotEmpty = 1 << 0,
+    kFmqNotFull = 1 << 1,
+};
+
+typedef android::AidlMessageQueue<uint8_t, SynchronizedReadWrite> AidlMessageQueueSync;
+typedef android::AidlMessageQueue<uint8_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
+typedef android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite> MessageQueueSync;
+typedef android::hardware::MessageQueue<uint8_t, kUnsynchronizedWrite> MessageQueueUnsync;
+typedef android::AidlMessageQueue<uint16_t, SynchronizedReadWrite> AidlMessageQueueSync16;
+typedef android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync16;
+
+typedef android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite> MessageQueueSync8;
+typedef android::hardware::MQDescriptor<uint8_t, kSynchronizedReadWrite> HidlMQDescSync8;
+typedef android::AidlMessageQueue<int8_t, SynchronizedReadWrite> AidlMessageQueueSync8;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<int8_t, SynchronizedReadWrite>
+        AidlMQDescSync8;
+typedef android::hardware::MessageQueue<uint8_t, kUnsynchronizedWrite> MessageQueueUnsync8;
+typedef android::hardware::MQDescriptor<uint8_t, kUnsynchronizedWrite> HidlMQDescUnsync8;
+typedef android::AidlMessageQueue<int8_t, UnsynchronizedWrite> AidlMessageQueueUnsync8;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<int8_t, UnsynchronizedWrite>
+        AidlMQDescUnsync8;
+
+enum class SetupType {
+    SINGLE_FD,
+    DOUBLE_FD,
+};
+
+template <typename T, SetupType setupType>
+class TestParamTypes {
+  public:
+    typedef T MQType;
+    static constexpr SetupType Setup = setupType;
+};
+
+// Run everything on both the AIDL and HIDL versions with one and two FDs
+typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync, SetupType::SINGLE_FD>,
+                         TestParamTypes<MessageQueueSync, SetupType::SINGLE_FD>,
+                         TestParamTypes<AidlMessageQueueSync, SetupType::DOUBLE_FD>,
+                         TestParamTypes<MessageQueueSync, SetupType::DOUBLE_FD>>
+        SyncTypes;
+typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync, SetupType::SINGLE_FD>,
+                         TestParamTypes<MessageQueueUnsync, SetupType::SINGLE_FD>,
+                         TestParamTypes<AidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
+                         TestParamTypes<MessageQueueUnsync, SetupType::DOUBLE_FD>>
+        UnsyncTypes;
+typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync16, SetupType::SINGLE_FD>,
+                         TestParamTypes<MessageQueueSync16, SetupType::SINGLE_FD>,
+                         TestParamTypes<AidlMessageQueueSync16, SetupType::DOUBLE_FD>,
+                         TestParamTypes<MessageQueueSync16, SetupType::DOUBLE_FD>>
+        BadConfigTypes;
+
+template <typename T>
+class TestBase : public ::testing::Test {
+  public:
+    static void ReaderThreadBlocking(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr);
+    static void ReaderThreadBlocking2(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr);
+};
+
+TYPED_TEST_CASE(SynchronizedReadWrites, SyncTypes);
+
+template <typename T>
+class SynchronizedReadWrites : public TestBase<T> {
+  protected:
+    virtual void TearDown() {
+        delete mQueue;
+    }
+
+    virtual void SetUp() {
+        static constexpr size_t kNumElementsInQueue = 2048;
+        static constexpr size_t kPayloadSizeBytes = 1;
+        if (T::Setup == SetupType::SINGLE_FD) {
+            mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
+        } else {
+            android::base::unique_fd ringbufferFd(::ashmem_create_region(
+                    "SyncReadWrite", kNumElementsInQueue * kPayloadSizeBytes));
+            mQueue = new (std::nothrow)
+                    typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
+                                       kNumElementsInQueue * kPayloadSizeBytes);
+        }
+        ASSERT_NE(nullptr, mQueue);
+        ASSERT_TRUE(mQueue->isValid());
+        mNumMessagesMax = mQueue->getQuantumCount();
+        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
+    }
+
+    typename T::MQType* mQueue = nullptr;
+    size_t mNumMessagesMax = 0;
+};
+
+TYPED_TEST_CASE(UnsynchronizedWriteTest, UnsyncTypes);
+
+template <typename T>
+class UnsynchronizedWriteTest : public TestBase<T> {
+  protected:
+    virtual void TearDown() {
+        delete mQueue;
+    }
+
+    virtual void SetUp() {
+        static constexpr size_t kNumElementsInQueue = 2048;
+        static constexpr size_t kPayloadSizeBytes = 1;
+        if (T::Setup == SetupType::SINGLE_FD) {
+            mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
+        } else {
+            android::base::unique_fd ringbufferFd(
+                    ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kPayloadSizeBytes));
+            mQueue = new (std::nothrow)
+                    typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
+                                       kNumElementsInQueue * kPayloadSizeBytes);
+        }
+        ASSERT_NE(nullptr, mQueue);
+        ASSERT_TRUE(mQueue->isValid());
+        mNumMessagesMax = mQueue->getQuantumCount();
+        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
+    }
+
+    typename T::MQType* mQueue = nullptr;
+    size_t mNumMessagesMax = 0;
+};
+
+TYPED_TEST_CASE(BlockingReadWrites, SyncTypes);
+
+template <typename T>
+class BlockingReadWrites : public TestBase<T> {
+  protected:
+    virtual void TearDown() {
+        delete mQueue;
+    }
+    virtual void SetUp() {
+        static constexpr size_t kNumElementsInQueue = 2048;
+        static constexpr size_t kPayloadSizeBytes = 1;
+        if (T::Setup == SetupType::SINGLE_FD) {
+            mQueue = new (std::nothrow) typename T::MQType(kNumElementsInQueue);
+        } else {
+            android::base::unique_fd ringbufferFd(::ashmem_create_region(
+                    "SyncBlockingReadWrite", kNumElementsInQueue * kPayloadSizeBytes));
+            mQueue = new (std::nothrow)
+                    typename T::MQType(kNumElementsInQueue, false, std::move(ringbufferFd),
+                                       kNumElementsInQueue * kPayloadSizeBytes);
+        }
+        ASSERT_NE(nullptr, mQueue);
+        ASSERT_TRUE(mQueue->isValid());
+        mNumMessagesMax = mQueue->getQuantumCount();
+        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
+        /*
+         * Initialize the EventFlag word to indicate Queue is not full.
+         */
+        std::atomic_init(&mFw, static_cast<uint32_t>(kFmqNotFull));
+    }
+
+    typename T::MQType* mQueue;
+    std::atomic<uint32_t> mFw;
+    size_t mNumMessagesMax = 0;
+};
+
+TYPED_TEST_CASE(QueueSizeOdd, SyncTypes);
+
+template <typename T>
+class QueueSizeOdd : public TestBase<T> {
+  protected:
+    virtual void TearDown() { delete mQueue; }
+    virtual void SetUp() {
+        static constexpr size_t kNumElementsInQueue = 2049;
+        static constexpr size_t kPayloadSizeBytes = 1;
+        if (T::Setup == SetupType::SINGLE_FD) {
+            mQueue = new (std::nothrow)
+                    typename T::MQType(kNumElementsInQueue, true /* configureEventFlagWord */);
+        } else {
+            android::base::unique_fd ringbufferFd(
+                    ::ashmem_create_region("SyncSizeOdd", kNumElementsInQueue * kPayloadSizeBytes));
+            mQueue = new (std::nothrow) typename T::MQType(
+                    kNumElementsInQueue, true /* configureEventFlagWord */, std::move(ringbufferFd),
+                    kNumElementsInQueue * kPayloadSizeBytes);
+        }
+        ASSERT_NE(nullptr, mQueue);
+        ASSERT_TRUE(mQueue->isValid());
+        mNumMessagesMax = mQueue->getQuantumCount();
+        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
+        auto evFlagWordPtr = mQueue->getEventFlagWord();
+        ASSERT_NE(nullptr, evFlagWordPtr);
+        /*
+         * Initialize the EventFlag word to indicate Queue is not full.
+         */
+        std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(kFmqNotFull));
+    }
+
+    typename T::MQType* mQueue;
+    size_t mNumMessagesMax = 0;
+};
+
+TYPED_TEST_CASE(BadQueueConfig, BadConfigTypes);
+
+template <typename T>
+class BadQueueConfig : public TestBase<T> {};
+
+class AidlOnlyBadQueueConfig : public ::testing::Test {};
+class Hidl2AidlOperation : public ::testing::Test {};
+class DoubleFdFailures : public ::testing::Test {};
+
+/*
+ * Utility function to initialize data to be written to the FMQ
+ */
+inline void initData(uint8_t* data, size_t count) {
+    for (size_t i = 0; i < count; i++) {
+        data[i] = i & 0xFF;
+    }
+}
+
+/*
+ * This thread will attempt to read and block. When wait returns
+ * it checks if the kFmqNotEmpty bit is actually set.
+ * If the read is succesful, it signals Wake to kFmqNotFull.
+ */
+template <typename T>
+void TestBase<T>::ReaderThreadBlocking(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr) {
+    const size_t dataLen = 64;
+    uint8_t data[dataLen];
+    android::hardware::EventFlag* efGroup = nullptr;
+    android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+    ASSERT_NE(nullptr, efGroup);
+
+    while (true) {
+        uint32_t efState = 0;
+        android::status_t ret = efGroup->wait(kFmqNotEmpty,
+                                              &efState,
+                                              5000000000 /* timeoutNanoSeconds */);
+        /*
+         * Wait should not time out here after 5s
+         */
+        ASSERT_NE(android::TIMED_OUT, ret);
+
+        if ((efState & kFmqNotEmpty) && fmq->read(data, dataLen)) {
+            efGroup->wake(kFmqNotFull);
+            break;
+        }
+    }
+
+    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * This thread will attempt to read and block using the readBlocking() API and
+ * passes in a pointer to an EventFlag object.
+ */
+template <typename T>
+void TestBase<T>::ReaderThreadBlocking2(typename T::MQType* fmq, std::atomic<uint32_t>* fwAddr) {
+    const size_t dataLen = 64;
+    uint8_t data[dataLen];
+    android::hardware::EventFlag* efGroup = nullptr;
+    android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+    ASSERT_NE(nullptr, efGroup);
+    bool ret = fmq->readBlocking(data,
+                                 dataLen,
+                                 static_cast<uint32_t>(kFmqNotFull),
+                                 static_cast<uint32_t>(kFmqNotEmpty),
+                                 5000000000 /* timeOutNanos */,
+                                 efGroup);
+    ASSERT_TRUE(ret);
+    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+}
+
+TYPED_TEST(BadQueueConfig, QueueSizeTooLarge) {
+    size_t numElementsInQueue = SIZE_MAX / sizeof(uint16_t) + 1;
+    typename TypeParam::MQType* fmq =
+            new (std::nothrow) typename TypeParam::MQType(numElementsInQueue);
+    ASSERT_NE(nullptr, fmq);
+    /*
+     * Should fail due to size being too large to fit into size_t.
+     */
+    ASSERT_FALSE(fmq->isValid());
+}
+
+// If this test fails and we do leak FDs, the next test will cause a crash
+TEST_F(AidlOnlyBadQueueConfig, LookForLeakedFds) {
+    size_t numElementsInQueue = SIZE_MAX / sizeof(uint32_t) - PAGE_SIZE - 1;
+    struct rlimit rlim;
+    ASSERT_EQ(getrlimit(RLIMIT_NOFILE, &rlim), 0);
+    for (int i = 0; i <= rlim.rlim_cur + 1; i++) {
+        android::AidlMessageQueue<uint32_t, SynchronizedReadWrite> fmq(numElementsInQueue);
+        ASSERT_FALSE(fmq.isValid());
+    }
+    // try to get another FD
+    int fd = ashmem_create_region("test", 100);
+    ASSERT_NE(fd, -1);
+    close(fd);
+}
+
+TEST_F(Hidl2AidlOperation, ConvertDescriptorsSync) {
+    size_t numElementsInQueue = 64;
+
+    // Create HIDL side and get MQDescriptor
+    MessageQueueSync8* fmq = new (std::nothrow) MessageQueueSync8(numElementsInQueue);
+    ASSERT_NE(nullptr, fmq);
+    ASSERT_TRUE(fmq->isValid());
+    const HidlMQDescSync8* hidlDesc = fmq->getDesc();
+    ASSERT_NE(nullptr, hidlDesc);
+
+    // Create AIDL MQDescriptor to send to another process based off the HIDL MQDescriptor
+    AidlMQDescSync8 aidlDesc;
+    android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(*hidlDesc,
+                                                                                  &aidlDesc);
+
+    // Other process will create the other side of the queue using the AIDL MQDescriptor
+    AidlMessageQueueSync8* aidlFmq = new (std::nothrow) AidlMessageQueueSync8(aidlDesc);
+    ASSERT_NE(nullptr, aidlFmq);
+    ASSERT_TRUE(aidlFmq->isValid());
+
+    // Make sure a write to the HIDL side, will show up for the AIDL side
+    constexpr size_t dataLen = 4;
+    uint8_t data[dataLen] = {12, 11, 10, 9};
+    fmq->write(data, dataLen);
+
+    int8_t readData[dataLen];
+    ASSERT_TRUE(aidlFmq->read(readData, dataLen));
+
+    ASSERT_EQ(data[0], readData[0]);
+    ASSERT_EQ(data[1], readData[1]);
+    ASSERT_EQ(data[2], readData[2]);
+    ASSERT_EQ(data[3], readData[3]);
+}
+
+TEST_F(Hidl2AidlOperation, ConvertDescriptorsUnsync) {
+    size_t numElementsInQueue = 64;
+
+    // Create HIDL side and get MQDescriptor
+    MessageQueueUnsync8* fmq = new (std::nothrow) MessageQueueUnsync8(numElementsInQueue);
+    ASSERT_NE(nullptr, fmq);
+    ASSERT_TRUE(fmq->isValid());
+    const HidlMQDescUnsync8* hidlDesc = fmq->getDesc();
+    ASSERT_NE(nullptr, hidlDesc);
+
+    // Create AIDL MQDescriptor to send to another process based off the HIDL MQDescriptor
+    AidlMQDescUnsync8 aidlDesc;
+    android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(*hidlDesc,
+                                                                                &aidlDesc);
+
+    // Other process will create the other side of the queue using the AIDL MQDescriptor
+    AidlMessageQueueUnsync8* aidlFmq = new (std::nothrow) AidlMessageQueueUnsync8(aidlDesc);
+    ASSERT_NE(nullptr, aidlFmq);
+    ASSERT_TRUE(aidlFmq->isValid());
+
+    // Can have multiple readers with unsync flavor
+    AidlMessageQueueUnsync8* aidlFmq2 = new (std::nothrow) AidlMessageQueueUnsync8(aidlDesc);
+    ASSERT_NE(nullptr, aidlFmq2);
+    ASSERT_TRUE(aidlFmq2->isValid());
+
+    // Make sure a write to the HIDL side, will show up for the AIDL side
+    constexpr size_t dataLen = 4;
+    uint8_t data[dataLen] = {12, 11, 10, 9};
+    fmq->write(data, dataLen);
+
+    int8_t readData[dataLen];
+    ASSERT_TRUE(aidlFmq->read(readData, dataLen));
+    int8_t readData2[dataLen];
+    ASSERT_TRUE(aidlFmq2->read(readData2, dataLen));
+
+    ASSERT_EQ(data[0], readData[0]);
+    ASSERT_EQ(data[1], readData[1]);
+    ASSERT_EQ(data[2], readData[2]);
+    ASSERT_EQ(data[3], readData[3]);
+    ASSERT_EQ(data[0], readData2[0]);
+    ASSERT_EQ(data[1], readData2[1]);
+    ASSERT_EQ(data[2], readData2[2]);
+    ASSERT_EQ(data[3], readData2[3]);
+}
+
+TEST_F(Hidl2AidlOperation, ConvertFdIndex1) {
+    native_handle_t* mqHandle = native_handle_create(2 /* numFds */, 0 /* numInts */);
+    if (mqHandle == nullptr) {
+        return;
+    }
+    mqHandle->data[0] = 12;
+    mqHandle->data[1] = 5;
+    ::android::hardware::hidl_vec<android::hardware::GrantorDescriptor> grantors;
+    grantors.resize(3);
+    grantors[0] = {0, 1 /* fdIndex */, 16, 16};
+    grantors[1] = {0, 1 /* fdIndex */, 16, 16};
+    grantors[2] = {0, 1 /* fdIndex */, 16, 16};
+
+    HidlMQDescUnsync8* hidlDesc = new (std::nothrow) HidlMQDescUnsync8(grantors, mqHandle, 10);
+    ASSERT_TRUE(hidlDesc->isHandleValid());
+
+    AidlMQDescUnsync8 aidlDesc;
+    bool ret = android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(
+            *hidlDesc, &aidlDesc);
+    ASSERT_TRUE(ret);
+}
+
+TEST_F(Hidl2AidlOperation, ConvertMultipleFds) {
+    native_handle_t* mqHandle = native_handle_create(2 /* numFds */, 0 /* numInts */);
+    if (mqHandle == nullptr) {
+        return;
+    }
+    mqHandle->data[0] = ::ashmem_create_region("ConvertMultipleFds", 8);
+    mqHandle->data[1] = ::ashmem_create_region("ConvertMultipleFds2", 8);
+    ::android::hardware::hidl_vec<android::hardware::GrantorDescriptor> grantors;
+    grantors.resize(3);
+    grantors[0] = {0, 1 /* fdIndex */, 16, 16};
+    grantors[1] = {0, 1 /* fdIndex */, 16, 16};
+    grantors[2] = {0, 0 /* fdIndex */, 16, 16};
+
+    HidlMQDescUnsync8* hidlDesc = new (std::nothrow) HidlMQDescUnsync8(grantors, mqHandle, 10);
+    ASSERT_TRUE(hidlDesc->isHandleValid());
+
+    AidlMQDescUnsync8 aidlDesc;
+    bool ret = android::unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, UnsynchronizedWrite>(
+            *hidlDesc, &aidlDesc);
+    ASSERT_TRUE(ret);
+    EXPECT_EQ(aidlDesc.handle.fds.size(), 2);
+    native_handle_close(mqHandle);
+    native_handle_delete(mqHandle);
+}
+
+// TODO(b/165674950) Since AIDL does not support unsigned integers, it can only support
+// 1/2 the queue size of HIDL. Once support is added to AIDL, this restriction can be
+// lifted. Until then, check against SSIZE_MAX instead of SIZE_MAX.
+TEST_F(AidlOnlyBadQueueConfig, QueueSizeTooLargeForAidl) {
+    size_t numElementsInQueue = SSIZE_MAX / sizeof(uint16_t) + 1;
+    AidlMessageQueueSync16* fmq = new (std::nothrow) AidlMessageQueueSync16(numElementsInQueue);
+    ASSERT_NE(nullptr, fmq);
+    /*
+     * Should fail due to size being too large to fit into size_t.
+     */
+    ASSERT_FALSE(fmq->isValid());
+}
+
+TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptor) {
+    aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
+    desc.quantum = -10;
+    AidlMessageQueueSync16* fmq = new (std::nothrow) AidlMessageQueueSync16(desc);
+    ASSERT_NE(nullptr, fmq);
+    /*
+     * Should fail due to quantum being negative.
+     */
+    ASSERT_FALSE(fmq->isValid());
+}
+
+TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptorGrantor) {
+    aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
+    desc.quantum = 2;
+    desc.flags = 0;
+    desc.grantors.push_back(
+            aidl::android::hardware::common::fmq::GrantorDescriptor{.offset = 12, .extent = -10});
+    AidlMessageQueueSync16* fmq = new (std::nothrow) AidlMessageQueueSync16(desc);
+    ASSERT_NE(nullptr, fmq);
+    /*
+     * Should fail due to grantor having negative extent.
+     */
+    ASSERT_FALSE(fmq->isValid());
+}
+
+/*
+ * Test creating a new queue from a modified MQDescriptor of another queue.
+ * If MQDescriptor.quantum doesn't match the size of the payload(T), the queue
+ * should be invalid.
+ */
+TEST_F(AidlOnlyBadQueueConfig, MismatchedPayloadSize) {
+    AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(64);
+    aidl::android::hardware::common::fmq::MQDescriptor<uint16_t, SynchronizedReadWrite> desc =
+            fmq.dupeDesc();
+    // This should work fine with the unmodified MQDescriptor
+    AidlMessageQueueSync16 fmq2 = AidlMessageQueueSync16(desc);
+    ASSERT_TRUE(fmq2.isValid());
+
+    // Simulate a difference in payload size between processes handling the queue
+    desc.quantum = 8;
+    AidlMessageQueueSync16 fmq3 = AidlMessageQueueSync16(desc);
+
+    // Should fail due to the quantum not matching the sizeof(uint16_t)
+    ASSERT_FALSE(fmq3.isValid());
+}
+
+/*
+ * Test creating a new queue with an invalid fd. This should assert with message
+ * "mRing is null".
+ */
+TEST_F(DoubleFdFailures, InvalidFd) {
+    EXPECT_DEATH_IF_SUPPORTED(AidlMessageQueueSync(64, false, android::base::unique_fd(3000), 64),
+                              "mRing is null");
+}
+
+/*
+ * Test creating a new queue with a buffer fd and bufferSize smaller than the
+ * requested queue. This should fail to create a valid message queue.
+ */
+TEST_F(DoubleFdFailures, InvalidFdSize) {
+    constexpr size_t kNumElementsInQueue = 1024;
+    constexpr size_t kRequiredDataBufferSize = kNumElementsInQueue * sizeof(uint16_t);
+    android::base::unique_fd ringbufferFd(
+            ::ashmem_create_region("SyncReadWrite", kRequiredDataBufferSize - 8));
+    AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(
+            kNumElementsInQueue, false, std::move(ringbufferFd), kRequiredDataBufferSize - 8);
+    EXPECT_FALSE(fmq.isValid());
+}
+
+/*
+ * Test creating a new queue with a buffer fd and bufferSize larger than the
+ * requested queue. The message queue should be valid.
+ */
+TEST_F(DoubleFdFailures, LargerFdSize) {
+    constexpr size_t kNumElementsInQueue = 1024;
+    constexpr size_t kRequiredDataBufferSize = kNumElementsInQueue * sizeof(uint16_t);
+    android::base::unique_fd ringbufferFd(
+            ::ashmem_create_region("SyncReadWrite", kRequiredDataBufferSize + 8));
+    AidlMessageQueueSync16 fmq = AidlMessageQueueSync16(
+            kNumElementsInQueue, false, std::move(ringbufferFd), kRequiredDataBufferSize + 8);
+    EXPECT_TRUE(fmq.isValid());
+}
+
+/*
+ * Test that basic blocking works. This test uses the non-blocking read()/write()
+ * APIs.
+ */
+TYPED_TEST(BlockingReadWrites, SmallInputTest1) {
+    const size_t dataLen = 64;
+    uint8_t data[dataLen] = {0};
+
+    android::hardware::EventFlag* efGroup = nullptr;
+    android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
+
+    ASSERT_EQ(android::NO_ERROR, status);
+    ASSERT_NE(nullptr, efGroup);
+
+    /*
+     * Start a thread that will try to read and block on kFmqNotEmpty.
+     */
+    std::thread Reader(BlockingReadWrites<TypeParam>::ReaderThreadBlocking, this->mQueue,
+                       &this->mFw);
+    struct timespec waitTime = {0, 100 * 1000000};
+    ASSERT_EQ(0, nanosleep(&waitTime, NULL));
+
+    /*
+     * After waiting for some time write into the FMQ
+     * and call Wake on kFmqNotEmpty.
+     */
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    status = efGroup->wake(kFmqNotEmpty);
+    ASSERT_EQ(android::NO_ERROR, status);
+
+    ASSERT_EQ(0, nanosleep(&waitTime, NULL));
+    Reader.join();
+
+    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * Test that basic blocking works. This test uses the
+ * writeBlocking()/readBlocking() APIs.
+ */
+TYPED_TEST(BlockingReadWrites, SmallInputTest2) {
+    const size_t dataLen = 64;
+    uint8_t data[dataLen] = {0};
+
+    android::hardware::EventFlag* efGroup = nullptr;
+    android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
+
+    ASSERT_EQ(android::NO_ERROR, status);
+    ASSERT_NE(nullptr, efGroup);
+
+    /*
+     * Start a thread that will try to read and block on kFmqNotEmpty. It will
+     * call wake() on kFmqNotFull when the read is successful.
+     */
+    std::thread Reader(BlockingReadWrites<TypeParam>::ReaderThreadBlocking2, this->mQueue,
+                       &this->mFw);
+    bool ret = this->mQueue->writeBlocking(data, dataLen, static_cast<uint32_t>(kFmqNotFull),
+                                           static_cast<uint32_t>(kFmqNotEmpty),
+                                           5000000000 /* timeOutNanos */, efGroup);
+    ASSERT_TRUE(ret);
+    Reader.join();
+
+    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * Test that basic blocking times out as intended.
+ */
+TYPED_TEST(BlockingReadWrites, BlockingTimeOutTest) {
+    android::hardware::EventFlag* efGroup = nullptr;
+    android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
+
+    ASSERT_EQ(android::NO_ERROR, status);
+    ASSERT_NE(nullptr, efGroup);
+
+    /* Block on an EventFlag bit that no one will wake and time out in 1s */
+    uint32_t efState = 0;
+    android::status_t ret = efGroup->wait(kFmqNotEmpty,
+                                          &efState,
+                                          1000000000 /* timeoutNanoSeconds */);
+    /*
+     * Wait should time out in a second.
+     */
+    EXPECT_EQ(android::TIMED_OUT, ret);
+
+    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+    ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * Test that odd queue sizes do not cause unaligned error
+ * on access to EventFlag object.
+ */
+TYPED_TEST(QueueSizeOdd, EventFlagTest) {
+    const size_t dataLen = 64;
+    uint8_t data[dataLen] = {0};
+
+    bool ret = this->mQueue->writeBlocking(data, dataLen, static_cast<uint32_t>(kFmqNotFull),
+                                           static_cast<uint32_t>(kFmqNotEmpty),
+                                           5000000000 /* timeOutNanos */);
+    ASSERT_TRUE(ret);
+}
+
+/*
+ * Verify that a few bytes of data can be successfully written and read.
+ */
+TYPED_TEST(SynchronizedReadWrites, SmallInputTest1) {
+    const size_t dataLen = 16;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    uint8_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    ASSERT_EQ(0, memcmp(data, readData, dataLen));
+}
+
+/*
+ * Verify that a few bytes of data can be successfully written and read using
+ * beginRead/beginWrite/CommitRead/CommitWrite
+ */
+TYPED_TEST(SynchronizedReadWrites, SmallInputTest2) {
+    const size_t dataLen = 16;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
+
+    ASSERT_TRUE(tx.copyTo(data, 0 /* startIdx */, dataLen));
+
+    ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
+
+    uint8_t readData[dataLen] = {};
+
+    ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
+
+    ASSERT_TRUE(tx.copyFrom(readData, 0 /* startIdx */, dataLen));
+
+    ASSERT_TRUE(this->mQueue->commitRead(dataLen));
+
+    ASSERT_EQ(0, memcmp(data, readData, dataLen));
+}
+
+/*
+ * Verify that a few bytes of data can be successfully written and read using
+ * beginRead/beginWrite/CommitRead/CommitWrite as well as getSlot().
+ */
+TYPED_TEST(SynchronizedReadWrites, SmallInputTest3) {
+    const size_t dataLen = 16;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
+
+    auto first = tx.getFirstRegion();
+    auto second = tx.getSecondRegion();
+
+    ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
+    for (size_t i = 0; i < dataLen; i++) {
+        uint8_t* ptr = tx.getSlot(i);
+        *ptr = data[i];
+    }
+
+    ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
+
+    uint8_t readData[dataLen] = {};
+
+    ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
+
+    first = tx.getFirstRegion();
+    second = tx.getSecondRegion();
+
+    ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
+
+    for (size_t i = 0; i < dataLen; i++) {
+        uint8_t* ptr = tx.getSlot(i);
+        readData[i] = *ptr;
+    }
+
+    ASSERT_TRUE(this->mQueue->commitRead(dataLen));
+
+    ASSERT_EQ(0, memcmp(data, readData, dataLen));
+}
+
+/*
+ * Verify that read() returns false when trying to read from an empty queue.
+ */
+TYPED_TEST(SynchronizedReadWrites, ReadWhenEmpty1) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 2;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t readData[dataLen];
+    ASSERT_FALSE(this->mQueue->read(readData, dataLen));
+}
+
+/*
+ * Verify that beginRead() returns a MemTransaction object with null pointers when trying
+ * to read from an empty queue.
+ */
+TYPED_TEST(SynchronizedReadWrites, ReadWhenEmpty2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 2;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_FALSE(this->mQueue->beginRead(dataLen, &tx));
+
+    auto first = tx.getFirstRegion();
+    auto second = tx.getSecondRegion();
+
+    ASSERT_EQ(nullptr, first.getAddress());
+    ASSERT_EQ(nullptr, second.getAddress());
+}
+
+/*
+ * Write the queue until full. Verify that another write is unsuccessful.
+ * Verify that availableToWrite() returns 0 as expected.
+ */
+TYPED_TEST(SynchronizedReadWrites, WriteWhenFull1) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_FALSE(this->mQueue->write(&data[0], 1));
+
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Write the queue until full. Verify that beginWrite() returns
+ * a MemTransaction object with null base pointers.
+ */
+TYPED_TEST(SynchronizedReadWrites, WriteWhenFull2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_FALSE(this->mQueue->beginWrite(1, &tx));
+
+    auto first = tx.getFirstRegion();
+    auto second = tx.getSecondRegion();
+
+    ASSERT_EQ(nullptr, first.getAddress());
+    ASSERT_EQ(nullptr, second.getAddress());
+}
+
+/*
+ * Write a chunk of data equal to the queue size.
+ * Verify that the write is successful and the subsequent read
+ * returns the expected data.
+ */
+TYPED_TEST(SynchronizedReadWrites, LargeInputTest1) {
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Attempt to write a chunk of data larger than the queue size.
+ * Verify that it fails. Verify that a subsequent read fails and
+ * the queue is still empty.
+ */
+TYPED_TEST(SynchronizedReadWrites, LargeInputTest2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 4096;
+    ASSERT_GT(dataLen, this->mNumMessagesMax);
+    std::vector<uint8_t> data(dataLen);
+
+    initData(&data[0], dataLen);
+    ASSERT_FALSE(this->mQueue->write(&data[0], dataLen));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_NE(data, readData);
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+}
+
+/*
+ * After the queue is full, try to write more data. Verify that
+ * the attempt returns false. Verify that the attempt did not
+ * affect the pre-existing data in the queue.
+ */
+TYPED_TEST(SynchronizedReadWrites, LargeInputTest3) {
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_FALSE(this->mQueue->write(&data[0], 1));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Verify that beginWrite() returns a MemTransaction with
+ * null base pointers when attempting to write data larger
+ * than the queue size.
+ */
+TYPED_TEST(SynchronizedReadWrites, LargeInputTest4) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 4096;
+    ASSERT_GT(dataLen, this->mNumMessagesMax);
+
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_FALSE(this->mQueue->beginWrite(dataLen, &tx));
+
+    auto first = tx.getFirstRegion();
+    auto second = tx.getSecondRegion();
+
+    ASSERT_EQ(nullptr, first.getAddress());
+    ASSERT_EQ(nullptr, second.getAddress());
+}
+
+/*
+ * Verify that multiple reads one after the other return expected data.
+ */
+TYPED_TEST(SynchronizedReadWrites, MultipleRead) {
+    const size_t chunkSize = 100;
+    const size_t chunkNum = 5;
+    const size_t dataLen = chunkSize * chunkNum;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    uint8_t readData[dataLen] = {};
+    for (size_t i = 0; i < chunkNum; i++) {
+        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
+    }
+    ASSERT_EQ(0, memcmp(readData, data, dataLen));
+}
+
+/*
+ * Verify that multiple writes one after the other happens correctly.
+ */
+TYPED_TEST(SynchronizedReadWrites, MultipleWrite) {
+    const int chunkSize = 100;
+    const int chunkNum = 5;
+    const size_t dataLen = chunkSize * chunkNum;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+    for (unsigned int i = 0; i < chunkNum; i++) {
+        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
+    }
+    uint8_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    ASSERT_EQ(0, memcmp(readData, data, dataLen));
+}
+
+/*
+ * Write enough messages into the FMQ to fill half of it
+ * and read back the same.
+ * Write this->mNumMessagesMax messages into the queue. This will cause a
+ * wrap around. Read and verify the data.
+ */
+TYPED_TEST(SynchronizedReadWrites, ReadWriteWrapAround1) {
+    size_t numMessages = this->mNumMessagesMax - 1;
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
+    ASSERT_TRUE(this->mQueue->read(&readData[0], numMessages));
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Use beginRead/CommitRead/beginWrite/commitWrite APIs
+ * to test wrap arounds are handled correctly.
+ * Write enough messages into the FMQ to fill half of it
+ * and read back the same.
+ * Write mNumMessagesMax messages into the queue. This will cause a
+ * wrap around. Read and verify the data.
+ */
+TYPED_TEST(SynchronizedReadWrites, ReadWriteWrapAround2) {
+    size_t dataLen = this->mNumMessagesMax - 1;
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], dataLen));
+    ASSERT_TRUE(this->mQueue->read(&readData[0], dataLen));
+
+    /*
+     * The next write and read will have to deal with with wrap arounds.
+     */
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(this->mNumMessagesMax, &tx));
+
+    auto first = tx.getFirstRegion();
+    auto second = tx.getSecondRegion();
+
+    ASSERT_EQ(first.getLength() + second.getLength(), this->mNumMessagesMax);
+
+    ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */, this->mNumMessagesMax));
+
+    ASSERT_TRUE(this->mQueue->commitWrite(this->mNumMessagesMax));
+
+    ASSERT_TRUE(this->mQueue->beginRead(this->mNumMessagesMax, &tx));
+
+    first = tx.getFirstRegion();
+    second = tx.getSecondRegion();
+
+    ASSERT_EQ(first.getLength() + second.getLength(), this->mNumMessagesMax);
+
+    ASSERT_TRUE(tx.copyFrom(&readData[0], 0 /* startIdx */, this->mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->commitRead(this->mNumMessagesMax));
+
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Verify that a few bytes of data can be successfully written and read.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, SmallInputTest1) {
+    const size_t dataLen = 16;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    uint8_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    ASSERT_EQ(0, memcmp(data, readData, dataLen));
+}
+
+/*
+ * Verify that read() returns false when trying to read from an empty queue.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, ReadWhenEmpty) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 2;
+    ASSERT_TRUE(dataLen < this->mNumMessagesMax);
+    uint8_t readData[dataLen];
+    ASSERT_FALSE(this->mQueue->read(readData, dataLen));
+}
+
+/*
+ * Write the queue when full. Verify that a subsequent writes is succesful.
+ * Verify that availableToWrite() returns 0 as expected.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, WriteWhenFull1) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_TRUE(this->mQueue->write(&data[0], 1));
+
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+}
+
+/*
+ * Write the queue when full. Verify that a subsequent writes
+ * using beginRead()/commitRead() is succesful.
+ * Verify that the next read fails as expected for unsynchronized flavor.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, WriteWhenFull2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(1, &tx));
+
+    ASSERT_EQ(tx.getFirstRegion().getLength(), 1U);
+
+    ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */));
+
+    ASSERT_TRUE(this->mQueue->commitWrite(1));
+
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+}
+
+/*
+ * Write a chunk of data equal to the queue size.
+ * Verify that the write is successful and the subsequent read
+ * returns the expected data.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, LargeInputTest1) {
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
+
+/*
+ * Attempt to write a chunk of data larger than the queue size.
+ * Verify that it fails. Verify that a subsequent read fails and
+ * the queue is still empty.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, LargeInputTest2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t dataLen = 4096;
+    ASSERT_GT(dataLen, this->mNumMessagesMax);
+    std::vector<uint8_t> data(dataLen);
+    initData(&data[0], dataLen);
+    ASSERT_FALSE(this->mQueue->write(&data[0], dataLen));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_NE(data, readData);
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+}
+
+/*
+ * After the queue is full, try to write more data. Verify that
+ * the attempt is succesful. Verify that the read fails
+ * as expected.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, LargeInputTest3) {
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->write(&data[0], 1));
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+    ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+}
+
+/*
+ * Verify that multiple reads one after the other return expected data.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, MultipleRead) {
+    const size_t chunkSize = 100;
+    const size_t chunkNum = 5;
+    const size_t dataLen = chunkSize * chunkNum;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+    initData(data, dataLen);
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    uint8_t readData[dataLen] = {};
+    for (size_t i = 0; i < chunkNum; i++) {
+        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
+    }
+    ASSERT_EQ(0, memcmp(readData, data, dataLen));
+}
+
+/*
+ * Verify that multiple writes one after the other happens correctly.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, MultipleWrite) {
+    const size_t chunkSize = 100;
+    const size_t chunkNum = 5;
+    const size_t dataLen = chunkSize * chunkNum;
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    uint8_t data[dataLen];
+
+    initData(data, dataLen);
+    for (size_t i = 0; i < chunkNum; i++) {
+        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
+    }
+
+    uint8_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    ASSERT_EQ(0, memcmp(readData, data, dataLen));
+}
+
+/*
+ * Write enough messages into the FMQ to fill half of it
+ * and read back the same.
+ * Write mNumMessagesMax messages into the queue. This will cause a
+ * wrap around. Read and verify the data.
+ */
+TYPED_TEST(UnsynchronizedWriteTest, ReadWriteWrapAround) {
+    size_t numMessages = this->mNumMessagesMax - 1;
+    std::vector<uint8_t> data(this->mNumMessagesMax);
+    std::vector<uint8_t> readData(this->mNumMessagesMax);
+
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
+    ASSERT_TRUE(this->mQueue->read(&readData[0], numMessages));
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+    ASSERT_EQ(data, readData);
+}
diff --git a/tests/mq_test.cpp b/tests/mq_test.cpp
deleted file mode 100644
index 96528d3..0000000
--- a/tests/mq_test.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * 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.
- */
-
-#include <asm-generic/mman.h>
-#include <gtest/gtest.h>
-#include <atomic>
-#include <cstdlib>
-#include <sstream>
-#include <thread>
-#include <fmq/MessageQueue.h>
-#include <fmq/EventFlag.h>
-
-enum EventFlagBits : uint32_t {
-    kFmqNotEmpty = 1 << 0,
-    kFmqNotFull = 1 << 1,
-};
-
-typedef android::hardware::MessageQueue<uint8_t, android::hardware::kSynchronizedReadWrite>
-          MessageQueueSync;
-typedef android::hardware::MessageQueue<uint8_t, android::hardware::kUnsynchronizedWrite>
-            MessageQueueUnsync;
-
-class SynchronizedReadWrites : public ::testing::Test {
-protected:
-    virtual void TearDown() {
-        delete mQueue;
-    }
-
-    virtual void SetUp() {
-        static constexpr size_t kNumElementsInQueue = 2048;
-        mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue);
-        ASSERT_NE(nullptr, mQueue);
-        ASSERT_TRUE(mQueue->isValid());
-        mNumMessagesMax = mQueue->getQuantumCount();
-        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
-    }
-
-    MessageQueueSync* mQueue = nullptr;
-    size_t mNumMessagesMax = 0;
-};
-
-class UnsynchronizedWrite : public ::testing::Test {
-protected:
-    virtual void TearDown() {
-        delete mQueue;
-    }
-
-    virtual void SetUp() {
-        static constexpr size_t kNumElementsInQueue = 2048;
-        mQueue = new (std::nothrow) MessageQueueUnsync(kNumElementsInQueue);
-        ASSERT_NE(nullptr, mQueue);
-        ASSERT_TRUE(mQueue->isValid());
-        mNumMessagesMax = mQueue->getQuantumCount();
-        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
-    }
-
-    MessageQueueUnsync* mQueue = nullptr;
-    size_t mNumMessagesMax = 0;
-};
-
-class BlockingReadWrites : public ::testing::Test {
-protected:
-    virtual void TearDown() {
-        delete mQueue;
-    }
-    virtual void SetUp() {
-        static constexpr size_t kNumElementsInQueue = 2048;
-        mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue);
-        ASSERT_NE(nullptr, mQueue);
-        ASSERT_TRUE(mQueue->isValid());
-        mNumMessagesMax = mQueue->getQuantumCount();
-        ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
-        /*
-         * Initialize the EventFlag word to indicate Queue is not full.
-         */
-        std::atomic_init(&mFw, static_cast<uint32_t>(kFmqNotFull));
-    }
-
-    MessageQueueSync* mQueue;
-    std::atomic<uint32_t> mFw;
-    size_t mNumMessagesMax = 0;
-};
-
-class QueueSizeOdd : public ::testing::Test {
-protected:
-  virtual void TearDown() {
-      delete mQueue;
-  }
-  virtual void SetUp() {
-      static constexpr size_t kNumElementsInQueue = 2049;
-      mQueue = new (std::nothrow) MessageQueueSync(kNumElementsInQueue,
-                                                   true /* configureEventFlagWord */);
-      ASSERT_NE(nullptr, mQueue);
-      ASSERT_TRUE(mQueue->isValid());
-      mNumMessagesMax = mQueue->getQuantumCount();
-      ASSERT_EQ(kNumElementsInQueue, mNumMessagesMax);
-      auto evFlagWordPtr = mQueue->getEventFlagWord();
-      ASSERT_NE(nullptr, evFlagWordPtr);
-      /*
-       * Initialize the EventFlag word to indicate Queue is not full.
-       */
-      std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(kFmqNotFull));
-  }
-
-  MessageQueueSync* mQueue;
-  size_t mNumMessagesMax = 0;
-};
-
-class BadQueueConfig: public ::testing::Test {
-};
-
-/*
- * Utility function to initialize data to be written to the FMQ
- */
-inline void initData(uint8_t* data, size_t count) {
-    for (size_t i = 0; i < count; i++) {
-        data[i] = i & 0xFF;
-    }
-}
-
-/*
- * This thread will attempt to read and block. When wait returns
- * it checks if the kFmqNotEmpty bit is actually set.
- * If the read is succesful, it signals Wake to kFmqNotFull.
- */
-void ReaderThreadBlocking(
-        android::hardware::MessageQueue<uint8_t,
-        android::hardware::kSynchronizedReadWrite>* fmq,
-        std::atomic<uint32_t>* fwAddr) {
-    const size_t dataLen = 64;
-    uint8_t data[dataLen];
-    android::hardware::EventFlag* efGroup = nullptr;
-    android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-    ASSERT_NE(nullptr, efGroup);
-
-    while (true) {
-        uint32_t efState = 0;
-        android::status_t ret = efGroup->wait(kFmqNotEmpty,
-                                              &efState,
-                                              5000000000 /* timeoutNanoSeconds */);
-        /*
-         * Wait should not time out here after 5s
-         */
-        ASSERT_NE(android::TIMED_OUT, ret);
-
-        if ((efState & kFmqNotEmpty) && fmq->read(data, dataLen)) {
-            efGroup->wake(kFmqNotFull);
-            break;
-        }
-    }
-
-    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-}
-
-/*
- * This thread will attempt to read and block using the readBlocking() API and
- * passes in a pointer to an EventFlag object.
- */
-void ReaderThreadBlocking2(
-        android::hardware::MessageQueue<uint8_t,
-        android::hardware::kSynchronizedReadWrite>* fmq,
-        std::atomic<uint32_t>* fwAddr) {
-    const size_t dataLen = 64;
-    uint8_t data[dataLen];
-    android::hardware::EventFlag* efGroup = nullptr;
-    android::status_t status = android::hardware::EventFlag::createEventFlag(fwAddr, &efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-    ASSERT_NE(nullptr, efGroup);
-    bool ret = fmq->readBlocking(data,
-                                 dataLen,
-                                 static_cast<uint32_t>(kFmqNotFull),
-                                 static_cast<uint32_t>(kFmqNotEmpty),
-                                 5000000000 /* timeOutNanos */,
-                                 efGroup);
-    ASSERT_TRUE(ret);
-    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-}
-
-
-TEST_F(BadQueueConfig, QueueSizeTooLarge) {
-    typedef android::hardware::MessageQueue<uint16_t, android::hardware::kSynchronizedReadWrite>
-            MessageQueueSync16;
-    size_t numElementsInQueue = SIZE_MAX / sizeof(uint16_t) + 1;
-    MessageQueueSync16 * fmq = new (std::nothrow) MessageQueueSync16(numElementsInQueue);
-    ASSERT_NE(nullptr, fmq);
-    /*
-     * Should fail due to size being too large to fit into size_t.
-     */
-    ASSERT_FALSE(fmq->isValid());
-}
-
-/*
- * Test that basic blocking works. This test uses the non-blocking read()/write()
- * APIs.
- */
-TEST_F(BlockingReadWrites, SmallInputTest1) {
-    const size_t dataLen = 64;
-    uint8_t data[dataLen] = {0};
-
-    android::hardware::EventFlag* efGroup = nullptr;
-    android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
-
-    ASSERT_EQ(android::NO_ERROR, status);
-    ASSERT_NE(nullptr, efGroup);
-
-    /*
-     * Start a thread that will try to read and block on kFmqNotEmpty.
-     */
-    std::thread Reader(ReaderThreadBlocking, mQueue, &mFw);
-    struct timespec waitTime = {0, 100 * 1000000};
-    ASSERT_EQ(0, nanosleep(&waitTime, NULL));
-
-    /*
-     * After waiting for some time write into the FMQ
-     * and call Wake on kFmqNotEmpty.
-     */
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    status = efGroup->wake(kFmqNotEmpty);
-    ASSERT_EQ(android::NO_ERROR, status);
-
-    ASSERT_EQ(0, nanosleep(&waitTime, NULL));
-    Reader.join();
-
-    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-}
-
-/*
- * Test that basic blocking works. This test uses the
- * writeBlocking()/readBlocking() APIs.
- */
-TEST_F(BlockingReadWrites, SmallInputTest2) {
-    const size_t dataLen = 64;
-    uint8_t data[dataLen] = {0};
-
-    android::hardware::EventFlag* efGroup = nullptr;
-    android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
-
-    ASSERT_EQ(android::NO_ERROR, status);
-    ASSERT_NE(nullptr, efGroup);
-
-    /*
-     * Start a thread that will try to read and block on kFmqNotEmpty. It will
-     * call wake() on kFmqNotFull when the read is successful.
-     */
-    std::thread Reader(ReaderThreadBlocking2, mQueue, &mFw);
-    bool ret = mQueue->writeBlocking(data,
-                                     dataLen,
-                                     static_cast<uint32_t>(kFmqNotFull),
-                                     static_cast<uint32_t>(kFmqNotEmpty),
-                                     5000000000 /* timeOutNanos */,
-                                     efGroup);
-    ASSERT_TRUE(ret);
-    Reader.join();
-
-    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-}
-
-/*
- * Test that basic blocking times out as intended.
- */
-TEST_F(BlockingReadWrites, BlockingTimeOutTest) {
-    android::hardware::EventFlag* efGroup = nullptr;
-    android::status_t status = android::hardware::EventFlag::createEventFlag(&mFw, &efGroup);
-
-    ASSERT_EQ(android::NO_ERROR, status);
-    ASSERT_NE(nullptr, efGroup);
-
-    /* Block on an EventFlag bit that no one will wake and time out in 1s */
-    uint32_t efState = 0;
-    android::status_t ret = efGroup->wait(kFmqNotEmpty,
-                                          &efState,
-                                          1000000000 /* timeoutNanoSeconds */);
-    /*
-     * Wait should time out in a second.
-     */
-    EXPECT_EQ(android::TIMED_OUT, ret);
-
-    status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
-    ASSERT_EQ(android::NO_ERROR, status);
-}
-
-/*
- * Test that odd queue sizes do not cause unaligned error
- * on access to EventFlag object.
- */
-TEST_F(QueueSizeOdd, EventFlagTest) {
-    const size_t dataLen = 64;
-    uint8_t data[dataLen] = {0};
-
-    bool ret = mQueue->writeBlocking(data,
-                                     dataLen,
-                                     static_cast<uint32_t>(kFmqNotFull),
-                                     static_cast<uint32_t>(kFmqNotEmpty),
-                                     5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
-}
-
-/*
- * Verify that a few bytes of data can be successfully written and read.
- */
-TEST_F(SynchronizedReadWrites, SmallInputTest1) {
-    const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    uint8_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
-    ASSERT_EQ(0, memcmp(data, readData, dataLen));
-}
-
-/*
- * Verify that a few bytes of data can be successfully written and read using
- * beginRead/beginWrite/CommitRead/CommitWrite
- */
-TEST_F(SynchronizedReadWrites, SmallInputTest2) {
-    const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
-
-    ASSERT_TRUE(tx.copyTo(data, 0 /* startIdx */, dataLen));
-
-    ASSERT_TRUE(mQueue->commitWrite(dataLen));
-
-    uint8_t readData[dataLen] = {};
-
-    ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
-
-    ASSERT_TRUE(tx.copyFrom(readData, 0 /* startIdx */, dataLen));
-
-    ASSERT_TRUE(mQueue->commitRead(dataLen));
-
-    ASSERT_EQ(0, memcmp(data, readData, dataLen));
-}
-
-/*
- * Verify that a few bytes of data can be successfully written and read using
- * beginRead/beginWrite/CommitRead/CommitWrite as well as getSlot().
- */
-TEST_F(SynchronizedReadWrites, SmallInputTest3) {
-    const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
-
-    auto first = tx.getFirstRegion();
-    auto second = tx.getSecondRegion();
-
-    ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
-    for (size_t i = 0; i < dataLen; i++) {
-        uint8_t* ptr = tx.getSlot(i);
-        *ptr = data[i];
-    }
-
-    ASSERT_TRUE(mQueue->commitWrite(dataLen));
-
-    uint8_t readData[dataLen] = {};
-
-    ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
-
-    first = tx.getFirstRegion();
-    second = tx.getSecondRegion();
-
-    ASSERT_EQ(first.getLength() + second.getLength(),  dataLen);
-
-    for (size_t i = 0; i < dataLen; i++) {
-        uint8_t* ptr = tx.getSlot(i);
-        readData[i] = *ptr;
-    }
-
-    ASSERT_TRUE(mQueue->commitRead(dataLen));
-
-    ASSERT_EQ(0, memcmp(data, readData, dataLen));
-}
-
-/*
- * Verify that read() returns false when trying to read from an empty queue.
- */
-TEST_F(SynchronizedReadWrites, ReadWhenEmpty1) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 2;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t readData[dataLen];
-    ASSERT_FALSE(mQueue->read(readData, dataLen));
-}
-
-/*
- * Verify that beginRead() returns a MemTransaction object with null pointers when trying
- * to read from an empty queue.
- */
-TEST_F(SynchronizedReadWrites, ReadWhenEmpty2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 2;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_FALSE(mQueue->beginRead(dataLen, &tx));
-
-    auto first = tx.getFirstRegion();
-    auto second = tx.getSecondRegion();
-
-    ASSERT_EQ(nullptr, first.getAddress());
-    ASSERT_EQ(nullptr, second.getAddress());
-}
-
-/*
- * Write the queue until full. Verify that another write is unsuccessful.
- * Verify that availableToWrite() returns 0 as expected.
- */
-TEST_F(SynchronizedReadWrites, WriteWhenFull1) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    std::vector<uint8_t> data(mNumMessagesMax);
-
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_FALSE(mQueue->write(&data[0], 1));
-
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Write the queue until full. Verify that beginWrite() returns
- * a MemTransaction object with null base pointers.
- */
-TEST_F(SynchronizedReadWrites, WriteWhenFull2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    std::vector<uint8_t> data(mNumMessagesMax);
-
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_FALSE(mQueue->beginWrite(1, &tx));
-
-    auto first = tx.getFirstRegion();
-    auto second = tx.getSecondRegion();
-
-    ASSERT_EQ(nullptr, first.getAddress());
-    ASSERT_EQ(nullptr, second.getAddress());
-}
-
-/*
- * Write a chunk of data equal to the queue size.
- * Verify that the write is successful and the subsequent read
- * returns the expected data.
- */
-TEST_F(SynchronizedReadWrites, LargeInputTest1) {
-    std::vector<uint8_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Attempt to write a chunk of data larger than the queue size.
- * Verify that it fails. Verify that a subsequent read fails and
- * the queue is still empty.
- */
-TEST_F(SynchronizedReadWrites, LargeInputTest2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 4096;
-    ASSERT_GT(dataLen, mNumMessagesMax);
-    std::vector<uint8_t> data(dataLen);
-
-    initData(&data[0], dataLen);
-    ASSERT_FALSE(mQueue->write(&data[0], dataLen));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_NE(data, readData);
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-}
-
-/*
- * After the queue is full, try to write more data. Verify that
- * the attempt returns false. Verify that the attempt did not
- * affect the pre-existing data in the queue.
- */
-TEST_F(SynchronizedReadWrites, LargeInputTest3) {
-    std::vector<uint8_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_FALSE(mQueue->write(&data[0], 1));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Verify that beginWrite() returns a MemTransaction with
- * null base pointers when attempting to write data larger
- * than the queue size.
- */
-TEST_F(SynchronizedReadWrites, LargeInputTest4) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 4096;
-    ASSERT_GT(dataLen, mNumMessagesMax);
-
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_FALSE(mQueue->beginWrite(dataLen, &tx));
-
-    auto first = tx.getFirstRegion();
-    auto second = tx.getSecondRegion();
-
-    ASSERT_EQ(nullptr, first.getAddress());
-    ASSERT_EQ(nullptr, second.getAddress());
-}
-
-/*
- * Verify that multiple reads one after the other return expected data.
- */
-TEST_F(SynchronizedReadWrites, MultipleRead) {
-    const size_t chunkSize = 100;
-    const size_t chunkNum = 5;
-    const size_t dataLen = chunkSize * chunkNum;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    uint8_t readData[dataLen] = {};
-    for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
-    }
-    ASSERT_EQ(0, memcmp(readData, data, dataLen));
-}
-
-/*
- * Verify that multiple writes one after the other happens correctly.
- */
-TEST_F(SynchronizedReadWrites, MultipleWrite) {
-    const int chunkSize = 100;
-    const int chunkNum = 5;
-    const size_t dataLen = chunkSize * chunkNum;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-    for (unsigned int i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
-    }
-    uint8_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
-    ASSERT_EQ(0, memcmp(readData, data, dataLen));
-}
-
-/*
- * Write enough messages into the FMQ to fill half of it
- * and read back the same.
- * Write mNumMessagesMax messages into the queue. This will cause a
- * wrap around. Read and verify the data.
- */
-TEST_F(SynchronizedReadWrites, ReadWriteWrapAround1) {
-    size_t numMessages = mNumMessagesMax - 1;
-    std::vector<uint8_t> data(mNumMessagesMax);
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], numMessages));
-    ASSERT_TRUE(mQueue->read(&readData[0], numMessages));
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Use beginRead/CommitRead/beginWrite/commitWrite APIs
- * to test wrap arounds are handled correctly.
- * Write enough messages into the FMQ to fill half of it
- * and read back the same.
- * Write mNumMessagesMax messages into the queue. This will cause a
- * wrap around. Read and verify the data.
- */
-TEST_F(SynchronizedReadWrites, ReadWriteWrapAround2) {
-    size_t dataLen = mNumMessagesMax - 1;
-    std::vector<uint8_t> data(mNumMessagesMax);
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], dataLen));
-    ASSERT_TRUE(mQueue->read(&readData[0], dataLen));
-
-    /*
-     * The next write and read will have to deal with with wrap arounds.
-     */
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(mNumMessagesMax, &tx));
-
-    auto first = tx.getFirstRegion();
-    auto second = tx.getSecondRegion();
-
-    ASSERT_EQ(first.getLength() + second.getLength(), mNumMessagesMax);
-
-    ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */,  mNumMessagesMax));
-
-    ASSERT_TRUE(mQueue->commitWrite(mNumMessagesMax));
-
-    ASSERT_TRUE(mQueue->beginRead(mNumMessagesMax, &tx));
-
-    first = tx.getFirstRegion();
-    second = tx.getSecondRegion();
-
-    ASSERT_EQ(first.getLength() + second.getLength(), mNumMessagesMax);
-
-    ASSERT_TRUE(tx.copyFrom(&readData[0], 0 /* startIdx */, mNumMessagesMax));
-    ASSERT_TRUE(mQueue->commitRead(mNumMessagesMax));
-
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Verify that a few bytes of data can be successfully written and read.
- */
-TEST_F(UnsynchronizedWrite, SmallInputTest1) {
-    const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    uint8_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
-    ASSERT_EQ(0, memcmp(data, readData, dataLen));
-}
-
-/*
- * Verify that read() returns false when trying to read from an empty queue.
- */
-TEST_F(UnsynchronizedWrite, ReadWhenEmpty) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 2;
-    ASSERT_TRUE(dataLen < mNumMessagesMax);
-    uint8_t readData[dataLen];
-    ASSERT_FALSE(mQueue->read(readData, dataLen));
-}
-
-/*
- * Write the queue when full. Verify that a subsequent writes is succesful.
- * Verify that availableToWrite() returns 0 as expected.
- */
-TEST_F(UnsynchronizedWrite, WriteWhenFull1) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    std::vector<uint8_t> data(mNumMessagesMax);
-
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_TRUE(mQueue->write(&data[0], 1));
-
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
-}
-
-/*
- * Write the queue when full. Verify that a subsequent writes
- * using beginRead()/commitRead() is succesful.
- * Verify that the next read fails as expected for unsynchronized flavor.
- */
-TEST_F(UnsynchronizedWrite, WriteWhenFull2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    std::vector<uint8_t> data(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-
-    MessageQueueUnsync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(1, &tx));
-
-    ASSERT_EQ(tx.getFirstRegion().getLength(), 1U);
-
-    ASSERT_TRUE(tx.copyTo(&data[0], 0 /* startIdx */));
-
-    ASSERT_TRUE(mQueue->commitWrite(1));
-
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
-}
-
-/*
- * Write a chunk of data equal to the queue size.
- * Verify that the write is successful and the subsequent read
- * returns the expected data.
- */
-TEST_F(UnsynchronizedWrite, LargeInputTest1) {
-    std::vector<uint8_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
-
-/*
- * Attempt to write a chunk of data larger than the queue size.
- * Verify that it fails. Verify that a subsequent read fails and
- * the queue is still empty.
- */
-TEST_F(UnsynchronizedWrite, LargeInputTest2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t dataLen = 4096;
-    ASSERT_GT(dataLen, mNumMessagesMax);
-    std::vector<uint8_t> data(dataLen);
-    initData(&data[0], dataLen);
-    ASSERT_FALSE(mQueue->write(&data[0], dataLen));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_NE(data, readData);
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-}
-
-/*
- * After the queue is full, try to write more data. Verify that
- * the attempt is succesful. Verify that the read fails
- * as expected.
- */
-TEST_F(UnsynchronizedWrite, LargeInputTest3) {
-    std::vector<uint8_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_TRUE(mQueue->write(&data[0], 1));
-    std::vector<uint8_t> readData(mNumMessagesMax);
-    ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
-}
-
-/*
- * Verify that multiple reads one after the other return expected data.
- */
-TEST_F(UnsynchronizedWrite, MultipleRead) {
-    const size_t chunkSize = 100;
-    const size_t chunkNum = 5;
-    const size_t dataLen = chunkSize * chunkNum;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-    initData(data, dataLen);
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    uint8_t readData[dataLen] = {};
-    for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
-    }
-    ASSERT_EQ(0, memcmp(readData, data, dataLen));
-}
-
-/*
- * Verify that multiple writes one after the other happens correctly.
- */
-TEST_F(UnsynchronizedWrite, MultipleWrite) {
-    const size_t chunkSize = 100;
-    const size_t chunkNum = 5;
-    const size_t dataLen = chunkSize * chunkNum;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint8_t data[dataLen];
-
-    initData(data, dataLen);
-    for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
-    }
-
-    uint8_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
-    ASSERT_EQ(0, memcmp(readData, data, dataLen));
-}
-
-/*
- * Write enough messages into the FMQ to fill half of it
- * and read back the same.
- * Write mNumMessagesMax messages into the queue. This will cause a
- * wrap around. Read and verify the data.
- */
-TEST_F(UnsynchronizedWrite, ReadWriteWrapAround) {
-    size_t numMessages = mNumMessagesMax - 1;
-    std::vector<uint8_t> data(mNumMessagesMax);
-    std::vector<uint8_t> readData(mNumMessagesMax);
-
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], numMessages));
-    ASSERT_TRUE(mQueue->read(&readData[0], numMessages));
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_EQ(data, readData);
-}
diff --git a/tests/msgq_test_client.cpp b/tests/msgq_test_client.cpp
index ce7e340..a6f1ccc 100644
--- a/tests/msgq_test_client.cpp
+++ b/tests/msgq_test_client.cpp
@@ -19,7 +19,13 @@
 #error "GTest did not detect pthread library."
 #endif
 
+#include <aidl/android/fmq/test/FixedParcelable.h>
+#include <aidl/android/fmq/test/ITestAidlMsgQ.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 #include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
+#include <fmq/AidlMessageQueue.h>
 #include <fmq/EventFlag.h>
 #include <fmq/MessageQueue.h>
 #include <hidl/ServiceManagement.h>
@@ -30,6 +36,9 @@
 using android::status_t;
 
 // generated
+using ::aidl::android::fmq::test::EventFlagBits;
+using ::aidl::android::fmq::test::FixedParcelable;
+using ::aidl::android::fmq::test::ITestAidlMsgQ;
 using android::hardware::tests::msgq::V1_0::ITestMsgQ;
 
 // libhidl
@@ -40,87 +49,258 @@
 using android::hardware::MQDescriptorUnsync;
 using android::hardware::details::waitForHwService;
 
-typedef MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync;
-typedef MessageQueue<uint16_t, kUnsynchronizedWrite> MessageQueueUnsync;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::kUnsynchronizedWrite;
 
-static sp<ITestMsgQ> waitGetTestService() {
-    // waitForHwService is required because ITestMsgQ is not in manifest.xml.
-    // "Real" HALs shouldn't be doing this.
-    waitForHwService(ITestMsgQ::descriptor, "default");
-    return ITestMsgQ::getService();
-}
+typedef android::AidlMessageQueue<int32_t, SynchronizedReadWrite> AidlMessageQueueSync;
+typedef android::AidlMessageQueue<int32_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
+typedef android::hardware::MessageQueue<int32_t, kSynchronizedReadWrite> MessageQueueSync;
+typedef android::hardware::MessageQueue<int32_t, kUnsynchronizedWrite> MessageQueueUnsync;
+static const std::string kServiceName = "BnTestAidlMsgQ";
+static constexpr size_t kNumElementsInSyncQueue = (PAGE_SIZE - 16) / sizeof(int32_t);
 
-class UnsynchronizedWriteClientMultiProcess : public ::testing::Test {
-   protected:
-    void getQueue(MessageQueueUnsync** fmq, sp<ITestMsgQ>* service, bool setupQueue) {
-        *service = waitGetTestService();
-        *fmq = nullptr;
-        if (*service == nullptr) return;
-        if (!(*service)->isRemote()) return;
-        (*service)->getFmqUnsyncWrite(setupQueue,
-                                      [fmq](bool ret, const MQDescriptorUnsync<uint16_t>& in) {
-                                          ASSERT_TRUE(ret);
-                                          *fmq = new (std::nothrow) MessageQueueUnsync(in);
-                                      });
-    }
+enum class SetupType {
+    SINGLE_FD,
+    DOUBLE_FD,
 };
 
-class SynchronizedReadWriteClient : public ::testing::Test {
-protected:
+template <typename T, SetupType setupType>
+class TestParamTypes {
+  public:
+    typedef T MQType;
+    static constexpr bool UserFd = setupType == SetupType::DOUBLE_FD;
+};
+
+// Run everything on both the AIDL and HIDL versions with one and two FDs
+typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync, SetupType::SINGLE_FD>,
+                         TestParamTypes<MessageQueueSync, SetupType::SINGLE_FD>,
+                         TestParamTypes<AidlMessageQueueSync, SetupType::DOUBLE_FD>,
+                         TestParamTypes<MessageQueueSync, SetupType::DOUBLE_FD>>
+        SyncTypes;
+typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync, SetupType::SINGLE_FD>,
+                         TestParamTypes<MessageQueueUnsync, SetupType::SINGLE_FD>,
+                         TestParamTypes<AidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
+                         TestParamTypes<MessageQueueUnsync, SetupType::DOUBLE_FD>>
+        UnsyncTypes;
+
+template <typename T>
+class ClientSyncTestBase : public ::testing::Test {};
+
+// Specialize for AIDL
+template <>
+class ClientSyncTestBase<AidlMessageQueueSync> : public ::testing::Test {
+  protected:
+    static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
+        const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
+        ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
+        return ITestAidlMsgQ::fromBinder(binder);
+    }
+    bool configureFmqSyncReadWrite(AidlMessageQueueSync* mq) {
+        bool result = false;
+        auto ret = mService->configureFmqSyncReadWrite(mq->dupeDesc(), &result);
+        return result && ret.isOk();
+    }
+    bool requestReadFmqSync(size_t dataLen) {
+        bool result = false;
+        auto ret = mService->requestReadFmqSync(dataLen, &result);
+        return result && ret.isOk();
+    }
+    bool requestWriteFmqSync(size_t dataLen) {
+        bool result = false;
+        auto ret = mService->requestWriteFmqSync(dataLen, &result);
+        return result && ret.isOk();
+    }
+
+    std::shared_ptr<ITestAidlMsgQ> mService;
+};
+
+// Specialize for HIDL
+template <>
+class ClientSyncTestBase<MessageQueueSync> : public ::testing::Test {
+  protected:
+    static sp<ITestMsgQ> waitGetTestService() {
+        android::hardware::details::setTrebleTestingOverride(true);
+        // waitForHwService is required because ITestMsgQ is not in manifest.xml.
+        // "Real" HALs shouldn't be doing this.
+        waitForHwService(ITestMsgQ::descriptor, "default");
+        return ITestMsgQ::getService();
+    }
+    bool configureFmqSyncReadWrite(MessageQueueSync* mq) {
+        auto ret = mService->configureFmqSyncReadWrite(*mq->getDesc());
+        return ret && ret.isOk();
+    }
+    bool requestReadFmqSync(size_t dataLen) {
+        auto ret = mService->requestReadFmqSync(dataLen);
+        return ret && ret.isOk();
+    }
+    bool requestWriteFmqSync(size_t dataLen) {
+        auto ret = mService->requestWriteFmqSync(dataLen);
+        return ret && ret.isOk();
+    }
+
+    sp<ITestMsgQ> mService;
+};
+
+template <typename T>
+class ClientUnsyncTestBase : public ::testing::Test {};
+
+// Specialize for AIDL
+template <>
+class ClientUnsyncTestBase<AidlMessageQueueUnsync> : public ::testing::Test {
+  protected:
+    static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
+        const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
+        ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
+        return ITestAidlMsgQ::fromBinder(binder);
+    }
+    bool getFmqUnsyncWrite(bool configureFmq, bool userFd, std::shared_ptr<ITestAidlMsgQ> service,
+                           AidlMessageQueueUnsync** queue) {
+        bool result = false;
+        aidl::android::hardware::common::fmq::MQDescriptor<int32_t, UnsynchronizedWrite> desc;
+        auto ret = service->getFmqUnsyncWrite(configureFmq, userFd, &desc, &result);
+        *queue = new (std::nothrow) AidlMessageQueueUnsync(desc);
+        return result && ret.isOk();
+    }
+
+    std::shared_ptr<ITestAidlMsgQ> getQueue(AidlMessageQueueUnsync** fmq, bool setupQueue,
+                                            bool userFd) {
+        std::shared_ptr<ITestAidlMsgQ> service = waitGetTestService();
+        if (service == nullptr) return nullptr;
+        getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
+        return service;
+    }
+
+    bool requestReadFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
+        bool result = false;
+        auto ret = service->requestReadFmqUnsync(dataLen, &result);
+        return result && ret.isOk();
+    }
+    bool requestWriteFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
+        bool result = false;
+        auto ret = service->requestWriteFmqUnsync(dataLen, &result);
+        return result && ret.isOk();
+    }
+    AidlMessageQueueUnsync* newQueue() {
+        if (mQueue->isValid())
+            return new (std::nothrow) AidlMessageQueueUnsync(mQueue->dupeDesc());
+        else
+            return nullptr;
+    }
+
+    std::shared_ptr<ITestAidlMsgQ> mService;
+    AidlMessageQueueUnsync* mQueue = nullptr;
+};
+
+// Specialize for HIDL
+template <>
+class ClientUnsyncTestBase<MessageQueueUnsync> : public ::testing::Test {
+  protected:
+    static sp<ITestMsgQ> waitGetTestService() {
+        android::hardware::details::setTrebleTestingOverride(true);
+        // waitForHwService is required because ITestMsgQ is not in manifest.xml.
+        // "Real" HALs shouldn't be doing this.
+        waitForHwService(ITestMsgQ::descriptor, "default");
+        return ITestMsgQ::getService();
+    }
+    bool getFmqUnsyncWrite(bool configureFmq, bool userFd, sp<ITestMsgQ> service,
+                           MessageQueueUnsync** queue) {
+        if (!service) {
+            return false;
+        }
+        service->getFmqUnsyncWrite(configureFmq, userFd,
+                                   [queue](bool ret, const MQDescriptorUnsync<int32_t>& in) {
+                                       ASSERT_TRUE(ret);
+                                       *queue = new (std::nothrow) MessageQueueUnsync(in);
+                                   });
+        return true;
+    }
+
+    sp<ITestMsgQ> getQueue(MessageQueueUnsync** fmq, bool setupQueue, bool userFd) {
+        sp<ITestMsgQ> service = waitGetTestService();
+        if (service == nullptr) return nullptr;
+        getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
+        return service;
+    }
+
+    bool requestReadFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
+        auto ret = service->requestReadFmqUnsync(dataLen);
+        return ret && ret.isOk();
+    }
+    bool requestWriteFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
+        auto ret = service->requestWriteFmqUnsync(dataLen);
+        return ret && ret.isOk();
+    }
+
+    MessageQueueUnsync* newQueue() {
+        return new (std::nothrow) MessageQueueUnsync(*mQueue->getDesc());
+    }
+
+    sp<ITestMsgQ> mService;
+    MessageQueueUnsync* mQueue = nullptr;
+};
+
+TYPED_TEST_CASE(UnsynchronizedWriteClientMultiProcess, UnsyncTypes);
+template <typename T>
+class UnsynchronizedWriteClientMultiProcess : public ClientUnsyncTestBase<typename T::MQType> {};
+
+TYPED_TEST_CASE(SynchronizedReadWriteClient, SyncTypes);
+template <typename T>
+class SynchronizedReadWriteClient : public ClientSyncTestBase<typename T::MQType> {
+  protected:
     virtual void TearDown() {
         delete mQueue;
     }
 
     virtual void SetUp() {
-        static constexpr size_t kNumElementsInQueue = 1024;
-        mService = waitGetTestService();
-        ASSERT_NE(mService, nullptr);
-        ASSERT_TRUE(mService->isRemote());
+        this->mService = this->waitGetTestService();
+        ASSERT_NE(this->mService, nullptr);
+        ASSERT_TRUE(this->mService->isRemote());
+        static constexpr size_t kSyncElementSizeBytes = sizeof(int32_t);
+        android::base::unique_fd ringbufferFd;
+        if (T::UserFd) {
+            ringbufferFd.reset(::ashmem_create_region(
+                    "SyncReadWrite", kNumElementsInSyncQueue * kSyncElementSizeBytes));
+        }
         // create a queue on the client side
-        mQueue = new (std::nothrow)
-            MessageQueueSync(kNumElementsInQueue, true /* configure event flag word */);
+        mQueue = new (std::nothrow) typename T::MQType(
+                kNumElementsInSyncQueue, true /* configure event flag word */,
+                std::move(ringbufferFd), kNumElementsInSyncQueue * kSyncElementSizeBytes);
         ASSERT_NE(nullptr, mQueue);
         ASSERT_TRUE(mQueue->isValid());
-        mNumMessagesMax = mQueue->getQuantumCount();
+        ASSERT_EQ(mQueue->getQuantumCount(), kNumElementsInSyncQueue);
 
         // tell server to set up the queue on its end
-        ASSERT_TRUE(mService->configureFmqSyncReadWrite(*mQueue->getDesc()));
+        ASSERT_TRUE(this->configureFmqSyncReadWrite(mQueue));
     }
 
-    sp<ITestMsgQ> mService;
-    MessageQueueSync* mQueue = nullptr;
-    size_t mNumMessagesMax = 0;
+    typename T::MQType* mQueue = nullptr;
 };
 
-class UnsynchronizedWriteClient : public ::testing::Test {
-protected:
-    virtual void TearDown() {
-        delete mQueue;
-    }
+TYPED_TEST_CASE(UnsynchronizedWriteClient, UnsyncTypes);
+template <typename T>
+class UnsynchronizedWriteClient : public ClientUnsyncTestBase<typename T::MQType> {
+  protected:
+    virtual void TearDown() { delete this->mQueue; }
 
     virtual void SetUp() {
-        mService = waitGetTestService();
-        ASSERT_NE(mService, nullptr);
-        ASSERT_TRUE(mService->isRemote());
-        mService->getFmqUnsyncWrite(true /* configureFmq */,
-                                    [this](bool ret, const MQDescriptorUnsync<uint16_t>& in) {
-                                        ASSERT_TRUE(ret);
-                                        mQueue = new (std::nothrow) MessageQueueUnsync(in);
-                                    });
-        ASSERT_NE(nullptr, mQueue);
-        ASSERT_TRUE(mQueue->isValid());
-        mNumMessagesMax = mQueue->getQuantumCount();
+        this->mService = this->waitGetTestService();
+        ASSERT_NE(this->mService, nullptr);
+        ASSERT_TRUE(this->mService->isRemote());
+        this->getFmqUnsyncWrite(true, false, this->mService, &this->mQueue);
+        ASSERT_NE(nullptr, this->mQueue);
+        ASSERT_TRUE(this->mQueue->isValid());
+        mNumMessagesMax = this->mQueue->getQuantumCount();
     }
 
-    sp<ITestMsgQ> mService;
-    MessageQueueUnsync*  mQueue = nullptr;
     size_t mNumMessagesMax = 0;
 };
 
 /*
  * Utility function to verify data read from the fast message queue.
  */
-bool verifyData(uint16_t* data, size_t count) {
+bool verifyData(int32_t* data, size_t count) {
     for (size_t i = 0; i < count; i++) {
         if (data[i] != i) return false;
     }
@@ -130,7 +310,7 @@
 /*
  * Utility function to initialize data to be written to the FMQ
  */
-inline void initData(uint16_t* data, size_t count) {
+inline void initData(int32_t* data, size_t count) {
     for (size_t i = 0; i < count; i++) {
         data[i] = i;
     }
@@ -140,33 +320,31 @@
  * Verify that for an unsynchronized flavor of FMQ, multiple readers
  * can recover from a write overflow condition.
  */
-TEST_F(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
+TYPED_TEST(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
     const size_t dataLen = 16;
 
     pid_t pid;
     /* creating first reader process */
     if ((pid = fork()) == 0) {
-        sp<ITestMsgQ> testService;
-        MessageQueueUnsync*  queue = nullptr;
-        getQueue(&queue, &testService, true /* setupQueue */);
-        ASSERT_NE(testService, nullptr);
-        ASSERT_TRUE(testService->isRemote());
+        typename TypeParam::MQType* queue = nullptr;
+        auto service =
+                this->getQueue(&queue, true /* setupQueue */, TypeParam::UserFd /* userFd */);
+        ASSERT_NE(service, nullptr);
+        ASSERT_TRUE(service->isRemote());
         ASSERT_NE(queue, nullptr);
         ASSERT_TRUE(queue->isValid());
 
         size_t numMessagesMax = queue->getQuantumCount();
 
         // The following two writes will cause a write overflow.
-        auto ret = testService->requestWriteFmqUnsync(numMessagesMax);
-        ASSERT_TRUE(ret.isOk());
+        auto ret = this->requestWriteFmqUnsync(numMessagesMax, service);
         ASSERT_TRUE(ret);
 
-        ret = testService->requestWriteFmqUnsync(1);
-        ASSERT_TRUE(ret.isOk());
+        ret = this->requestWriteFmqUnsync(1, service);
         ASSERT_TRUE(ret);
 
         // The following read should fail due to the overflow.
-        std::vector<uint16_t> readData(numMessagesMax);
+        std::vector<int32_t> readData(numMessagesMax);
         ASSERT_FALSE(queue->read(&readData[0], numMessagesMax));
 
         /*
@@ -174,8 +352,7 @@
          * overflow condition.
          */
         ASSERT_LT(dataLen, numMessagesMax);
-        ret = testService->requestWriteFmqUnsync(dataLen);
-        ASSERT_TRUE(ret.isOk());
+        ret = this->requestWriteFmqUnsync(dataLen, service);
         ASSERT_TRUE(ret);
 
         // Verify that the read is successful.
@@ -194,25 +371,22 @@
 
     // creating second reader process.
     if ((pid = fork()) == 0) {
-        sp<ITestMsgQ> testService;
-        MessageQueueUnsync* queue = nullptr;
-
-        getQueue(&queue, &testService, false /* setupQueue */);
-        ASSERT_NE(testService, nullptr);
-        ASSERT_TRUE(testService->isRemote());
+        typename TypeParam::MQType* queue = nullptr;
+        auto service = this->getQueue(&queue, false /* setupQueue */, false /* userFd */);
+        ASSERT_NE(service, nullptr);
+        ASSERT_TRUE(service->isRemote());
         ASSERT_NE(queue, nullptr);
         ASSERT_TRUE(queue->isValid());
 
         // This read should fail due to the write overflow.
-        std::vector<uint16_t> readData(dataLen);
+        std::vector<int32_t> readData(dataLen);
         ASSERT_FALSE(queue->read(&readData[0], dataLen));
 
         /*
          * Request another write to verify that the process that recover from
          * the overflow condition.
          */
-        auto ret = testService->requestWriteFmqUnsync(dataLen);
-        ASSERT_TRUE(ret.isOk());
+        auto ret = this->requestWriteFmqUnsync(dataLen, service);
         ASSERT_TRUE(ret);
 
         // verify that the read is successful.
@@ -231,26 +405,32 @@
  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
  * using the EventFlag object owned by FMQ.
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWrite1) {
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite1) {
     const size_t dataLen = 64;
-    uint16_t data[dataLen] = {0};
-
+    bool ret = false;
     /*
      * Request service to perform a blocking read. This call is oneway and will
      * return immediately.
      */
-    mService->requestBlockingRead(dataLen);
-    bool ret = mQueue->writeBlocking(data,
-                                     dataLen,
-                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                     5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
-    ret = mQueue->writeBlocking(data, mNumMessagesMax,
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
+    this->mService->requestBlockingRead(dataLen);
+    {
+        std::array<int32_t, dataLen> data = {0};
+        ret = this->mQueue->writeBlocking(
+                data.data(), data.size(),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
+        ASSERT_TRUE(ret);
+    }
+    {
+        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+        ret = this->mQueue->writeBlocking(
+                data.data(), data.size(),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
+        ASSERT_TRUE(ret);
+    }
 }
 
 /*
@@ -258,30 +438,34 @@
  * using the EventFlag object owned by FMQ and using the default EventFlag
  * notification bit mask.
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWrite2) {
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite2) {
     const size_t dataLen = 64;
-    std::vector<uint16_t> data(mNumMessagesMax);
+    bool ret = false;
 
     /*
      * Request service to perform a blocking read using default EventFlag
      * notification bit mask. This call is oneway and will
      * return immediately.
      */
-    mService->requestBlockingReadDefaultEventFlagBits(dataLen);
+    this->mService->requestBlockingReadDefaultEventFlagBits(dataLen);
 
     /* Cause a context switch to allow service to block */
     sched_yield();
-
-    bool ret = mQueue->writeBlocking(&data[0],
-                                     dataLen);
-    ASSERT_TRUE(ret);
+    {
+        std::array<int32_t, dataLen> data = {0};
+        ret = this->mQueue->writeBlocking(data.data(), data.size());
+        ASSERT_TRUE(ret);
+    }
 
     /*
      * If the blocking read was successful, another write of size
-     * mNumMessagesMax will succeed.
+     * kNumElementsInSyncQueue will succeed.
      */
-    ret = mQueue->writeBlocking(&data[0], mNumMessagesMax, 5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
+    {
+        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+        ret = this->mQueue->writeBlocking(data.data(), data.size(), 5000000000 /* timeOutNanos */);
+        ASSERT_TRUE(ret);
+    }
 }
 
 /*
@@ -290,32 +474,44 @@
  * Each write operation writes the same amount of data as a single read
  * operation.
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
     const size_t dataLen = 64;
-    uint16_t data[dataLen] = {0};
     bool ret = false;
 
     /*
-     * Request service to perform a blocking read. This call is oneway and will
-     * return immediately.
+     * Request service to perform a blocking read of 64 elements. This call is
+     * oneway and will return immediately.
      */
-    const size_t writeCount = 1024;
-    mService->requestBlockingReadRepeat(dataLen, writeCount);
+    const size_t writeCount = kNumElementsInSyncQueue;
+    this->mService->requestBlockingReadRepeat(dataLen, writeCount);
+    /*
+     * Write 64 elements into the queue for the service to consume
+     */
+    {
+        std::array<int32_t, dataLen> data = {0};
+        for (size_t i = 0; i < writeCount; i++) {
+            ret = this->mQueue->writeBlocking(
+                    data.data(), data.size(),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                    5000000000 /* timeOutNanos */);
+            ASSERT_TRUE(ret);
+        }
+    }
+    /*
+     * The queue should be totally empty now, so filling it up entirely with one
+     * blocking write should be successful.
+     */
+    {
+        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+        ret = this->mQueue->writeBlocking(
+                data.data(), data.size(),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
 
-    for (size_t i = 0; i < writeCount; i++) {
-        ret = mQueue->writeBlocking(data, dataLen,
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                    5000000000 /* timeOutNanos */);
         ASSERT_TRUE(ret);
     }
-
-    ret = mQueue->writeBlocking(data, mNumMessagesMax,
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                5000000000 /* timeOutNanos */);
-
-    ASSERT_TRUE(ret);
 }
 
 /*
@@ -324,31 +520,43 @@
  * amount of data as a single write.
  *
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
     const size_t dataLen = 64;
-    uint16_t data[dataLen] = {0};
     bool ret = false;
-
     /*
-     * Request service to perform a blocking read. This call is oneway and will
-     * return immediately.
+     * Request service to perform a repeated blocking read. This call is oneway
+     * and will return immediately. It will read 64 * 2 elements with each
+     * blocking read, for a total of writeCount / 2 calls.
      */
-    const size_t writeCount = 1024;
-    mService->requestBlockingReadRepeat(dataLen*2, writeCount/2);
-
-    for (size_t i = 0; i < writeCount; i++) {
-        ret = mQueue->writeBlocking(data, dataLen,
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                    5000000000 /* timeOutNanos */);
+    const size_t writeCount = kNumElementsInSyncQueue;
+    this->mService->requestBlockingReadRepeat(dataLen * 2, writeCount / 2);
+    /*
+     * Write 64 elements into the queue writeCount times
+     */
+    {
+        std::array<int32_t, dataLen> data = {0};
+        for (size_t i = 0; i < writeCount; i++) {
+            ret = this->mQueue->writeBlocking(
+                    data.data(), data.size(),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                    5000000000 /* timeOutNanos */);
+            ASSERT_TRUE(ret);
+        }
+    }
+    /*
+     * The queue should be totally empty now, so filling it up entirely with one
+     * blocking write should be successful.
+     */
+    {
+        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+        ret = this->mQueue->writeBlocking(
+                data.data(), data.size(),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
         ASSERT_TRUE(ret);
     }
-
-    ret = mQueue->writeBlocking(data, mNumMessagesMax,
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
 }
 
 /*
@@ -356,56 +564,67 @@
  * using the EventFlag object owned by FMQ. Each write operation writes twice
  * the amount of data as a single read.
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
     const size_t dataLen = 64;
-    uint16_t data[dataLen] = {0};
     bool ret = false;
 
     /*
-     * Request service to perform a blocking read. This call is oneway and will
-     * return immediately.
+     * Request service to perform a repeated blocking read. This call is oneway
+     * and will return immediately. It will read 64 / 2 elements with each
+     * blocking read, for a total of writeCount * 2 calls.
      */
     size_t writeCount = 1024;
-    mService->requestBlockingReadRepeat(dataLen/2, writeCount*2);
-
-    for (size_t i = 0; i < writeCount; i++) {
-        ret = mQueue->writeBlocking(data, dataLen,
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                    5000000000 /* timeOutNanos */);
+    this->mService->requestBlockingReadRepeat(dataLen / 2, writeCount * 2);
+    /*
+     * Write 64 elements into the queue writeCount times
+     */
+    {
+        std::array<int32_t, dataLen> data = {0};
+        for (size_t i = 0; i < writeCount; i++) {
+            ret = this->mQueue->writeBlocking(
+                    data.data(), data.size(),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                    static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                    5000000000 /* timeOutNanos */);
+            ASSERT_TRUE(ret);
+        }
+    }
+    /*
+     * The queue should be totally empty now, so filling it up entirely with one
+     * blocking write should be successful.
+     */
+    {
+        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+        ret = this->mQueue->writeBlocking(
+                data.data(), data.size(),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
         ASSERT_TRUE(ret);
     }
-    ret = mQueue->writeBlocking(data, mNumMessagesMax,
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
-                                5000000000 /* timeOutNanos */);
-    ASSERT_TRUE(ret);
 }
 
 /*
  * Test that writeBlocking()/readBlocking() APIs do not block on
  * attempts to write/read 0 messages and return true.
  */
-TEST_F(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
-    uint16_t data = 0;
+TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
+    int32_t data = 0;
 
     /*
      * Trigger a blocking write for zero messages with no timeout.
      */
-    bool ret = mQueue->writeBlocking(
-            &data,
-            0,
-            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+    bool ret = this->mQueue->writeBlocking(
+            &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
     ASSERT_TRUE(ret);
 
     /*
      * Trigger a blocking read for zero messages with no timeout.
      */
-    ret = mQueue->readBlocking(&data,
-                               0,
-                               static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-                               static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
+    ret = this->mQueue->readBlocking(
+            &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
     ASSERT_TRUE(ret);
 }
 
@@ -413,31 +632,70 @@
  * Request mService to write a small number of messages
  * to the FMQ. Read and verify data.
  */
-TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest1) {
+TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    bool ret = mService->requestWriteFmqSync(dataLen);
+    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
+    bool ret = this->requestWriteFmqSync(dataLen);
     ASSERT_TRUE(ret);
-    uint16_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
+    int32_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
     ASSERT_TRUE(verifyData(readData, dataLen));
 }
 
 /*
+ * Request mService to write a message to the queue followed by a beginRead().
+ * Get a pointer to the memory region for the that first message. Set the write
+ * counter to the last byte in the ring buffer. Request another write from
+ * mService. The write should fail because the write address is misaligned.
+ */
+TYPED_TEST(SynchronizedReadWriteClient, MisalignedWriteCounter) {
+    if (TypeParam::UserFd) {
+        // When using the second FD for the ring buffer, we can't get to the read/write
+        // counters from a pointer to the ring buffer, so no sense in testing.
+        GTEST_SKIP();
+    }
+    const size_t dataLen = 1;
+    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
+    bool ret = this->requestWriteFmqSync(dataLen);
+    ASSERT_TRUE(ret);
+    // begin read and get a MemTransaction object for the first object in the queue
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
+    // get a pointer to the beginning of the ring buffer
+    const auto& region = tx.getFirstRegion();
+    int32_t* firstStart = region.getAddress();
+
+    // because this is the first location in the ring buffer, we can get
+    // access to the read and write pointer stored in the fd. 8 bytes back for the
+    // write counter and 16 bytes back for the read counter
+    uint64_t* writeCntr = (uint64_t*)((uint8_t*)firstStart - 8);
+
+    // set it to point to the very last byte in the ring buffer
+    *(writeCntr) = this->mQueue->getQuantumCount() * this->mQueue->getQuantumSize() - 1;
+    ASSERT_TRUE(*writeCntr % sizeof(int32_t) != 0);
+
+    // this is not actually necessary, but it's the expected the pattern.
+    this->mQueue->commitRead(dataLen);
+
+    // This next write will be misaligned and will overlap outside of the ring buffer.
+    // The write should fail.
+    ret = this->requestWriteFmqSync(dataLen);
+    EXPECT_FALSE(ret);
+}
+
+/*
  * Request mService to write a small number of messages
  * to the FMQ. Read and verify each message using
  * beginRead/Commit read APIs.
  */
-TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest2) {
+TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest2) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    auto ret = mService->requestWriteFmqSync(dataLen);
-
-    ASSERT_TRUE(ret.isOk());
+    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
+    auto ret = this->requestWriteFmqSync(dataLen);
     ASSERT_TRUE(ret);
 
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
 
     auto first = tx.getFirstRegion();
     auto second = tx.getSecondRegion();
@@ -451,46 +709,46 @@
         }
     }
 
-    ASSERT_TRUE(mQueue->commitRead(dataLen));
+    ASSERT_TRUE(this->mQueue->commitRead(dataLen));
 }
 
 /*
  * Write a small number of messages to FMQ. Request
- * mService to read and verify that the write was succesful.
+ * mService to read and verify that the write was successful.
  */
-TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest1) {
+TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    size_t originalCount = mQueue->availableToWrite();
-    uint16_t data[dataLen];
+    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
+    size_t originalCount = this->mQueue->availableToWrite();
+    int32_t data[dataLen];
     initData(data, dataLen);
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    bool ret = mService->requestReadFmqSync(dataLen);
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    bool ret = this->requestReadFmqSync(dataLen);
     ASSERT_TRUE(ret);
-    size_t availableCount = mQueue->availableToWrite();
+    size_t availableCount = this->mQueue->availableToWrite();
     ASSERT_EQ(originalCount, availableCount);
 }
 
 /*
  * Write a small number of messages to FMQ using the beginWrite()/CommitWrite()
- * APIs. Request mService to read and verify that the write was succesful.
+ * APIs. Request mService to read and verify that the write was successful.
  */
-TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest2) {
+TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest2) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    size_t originalCount = mQueue->availableToWrite();
-    uint16_t data[dataLen];
+    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
+    size_t originalCount = this->mQueue->availableToWrite();
+    int32_t data[dataLen];
     initData(data, dataLen);
 
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
 
     auto first = tx.getFirstRegion();
     auto second = tx.getSecondRegion();
 
     size_t firstRegionLength = first.getLength();
-    uint16_t* firstBaseAddress = first.getAddress();
-    uint16_t* secondBaseAddress = second.getAddress();
+    int32_t* firstBaseAddress = first.getAddress();
+    int32_t* secondBaseAddress = second.getAddress();
 
     for (size_t i = 0; i < dataLen; i++) {
         if (i < firstRegionLength) {
@@ -500,24 +758,24 @@
         }
     }
 
-    ASSERT_TRUE(mQueue->commitWrite(dataLen));
+    ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
 
-    auto ret = mService->requestReadFmqSync(dataLen);
-    ASSERT_TRUE(ret.isOk());
+    auto ret = this->requestReadFmqSync(dataLen);
+    // ASSERT_TRUE(ret.isOk());
     ASSERT_TRUE(ret);
-    size_t availableCount = mQueue->availableToWrite();
+    size_t availableCount = this->mQueue->availableToWrite();
     ASSERT_EQ(originalCount, availableCount);
 }
 
 /*
  * Verify that the FMQ is empty and read fails when it is empty.
  */
-TEST_F(SynchronizedReadWriteClient, ReadWhenEmpty) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
+TYPED_TEST(SynchronizedReadWriteClient, ReadWhenEmpty) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
     const size_t numMessages = 2;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    uint16_t readData[numMessages];
-    ASSERT_FALSE(mQueue->read(readData, numMessages));
+    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
+    int32_t readData[numMessages];
+    ASSERT_FALSE(this->mQueue->read(readData, numMessages));
 }
 
 /*
@@ -525,17 +783,16 @@
  * Write enough messages to fill it.
  * Verify availableToWrite() method returns is zero.
  * Try writing another message and verify that
- * the attempted write was unsuccesful. Request mService
+ * the attempted write was unsuccessful. Request mService
  * to read and verify the messages in the FMQ.
  */
-
-TEST_F(SynchronizedReadWriteClient, WriteWhenFull) {
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_FALSE(mQueue->write(&data[0], 1));
-    bool ret = mService->requestReadFmqSync(mNumMessagesMax);
+TYPED_TEST(SynchronizedReadWriteClient, WriteWhenFull) {
+    std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+    initData(data.data(), data.size());
+    ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_FALSE(this->mQueue->write(&data[0], 1));
+    bool ret = this->requestReadFmqSync(data.size());
     ASSERT_TRUE(ret);
 }
 
@@ -544,12 +801,12 @@
  * Request mService to write data equal to queue size.
  * Read and verify data in mQueue.
  */
-TEST_F(SynchronizedReadWriteClient, LargeInputTest1) {
-    bool ret = mService->requestWriteFmqSync(mNumMessagesMax);
+TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest1) {
+    bool ret = this->requestWriteFmqSync(kNumElementsInSyncQueue);
     ASSERT_TRUE(ret);
-    std::vector<uint16_t> readData(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
-    ASSERT_TRUE(verifyData(&readData[0], mNumMessagesMax));
+    std::vector<int32_t> readData(kNumElementsInSyncQueue);
+    ASSERT_TRUE(this->mQueue->read(&readData[0], kNumElementsInSyncQueue));
+    ASSERT_TRUE(verifyData(&readData[0], kNumElementsInSyncQueue));
 }
 
 /*
@@ -557,15 +814,15 @@
  * Verify that the write fails. Verify that availableToRead() method
  * still returns 0 and verify that attempt to read fails.
  */
-TEST_F(SynchronizedReadWriteClient, LargeInputTest2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
+TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
     const size_t numMessages = 2048;
-    ASSERT_GT(numMessages, mNumMessagesMax);
-    bool ret = mService->requestWriteFmqSync(numMessages);
+    ASSERT_GT(numMessages, kNumElementsInSyncQueue);
+    bool ret = this->requestWriteFmqSync(numMessages);
     ASSERT_FALSE(ret);
-    uint16_t readData;
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    ASSERT_FALSE(mQueue->read(&readData, 1));
+    int32_t readData;
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    ASSERT_FALSE(this->mQueue->read(&readData, 1));
 }
 
 /*
@@ -576,14 +833,14 @@
  * Request mService to read. Verify read count.
  */
 
-TEST_F(SynchronizedReadWriteClient, LargeInputTest3) {
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_FALSE(mQueue->write(&data[0], 1));
+TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest3) {
+    std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+    initData(data.data(), data.size());
+    ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_FALSE(this->mQueue->write(data.data(), 1));
 
-    bool ret = mService->requestReadFmqSync(mNumMessagesMax);
+    bool ret = this->requestReadFmqSync(data.size());
     ASSERT_TRUE(ret);
 }
 
@@ -591,19 +848,19 @@
  * Confirm that the FMQ is empty. Request mService to write to FMQ.
  * Do multiple reads to empty FMQ and verify data.
  */
-TEST_F(SynchronizedReadWriteClient, MultipleRead) {
+TYPED_TEST(SynchronizedReadWriteClient, MultipleRead) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    size_t availableToRead = mQueue->availableToRead();
+    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
+    size_t availableToRead = this->mQueue->availableToRead();
     size_t expectedCount = 0;
     ASSERT_EQ(expectedCount, availableToRead);
-    bool ret = mService->requestWriteFmqSync(numMessages);
+    bool ret = this->requestWriteFmqSync(numMessages);
     ASSERT_TRUE(ret);
-    uint16_t readData[numMessages] = {};
+    int32_t readData[numMessages] = {};
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
+        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
     }
     ASSERT_TRUE(verifyData(readData, numMessages));
 }
@@ -612,18 +869,18 @@
  * Write to FMQ in bursts.
  * Request mService to read data. Verify the read was successful.
  */
-TEST_F(SynchronizedReadWriteClient, MultipleWrite) {
+TYPED_TEST(SynchronizedReadWriteClient, MultipleWrite) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    uint16_t data[numMessages];
+    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
+    int32_t data[numMessages];
     initData(&data[0], numMessages);
 
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
+        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
     }
-    bool ret = mService->requestReadFmqSync(numMessages);
+    bool ret = this->requestReadFmqSync(numMessages);
     ASSERT_TRUE(ret);
 }
 
@@ -633,15 +890,15 @@
  * Write mNumMessagesMax messages into the queue. This should cause a
  * wrap around. Request mService to read and verify the data.
  */
-TEST_F(SynchronizedReadWriteClient, ReadWriteWrapAround) {
-    size_t numMessages = mNumMessagesMax / 2;
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], numMessages));
-    bool ret = mService->requestReadFmqSync(numMessages);
+TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround) {
+    size_t numMessages = kNumElementsInSyncQueue / 2;
+    std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+    initData(data.data(), data.size());
+    ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
+    bool ret = this->requestReadFmqSync(numMessages);
     ASSERT_TRUE(ret);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ret = mService->requestReadFmqSync(mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
+    ret = this->requestReadFmqSync(data.size());
     ASSERT_TRUE(ret);
 }
 
@@ -653,74 +910,70 @@
  * Write mNumMessagesMax messages into the queue. This will cause a
  * wrap around. Read and verify the data.
  */
-TEST_F(SynchronizedReadWriteClient, ReadWriteWrapAround2) {
-    size_t numMessages = mNumMessagesMax / 2;
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], numMessages));
-    auto ret = mService->requestReadFmqSync(numMessages);
-
-    ASSERT_TRUE(ret.isOk());
+TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround2) {
+    size_t numMessages = kNumElementsInSyncQueue / 2;
+    std::array<int32_t, kNumElementsInSyncQueue> data = {0};
+    initData(data.data(), data.size());
+    ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
+    auto ret = this->requestReadFmqSync(numMessages);
     ASSERT_TRUE(ret);
 
     /*
      * The next write and read will have to deal with with wrap arounds.
      */
-    MessageQueueSync::MemTransaction tx;
-    ASSERT_TRUE(mQueue->beginWrite(mNumMessagesMax, &tx));
+    typename TypeParam::MQType::MemTransaction tx;
+    ASSERT_TRUE(this->mQueue->beginWrite(data.size(), &tx));
 
-    ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(),  mNumMessagesMax);
+    ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(), data.size());
 
-    for (size_t i = 0; i < mNumMessagesMax; i++) {
-        uint16_t* ptr = tx.getSlot(i);
+    for (size_t i = 0; i < data.size(); i++) {
+        int32_t* ptr = tx.getSlot(i);
         *ptr = data[i];
     }
 
-    ASSERT_TRUE(mQueue->commitWrite(mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->commitWrite(data.size()));
 
-    ret = mService->requestReadFmqSync(mNumMessagesMax);
-
-    ASSERT_TRUE(ret.isOk());
+    ret = this->requestReadFmqSync(data.size());
     ASSERT_TRUE(ret);
 }
 
 /*
- * Request mService to write a small number of messages
+ * Request this->mService to write a small number of messages
  * to the FMQ. Read and verify data.
  */
-TEST_F(UnsynchronizedWriteClient, SmallInputReaderTest1) {
+TYPED_TEST(UnsynchronizedWriteClient, SmallInputReaderTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    bool ret = mService->requestWriteFmqUnsync(dataLen);
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
     ASSERT_TRUE(ret);
-    uint16_t readData[dataLen] = {};
-    ASSERT_TRUE(mQueue->read(readData, dataLen));
+    int32_t readData[dataLen] = {};
+    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
     ASSERT_TRUE(verifyData(readData, dataLen));
 }
 
 /*
  * Write a small number of messages to FMQ. Request
- * mService to read and verify that the write was succesful.
+ * this->mService to read and verify that the write was successful.
  */
-TEST_F(UnsynchronizedWriteClient, SmallInputWriterTest1) {
+TYPED_TEST(UnsynchronizedWriteClient, SmallInputWriterTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
-    uint16_t data[dataLen];
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    int32_t data[dataLen];
     initData(data, dataLen);
-    ASSERT_TRUE(mQueue->write(data, dataLen));
-    bool ret = mService->requestReadFmqUnsync(dataLen);
+    ASSERT_TRUE(this->mQueue->write(data, dataLen));
+    bool ret = this->requestReadFmqUnsync(dataLen, this->mService);
     ASSERT_TRUE(ret);
 }
 
 /*
  * Verify that the FMQ is empty and read fails when it is empty.
  */
-TEST_F(UnsynchronizedWriteClient, ReadWhenEmpty) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
+TYPED_TEST(UnsynchronizedWriteClient, ReadWhenEmpty) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
     const size_t numMessages = 2;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    uint16_t readData[numMessages];
-    ASSERT_FALSE(mQueue->read(readData, numMessages));
+    ASSERT_LE(numMessages, this->mNumMessagesMax);
+    int32_t readData[numMessages];
+    ASSERT_FALSE(this->mQueue->read(readData, numMessages));
 }
 
 /*
@@ -728,187 +981,210 @@
  * Write enough messages to fill it.
  * Verify availableToWrite() method returns is zero.
  * Try writing another message and verify that
- * the attempted write was successful. Request mService
- * to read the messages in the FMQ and verify that it is unsuccesful.
+ * the attempted write was successful. Request this->mService
+ * to read the messages in the FMQ and verify that it is unsuccessful.
  */
 
-TEST_F(UnsynchronizedWriteClient, WriteWhenFull) {
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_TRUE(mQueue->write(&data[0], 1));
-    bool ret = mService->requestReadFmqUnsync(mNumMessagesMax);
+TYPED_TEST(UnsynchronizedWriteClient, WriteWhenFull) {
+    std::vector<int32_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_TRUE(this->mQueue->write(&data[0], 1));
+    bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_FALSE(ret);
 }
 
 /*
  * Verify FMQ is empty.
- * Request mService to write data equal to queue size.
- * Read and verify data in mQueue.
+ * Request this->mService to write data equal to queue size.
+ * Read and verify data in this->mQueue.
  */
-TEST_F(UnsynchronizedWriteClient, LargeInputTest1) {
-    bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
+TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest1) {
+    bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_TRUE(ret);
-    std::vector<uint16_t> data(mNumMessagesMax);
-    ASSERT_TRUE(mQueue->read(&data[0], mNumMessagesMax));
-    ASSERT_TRUE(verifyData(&data[0], mNumMessagesMax));
+    std::vector<int32_t> data(this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->read(&data[0], this->mNumMessagesMax));
+    ASSERT_TRUE(verifyData(&data[0], this->mNumMessagesMax));
 }
 
 /*
- * Request mService to write more than maximum number of messages to the FMQ.
+ * Request this->mService to write more than maximum number of messages to the FMQ.
  * Verify that the write fails. Verify that availableToRead() method
  * still returns 0 and verify that attempt to read fails.
  */
-TEST_F(UnsynchronizedWriteClient, LargeInputTest2) {
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    const size_t numMessages = mNumMessagesMax + 1;
-    bool ret = mService->requestWriteFmqUnsync(numMessages);
+TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest2) {
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    const size_t numMessages = this->mNumMessagesMax + 1;
+    bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
     ASSERT_FALSE(ret);
-    uint16_t readData;
-    ASSERT_EQ(0UL, mQueue->availableToRead());
-    ASSERT_FALSE(mQueue->read(&readData, 1));
+    int32_t readData;
+    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+    ASSERT_FALSE(this->mQueue->read(&readData, 1));
 }
 
 /*
  * Write until FMQ is full.
  * Verify that the number of messages available to write
- * is equal to mNumMessagesMax.
- * Verify that another write attempt is succesful.
- * Request mService to read. Verify that read is unsuccessful.
- * Perform another write and verify that the read is succesful
+ * is equal to this->mNumMessagesMax.
+ * Verify that another write attempt is successful.
+ * Request this->mService to read. Verify that read is unsuccessful.
+ * Perform another write and verify that the read is successful
  * to check if the reader process can recover from the error condition.
  */
-TEST_F(UnsynchronizedWriteClient, LargeInputTest3) {
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ASSERT_EQ(0UL, mQueue->availableToWrite());
-    ASSERT_TRUE(mQueue->write(&data[0], 1));
+TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest3) {
+    std::vector<int32_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_EQ(0UL, this->mQueue->availableToWrite());
+    ASSERT_TRUE(this->mQueue->write(&data[0], 1));
 
-    bool ret = mService->requestReadFmqUnsync(mNumMessagesMax);
+    bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_FALSE(ret);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
 
-    ret = mService->requestReadFmqUnsync(mNumMessagesMax);
+    ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_TRUE(ret);
 }
 
 /*
- * Confirm that the FMQ is empty. Request mService to write to FMQ.
+ * Confirm that the FMQ is empty. Request this->mService to write to FMQ.
  * Do multiple reads to empty FMQ and verify data.
  */
-TEST_F(UnsynchronizedWriteClient, MultipleRead) {
+TYPED_TEST(UnsynchronizedWriteClient, MultipleRead) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    size_t availableToRead = mQueue->availableToRead();
+    ASSERT_LE(numMessages, this->mNumMessagesMax);
+    size_t availableToRead = this->mQueue->availableToRead();
     size_t expectedCount = 0;
     ASSERT_EQ(expectedCount, availableToRead);
-    bool ret = mService->requestWriteFmqUnsync(numMessages);
+    bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
     ASSERT_TRUE(ret);
-    uint16_t readData[numMessages] = {};
+    int32_t readData[numMessages] = {};
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
+        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
     }
     ASSERT_TRUE(verifyData(readData, numMessages));
 }
 
 /*
  * Write to FMQ in bursts.
- * Request mService to read data, verify that it was successful.
+ * Request this->mService to read data, verify that it was successful.
  */
-TEST_F(UnsynchronizedWriteClient, MultipleWrite) {
+TYPED_TEST(UnsynchronizedWriteClient, MultipleWrite) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, mNumMessagesMax);
-    uint16_t data[numMessages];
+    ASSERT_LE(numMessages, this->mNumMessagesMax);
+    int32_t data[numMessages];
     initData(data, numMessages);
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
+        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
     }
-    bool ret = mService->requestReadFmqUnsync(numMessages);
+    bool ret = this->requestReadFmqUnsync(numMessages, this->mService);
     ASSERT_TRUE(ret);
 }
 
 /*
  * Write enough messages into the FMQ to fill half of it.
- * Request mService to read back the same.
- * Write mNumMessagesMax messages into the queue. This should cause a
- * wrap around. Request mService to read and verify the data.
+ * Request this->mService to read back the same.
+ * Write this->mNumMessagesMax messages into the queue. This should cause a
+ * wrap around. Request this->mService to read and verify the data.
  */
-TEST_F(UnsynchronizedWriteClient, ReadWriteWrapAround) {
-    size_t numMessages = mNumMessagesMax / 2;
-    std::vector<uint16_t> data(mNumMessagesMax);
-    initData(&data[0], mNumMessagesMax);
-    ASSERT_TRUE(mQueue->write(&data[0], numMessages));
-    bool ret = mService->requestReadFmqUnsync(numMessages);
+TYPED_TEST(UnsynchronizedWriteClient, ReadWriteWrapAround) {
+    size_t numMessages = this->mNumMessagesMax / 2;
+    std::vector<int32_t> data(this->mNumMessagesMax);
+    initData(&data[0], this->mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
+    bool ret = this->requestReadFmqUnsync(numMessages, this->mService);
     ASSERT_TRUE(ret);
-    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
-    ret = mService->requestReadFmqUnsync(mNumMessagesMax);
+    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_TRUE(ret);
 }
 
 /*
- * Request mService to write a small number of messages
+ * Request this->mService to write a small number of messages
  * to the FMQ. Read and verify data from two threads configured
  * as readers to the FMQ.
  */
-TEST_F(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
-    auto desc = mQueue->getDesc();
-    std::unique_ptr<MessageQueue<uint16_t, kUnsynchronizedWrite>> mQueue2(
-            new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite>(*desc));
-    ASSERT_NE(nullptr, mQueue2.get());
+TYPED_TEST(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
+    typename TypeParam::MQType* mQueue2 = this->newQueue();
+
+    ASSERT_NE(nullptr, mQueue2);
 
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, mNumMessagesMax);
+    ASSERT_LE(dataLen, this->mNumMessagesMax);
 
-    bool ret = mService->requestWriteFmqUnsync(dataLen);
+    bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
     ASSERT_TRUE(ret);
 
     pid_t pid;
     if ((pid = fork()) == 0) {
         /* child process */
-        uint16_t readData[dataLen] = {};
+        int32_t readData[dataLen] = {};
         ASSERT_TRUE(mQueue2->read(readData, dataLen));
         ASSERT_TRUE(verifyData(readData, dataLen));
         exit(0);
     } else {
         ASSERT_GT(pid,
                   0 /* parent should see PID greater than 0 for a good fork */);
-        uint16_t readData[dataLen] = {};
-        ASSERT_TRUE(mQueue->read(readData, dataLen));
+        int32_t readData[dataLen] = {};
+        ASSERT_TRUE(this->mQueue->read(readData, dataLen));
         ASSERT_TRUE(verifyData(readData, dataLen));
     }
 }
 
 /*
- * Request mService to write into the FMQ until it is full.
- * Request mService to do another write and verify it is successful.
+ * Request this->mService to write into the FMQ until it is full.
+ * Request this->mService to do another write and verify it is successful.
  * Use two reader processes to read and verify that both fail.
  */
-TEST_F(UnsynchronizedWriteClient, OverflowNotificationTest) {
-    auto desc = mQueue->getDesc();
-    std::unique_ptr<MessageQueue<uint16_t, kUnsynchronizedWrite>> mQueue2(
-            new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite>(*desc));
-    ASSERT_NE(nullptr, mQueue2.get());
+TYPED_TEST(UnsynchronizedWriteClient, OverflowNotificationTest) {
+    typename TypeParam::MQType* mQueue2 = this->newQueue();
+    ASSERT_NE(nullptr, mQueue2);
 
-    bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
+    bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
     ASSERT_TRUE(ret);
-    ret = mService->requestWriteFmqUnsync(1);
+    ret = this->requestWriteFmqUnsync(1, this->mService);
     ASSERT_TRUE(ret);
 
     pid_t pid;
     if ((pid = fork()) == 0) {
         /* child process */
-        std::vector<uint16_t> readData(mNumMessagesMax);
-        ASSERT_FALSE(mQueue2->read(&readData[0], mNumMessagesMax));
+        std::vector<int32_t> readData(this->mNumMessagesMax);
+        ASSERT_FALSE(mQueue2->read(&readData[0], this->mNumMessagesMax));
         exit(0);
     } else {
         ASSERT_GT(pid, 0/* parent should see PID greater than 0 for a good fork */);
-        std::vector<uint16_t> readData(mNumMessagesMax);
-        ASSERT_FALSE(mQueue->read(&readData[0], mNumMessagesMax));
+        std::vector<int32_t> readData(this->mNumMessagesMax);
+        ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
     }
 }
+
+/*
+ * Make sure a valid queue can be created with different supported types.
+ * All fundamental or native types should work. An AIDL parcelable that is
+ * annotated with @FixedSize is supported. A parcelable without it, will cause
+ * a compilation error.
+ */
+typedef ::testing::Types<FixedParcelable, EventFlagBits, bool, int8_t, char, char16_t, int32_t,
+                         int64_t, float, double>
+        AidlTypeCheckTypes;
+
+template <typename T>
+class AidlTypeChecks : public ::testing::Test {};
+
+TYPED_TEST_CASE(AidlTypeChecks, AidlTypeCheckTypes);
+
+TYPED_TEST(AidlTypeChecks, FixedSizeParcelableTest) {
+    android::AidlMessageQueue<TypeParam, UnsynchronizedWrite> queue =
+            android::AidlMessageQueue<TypeParam, UnsynchronizedWrite>(64);
+    ASSERT_TRUE(queue.isValid());
+    // Make sure we can do a simple write/read of any value.
+    TypeParam writeData[1];
+    TypeParam readData[1];
+    EXPECT_TRUE(queue.write(writeData, 1));
+    EXPECT_TRUE(queue.read(readData, 1));
+}
