diff --git a/Android.bp b/Android.bp
index 5889a9c..e2cb961 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,10 +12,6 @@
 // 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: [
@@ -35,12 +31,6 @@
     ],
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
-    header_libs: [
-        "libfmq-base",
-    ],
-    export_header_lib_headers: [
-        "libfmq-base",
-    ],
     srcs: [
         "EventFlag.cpp",
         "FmqInternal.cpp",
@@ -50,7 +40,6 @@
         "-Werror",
     ],
     vendor_available: true,
-    product_available: true,
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
     vndk: {
@@ -58,21 +47,4 @@
     },
     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 96f9519..cb101bd 100644
--- a/EventFlag.cpp
+++ b/EventFlag.cpp
@@ -22,7 +22,6 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include <limits>
 #include <new>
 
 #include <fmq/EventFlag.h>
@@ -121,9 +120,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, kIntMax, NULL, NULL, bitmask);
+        int ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAKE_BITSET,
+                          INT_MAX, 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 886d155..6b95def 100644
--- a/FmqInternal.cpp
+++ b/FmqInternal.cpp
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "FMQ"
 #include <android-base/logging.h>
-#include <utils/Log.h>
 
 namespace android {
 namespace hardware {
@@ -30,10 +29,6 @@
     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 18b0a1b..213c93a 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -3,4 +3,3 @@
 
 [Builtin Hooks]
 clang_format = true
-bpfmt = true
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index dfa7071..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "fmq_unit_tests"
-    },
-    {
-      "name": "fmq_test"
-    }
-  ]
-}
diff --git a/base/fmq/MQDescriptorBase.h b/base/fmq/MQDescriptorBase.h
deleted file mode 100644
index 0d18d4c..0000000
--- a/base/fmq/MQDescriptorBase.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 3cae117..d82c0a3 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -31,11 +31,10 @@
 LOCAL_REQUIRED_MODULES := android.hardware.tests.msgq@1.0-impl
 
 ifneq ($(TARGET_2ND_ARCH),)
-LOCAL_REQUIRED_MODULES += android.hardware.tests.msgq@1.0-impl:32
+LOCAL_REQUIRED_MODULES += android.hardware.tests.msgq@1.0-impl$(TARGET_2ND_ARCH_MODULE_SUFFIX)
 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
deleted file mode 100644
index 6b41e3f..0000000
--- a/fuzzer/Android.bp
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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
deleted file mode 100644
index 844188f..0000000
--- a/fuzzer/fmq_fuzzer.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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
deleted file mode 100644
index e3d3cb9..0000000
--- a/include/fmq/AidlMQDescriptorShim.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0536d6a..0000000
--- a/include/fmq/AidlMessageQueue.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6534ebe..0000000
--- a/include/fmq/ConvertMQDescriptors.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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 8ff0739..97fee0e 100644
--- a/include/fmq/MessageQueue.h
+++ b/include/fmq/MessageQueue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,20 +14,38 @@
  * limitations under the License.
  */
 
-#pragma once
+#ifndef HIDL_MQ_H
+#define HIDL_MQ_H
 
+#include <atomic>
+#include <cutils/ashmem.h>
+#include <fmq/EventFlag.h>
 #include <hidl/MQDescriptor.h>
-#include "MessageQueueBase.h"
+#include <new>
+#include <sys/mman.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.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 final : public MessageQueueBase<MQDescriptor, T, flavor> {
+struct MessageQueue {
     typedef MQDescriptor<T, flavor> Descriptor;
-    MessageQueue(const Descriptor& Desc, bool resetPointers = true)
-        : MessageQueueBase<MQDescriptor, T, flavor>(Desc, resetPointers) {}
-    ~MessageQueue() = default;
+
+    /**
+     * @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();
 
     /**
      * This constructor uses Ashmem shared memory to create an FMQ
@@ -36,27 +54,1177 @@
      * @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,
-                 android::base::unique_fd bufferFd, size_t bufferSize)
-        : MessageQueueBase<MQDescriptor, T, flavor>(numElementsInQueue, configureEventFlagWord,
-                                                    std::move(bufferFd), bufferSize) {}
+    MessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false);
 
-    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 can be written into the FMQ
+     * without a read.
+     */
+    size_t availableToWrite() const;
 
-  private:
+    /**
+     * @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.
+     */
+    __attribute__((noinline)) 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.
+     */
+    __attribute__((noinline)) 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.
+     */
+    __attribute__((always_inline)) 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.
+     */
+    __attribute__((always_inline)) 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;
+
     MessageQueue(const MessageQueue& other) = delete;
     MessageQueue& operator=(const MessageQueue& other) = delete;
-    MessageQueue() = 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;
 };
 
+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);
+    if (writePtr % sizeof(T) != 0) {
+        hardware::details::logError(
+                "The write pointer has become misaligned. Writing to the queue is no longer "
+                "possible.");
+        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 <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 % 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.");
+        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 <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
deleted file mode 100644
index b932317..0000000
--- a/include/fmq/MessageQueueBase.h
+++ /dev/null
@@ -1,1300 +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.
- */
-
-#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 ec38cea..b85aa16 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -14,36 +14,14 @@
 // 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: "fmq_test_client",
+    name: "mq_test_client",
     srcs: ["msgq_test_client.cpp"],
 
     cflags: [
         "-Wall",
         "-Werror",
     ],
-    sanitize: {
-        misc_undefined: ["integer"],
-    },
 
     shared_libs: [
         "libbase",
@@ -52,39 +30,21 @@
         "libhidlbase",
         "liblog",
         "libutils",
-        "libbinder_ndk",
     ],
 
+    // 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.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,
+    static_libs: ["android.hardware.tests.msgq@1.0"],
+    whole_static_libs: ["android.hardware.tests.msgq@1.0-impl"],
 }
 
 cc_test {
-    name: "fmq_unit_tests",
+    name: "mq_test",
 
-    srcs: ["fmq_unit_tests.cpp"],
+    srcs: ["mq_test.cpp"],
     shared_libs: [
         "libbase",
         "libcutils",
@@ -93,17 +53,9 @@
         "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
new file mode 100644
index 0000000..6efe7c2
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,39 @@
+#
+# 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
new file mode 100644
index 0000000..9e5df01
--- /dev/null
+++ b/tests/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?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
deleted file mode 100644
index e210fda..0000000
--- a/tests/aidl/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-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
deleted file mode 100644
index 202a67c..0000000
--- a/tests/aidl/android/fmq/test/EventFlagBits.aidl
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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
deleted file mode 100644
index acb54f2..0000000
--- a/tests/aidl/android/fmq/test/FixedParcelable.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7f1f8b7..0000000
--- a/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 71a5533..0000000
--- a/tests/aidl/default/Android.bp
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index 485e75b..0000000
--- a/tests/aidl/default/TestAidlMsgQ.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6e7c859..0000000
--- a/tests/aidl/default/TestAidlMsgQ.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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
new file mode 100644
index 0000000..02683c9
--- /dev/null
+++ b/tests/fmq_test
@@ -0,0 +1,9 @@
+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
deleted file mode 100644
index 68114ad..0000000
--- a/tests/fmq_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/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
deleted file mode 100644
index f7b1f16..0000000
--- a/tests/fmq_test.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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
deleted file mode 100644
index be866ec..0000000
--- a/tests/fmq_unit_tests.cpp
+++ /dev/null
@@ -1,1147 +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 <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
new file mode 100644
index 0000000..96528d3
--- /dev/null
+++ b/tests/mq_test.cpp
@@ -0,0 +1,809 @@
+/*
+ * 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 a6f1ccc..271586a 100644
--- a/tests/msgq_test_client.cpp
+++ b/tests/msgq_test_client.cpp
@@ -19,13 +19,7 @@
 #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>
@@ -36,9 +30,6 @@
 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
@@ -49,258 +40,87 @@
 using android::hardware::MQDescriptorUnsync;
 using android::hardware::details::waitForHwService;
 
-using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
-using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
-using android::hardware::kSynchronizedReadWrite;
-using android::hardware::kUnsynchronizedWrite;
+typedef MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync;
+typedef MessageQueue<uint16_t, kUnsynchronizedWrite> MessageQueueUnsync;
 
-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);
+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();
+}
 
-enum class SetupType {
-    SINGLE_FD,
-    DOUBLE_FD,
+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);
+                                      });
+    }
 };
 
-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:
+class SynchronizedReadWriteClient : public ::testing::Test {
+protected:
     virtual void TearDown() {
         delete mQueue;
     }
 
     virtual void SetUp() {
-        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));
-        }
+        static constexpr size_t kNumElementsInQueue = (PAGE_SIZE - 16) / sizeof(uint16_t);
+        mService = waitGetTestService();
+        ASSERT_NE(mService, nullptr);
+        ASSERT_TRUE(mService->isRemote());
         // create a queue on the client side
-        mQueue = new (std::nothrow) typename T::MQType(
-                kNumElementsInSyncQueue, true /* configure event flag word */,
-                std::move(ringbufferFd), kNumElementsInSyncQueue * kSyncElementSizeBytes);
+        mQueue = new (std::nothrow)
+            MessageQueueSync(kNumElementsInQueue, true /* configure event flag word */);
         ASSERT_NE(nullptr, mQueue);
         ASSERT_TRUE(mQueue->isValid());
-        ASSERT_EQ(mQueue->getQuantumCount(), kNumElementsInSyncQueue);
+        mNumMessagesMax = mQueue->getQuantumCount();
 
         // tell server to set up the queue on its end
-        ASSERT_TRUE(this->configureFmqSyncReadWrite(mQueue));
+        ASSERT_TRUE(mService->configureFmqSyncReadWrite(*mQueue->getDesc()));
     }
 
-    typename T::MQType* mQueue = nullptr;
+    sp<ITestMsgQ> mService;
+    MessageQueueSync* mQueue = nullptr;
+    size_t mNumMessagesMax = 0;
 };
 
-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() {
-        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();
+class UnsynchronizedWriteClient : public ::testing::Test {
+protected:
+    virtual void TearDown() {
+        delete 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();
+    }
+
+    sp<ITestMsgQ> mService;
+    MessageQueueUnsync*  mQueue = nullptr;
     size_t mNumMessagesMax = 0;
 };
 
 /*
  * Utility function to verify data read from the fast message queue.
  */
-bool verifyData(int32_t* data, size_t count) {
+bool verifyData(uint16_t* data, size_t count) {
     for (size_t i = 0; i < count; i++) {
         if (data[i] != i) return false;
     }
@@ -310,7 +130,7 @@
 /*
  * Utility function to initialize data to be written to the FMQ
  */
-inline void initData(int32_t* data, size_t count) {
+inline void initData(uint16_t* data, size_t count) {
     for (size_t i = 0; i < count; i++) {
         data[i] = i;
     }
@@ -320,31 +140,33 @@
  * Verify that for an unsynchronized flavor of FMQ, multiple readers
  * can recover from a write overflow condition.
  */
-TYPED_TEST(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
+TEST_F(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
     const size_t dataLen = 16;
 
     pid_t pid;
     /* creating first reader process */
     if ((pid = fork()) == 0) {
-        typename TypeParam::MQType* queue = nullptr;
-        auto service =
-                this->getQueue(&queue, true /* setupQueue */, TypeParam::UserFd /* userFd */);
-        ASSERT_NE(service, nullptr);
-        ASSERT_TRUE(service->isRemote());
+        sp<ITestMsgQ> testService;
+        MessageQueueUnsync*  queue = nullptr;
+        getQueue(&queue, &testService, true /* setupQueue */);
+        ASSERT_NE(testService, nullptr);
+        ASSERT_TRUE(testService->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 = this->requestWriteFmqUnsync(numMessagesMax, service);
+        auto ret = testService->requestWriteFmqUnsync(numMessagesMax);
+        ASSERT_TRUE(ret.isOk());
         ASSERT_TRUE(ret);
 
-        ret = this->requestWriteFmqUnsync(1, service);
+        ret = testService->requestWriteFmqUnsync(1);
+        ASSERT_TRUE(ret.isOk());
         ASSERT_TRUE(ret);
 
         // The following read should fail due to the overflow.
-        std::vector<int32_t> readData(numMessagesMax);
+        std::vector<uint16_t> readData(numMessagesMax);
         ASSERT_FALSE(queue->read(&readData[0], numMessagesMax));
 
         /*
@@ -352,7 +174,8 @@
          * overflow condition.
          */
         ASSERT_LT(dataLen, numMessagesMax);
-        ret = this->requestWriteFmqUnsync(dataLen, service);
+        ret = testService->requestWriteFmqUnsync(dataLen);
+        ASSERT_TRUE(ret.isOk());
         ASSERT_TRUE(ret);
 
         // Verify that the read is successful.
@@ -371,22 +194,25 @@
 
     // creating second reader process.
     if ((pid = fork()) == 0) {
-        typename TypeParam::MQType* queue = nullptr;
-        auto service = this->getQueue(&queue, false /* setupQueue */, false /* userFd */);
-        ASSERT_NE(service, nullptr);
-        ASSERT_TRUE(service->isRemote());
+        sp<ITestMsgQ> testService;
+        MessageQueueUnsync* queue = nullptr;
+
+        getQueue(&queue, &testService, false /* setupQueue */);
+        ASSERT_NE(testService, nullptr);
+        ASSERT_TRUE(testService->isRemote());
         ASSERT_NE(queue, nullptr);
         ASSERT_TRUE(queue->isValid());
 
         // This read should fail due to the write overflow.
-        std::vector<int32_t> readData(dataLen);
+        std::vector<uint16_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 = this->requestWriteFmqUnsync(dataLen, service);
+        auto ret = testService->requestWriteFmqUnsync(dataLen);
+        ASSERT_TRUE(ret.isOk());
         ASSERT_TRUE(ret);
 
         // verify that the read is successful.
@@ -405,32 +231,26 @@
  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
  * using the EventFlag object owned by FMQ.
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite1) {
+TEST_F(SynchronizedReadWriteClient, BlockingReadWrite1) {
     const size_t dataLen = 64;
-    bool ret = false;
+    uint16_t data[dataLen] = {0};
+
     /*
      * Request service to perform a blocking read. This call is oneway and will
      * return immediately.
      */
-    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);
-    }
+    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);
 }
 
 /*
@@ -438,34 +258,30 @@
  * using the EventFlag object owned by FMQ and using the default EventFlag
  * notification bit mask.
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite2) {
+TEST_F(SynchronizedReadWriteClient, BlockingReadWrite2) {
     const size_t dataLen = 64;
-    bool ret = false;
+    std::vector<uint16_t> data(mNumMessagesMax);
 
     /*
      * Request service to perform a blocking read using default EventFlag
      * notification bit mask. This call is oneway and will
      * return immediately.
      */
-    this->mService->requestBlockingReadDefaultEventFlagBits(dataLen);
+    mService->requestBlockingReadDefaultEventFlagBits(dataLen);
 
     /* Cause a context switch to allow service to block */
     sched_yield();
-    {
-        std::array<int32_t, dataLen> data = {0};
-        ret = this->mQueue->writeBlocking(data.data(), data.size());
-        ASSERT_TRUE(ret);
-    }
+
+    bool ret = mQueue->writeBlocking(&data[0],
+                                     dataLen);
+    ASSERT_TRUE(ret);
 
     /*
      * If the blocking read was successful, another write of size
-     * kNumElementsInSyncQueue will succeed.
+     * mNumMessagesMax will succeed.
      */
-    {
-        std::array<int32_t, kNumElementsInSyncQueue> data = {0};
-        ret = this->mQueue->writeBlocking(data.data(), data.size(), 5000000000 /* timeOutNanos */);
-        ASSERT_TRUE(ret);
-    }
+    ret = mQueue->writeBlocking(&data[0], mNumMessagesMax, 5000000000 /* timeOutNanos */);
+    ASSERT_TRUE(ret);
 }
 
 /*
@@ -474,44 +290,32 @@
  * Each write operation writes the same amount of data as a single read
  * operation.
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
+TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
     const size_t dataLen = 64;
+    uint16_t data[dataLen] = {0};
     bool ret = false;
 
     /*
-     * Request service to perform a blocking read of 64 elements. This call is
-     * oneway and will return immediately.
+     * Request service to perform a blocking read. This call is oneway and will
+     * return immediately.
      */
-    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 */);
+    const size_t writeCount = 1024;
+    mService->requestBlockingReadRepeat(dataLen, writeCount);
 
+    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);
 }
 
 /*
@@ -520,43 +324,31 @@
  * amount of data as a single write.
  *
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
+TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
     const size_t dataLen = 64;
+    uint16_t data[dataLen] = {0};
     bool ret = false;
+
     /*
-     * 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.
+     * Request service to perform a blocking read. This call is oneway and will
+     * return immediately.
      */
-    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 */);
+    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 */);
         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);
 }
 
 /*
@@ -564,67 +356,56 @@
  * using the EventFlag object owned by FMQ. Each write operation writes twice
  * the amount of data as a single read.
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
+TEST_F(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
     const size_t dataLen = 64;
+    uint16_t data[dataLen] = {0};
     bool ret = false;
 
     /*
-     * 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.
+     * Request service to perform a blocking read. This call is oneway and will
+     * return immediately.
      */
     size_t writeCount = 1024;
-    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 */);
+    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 */);
         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.
  */
-TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
-    int32_t data = 0;
+TEST_F(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
+    uint16_t data = 0;
 
     /*
      * Trigger a blocking write for zero messages with no timeout.
      */
-    bool ret = this->mQueue->writeBlocking(
-            &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+    bool ret = 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 = this->mQueue->readBlocking(
-            &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
-            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
+    ret = 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);
 }
 
@@ -632,13 +413,13 @@
  * Request mService to write a small number of messages
  * to the FMQ. Read and verify data.
  */
-TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest1) {
+TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
-    bool ret = this->requestWriteFmqSync(dataLen);
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    bool ret = mService->requestWriteFmqSync(dataLen);
     ASSERT_TRUE(ret);
-    int32_t readData[dataLen] = {};
-    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    uint16_t readData[dataLen] = {};
+    ASSERT_TRUE(mQueue->read(readData, dataLen));
     ASSERT_TRUE(verifyData(readData, dataLen));
 }
 
@@ -648,22 +429,16 @@
  * 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();
-    }
+TEST_F(SynchronizedReadWriteClient, MisalignedWriteCounter) {
     const size_t dataLen = 1;
-    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
-    bool ret = this->requestWriteFmqSync(dataLen);
+    bool ret = mService->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));
+    MessageQueueSync::MemTransaction tx;
+    ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
     // get a pointer to the beginning of the ring buffer
     const auto& region = tx.getFirstRegion();
-    int32_t* firstStart = region.getAddress();
+    uint16_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
@@ -671,15 +446,15 @@
     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);
+    *(writeCntr) = mQueue->getQuantumCount() * mQueue->getQuantumSize() - 1;
+    ASSERT_TRUE(*writeCntr % sizeof(uint16_t) != 0);
 
     // this is not actually necessary, but it's the expected the pattern.
-    this->mQueue->commitRead(dataLen);
+    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);
+    ret = mService->requestWriteFmqSync(dataLen);
     EXPECT_FALSE(ret);
 }
 
@@ -688,14 +463,16 @@
  * to the FMQ. Read and verify each message using
  * beginRead/Commit read APIs.
  */
-TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest2) {
+TEST_F(SynchronizedReadWriteClient, SmallInputReaderTest2) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
-    auto ret = this->requestWriteFmqSync(dataLen);
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    auto ret = mService->requestWriteFmqSync(dataLen);
+
+    ASSERT_TRUE(ret.isOk());
     ASSERT_TRUE(ret);
 
-    typename TypeParam::MQType::MemTransaction tx;
-    ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
+    MessageQueueSync::MemTransaction tx;
+    ASSERT_TRUE(mQueue->beginRead(dataLen, &tx));
 
     auto first = tx.getFirstRegion();
     auto second = tx.getSecondRegion();
@@ -709,46 +486,46 @@
         }
     }
 
-    ASSERT_TRUE(this->mQueue->commitRead(dataLen));
+    ASSERT_TRUE(mQueue->commitRead(dataLen));
 }
 
 /*
  * Write a small number of messages to FMQ. Request
- * mService to read and verify that the write was successful.
+ * mService to read and verify that the write was succesful.
  */
-TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest1) {
+TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
-    size_t originalCount = this->mQueue->availableToWrite();
-    int32_t data[dataLen];
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    size_t originalCount = mQueue->availableToWrite();
+    uint16_t data[dataLen];
     initData(data, dataLen);
-    ASSERT_TRUE(this->mQueue->write(data, dataLen));
-    bool ret = this->requestReadFmqSync(dataLen);
+    ASSERT_TRUE(mQueue->write(data, dataLen));
+    bool ret = mService->requestReadFmqSync(dataLen);
     ASSERT_TRUE(ret);
-    size_t availableCount = this->mQueue->availableToWrite();
+    size_t availableCount = 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 successful.
+ * APIs. Request mService to read and verify that the write was succesful.
  */
-TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest2) {
+TEST_F(SynchronizedReadWriteClient, SmallInputWriterTest2) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, kNumElementsInSyncQueue);
-    size_t originalCount = this->mQueue->availableToWrite();
-    int32_t data[dataLen];
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    size_t originalCount = mQueue->availableToWrite();
+    uint16_t data[dataLen];
     initData(data, dataLen);
 
-    typename TypeParam::MQType::MemTransaction tx;
-    ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
+    MessageQueueSync::MemTransaction tx;
+    ASSERT_TRUE(mQueue->beginWrite(dataLen, &tx));
 
     auto first = tx.getFirstRegion();
     auto second = tx.getSecondRegion();
 
     size_t firstRegionLength = first.getLength();
-    int32_t* firstBaseAddress = first.getAddress();
-    int32_t* secondBaseAddress = second.getAddress();
+    uint16_t* firstBaseAddress = first.getAddress();
+    uint16_t* secondBaseAddress = second.getAddress();
 
     for (size_t i = 0; i < dataLen; i++) {
         if (i < firstRegionLength) {
@@ -758,24 +535,24 @@
         }
     }
 
-    ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
+    ASSERT_TRUE(mQueue->commitWrite(dataLen));
 
-    auto ret = this->requestReadFmqSync(dataLen);
-    // ASSERT_TRUE(ret.isOk());
+    auto ret = mService->requestReadFmqSync(dataLen);
+    ASSERT_TRUE(ret.isOk());
     ASSERT_TRUE(ret);
-    size_t availableCount = this->mQueue->availableToWrite();
+    size_t availableCount = mQueue->availableToWrite();
     ASSERT_EQ(originalCount, availableCount);
 }
 
 /*
  * Verify that the FMQ is empty and read fails when it is empty.
  */
-TYPED_TEST(SynchronizedReadWriteClient, ReadWhenEmpty) {
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+TEST_F(SynchronizedReadWriteClient, ReadWhenEmpty) {
+    ASSERT_EQ(0UL, mQueue->availableToRead());
     const size_t numMessages = 2;
-    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
-    int32_t readData[numMessages];
-    ASSERT_FALSE(this->mQueue->read(readData, numMessages));
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    uint16_t readData[numMessages];
+    ASSERT_FALSE(mQueue->read(readData, numMessages));
 }
 
 /*
@@ -783,16 +560,17 @@
  * Write enough messages to fill it.
  * Verify availableToWrite() method returns is zero.
  * Try writing another message and verify that
- * the attempted write was unsuccessful. Request mService
+ * the attempted write was unsuccesful. Request mService
  * to read and verify the messages in the FMQ.
  */
-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());
+
+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);
     ASSERT_TRUE(ret);
 }
 
@@ -801,12 +579,12 @@
  * Request mService to write data equal to queue size.
  * Read and verify data in mQueue.
  */
-TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest1) {
-    bool ret = this->requestWriteFmqSync(kNumElementsInSyncQueue);
+TEST_F(SynchronizedReadWriteClient, LargeInputTest1) {
+    bool ret = mService->requestWriteFmqSync(mNumMessagesMax);
     ASSERT_TRUE(ret);
-    std::vector<int32_t> readData(kNumElementsInSyncQueue);
-    ASSERT_TRUE(this->mQueue->read(&readData[0], kNumElementsInSyncQueue));
-    ASSERT_TRUE(verifyData(&readData[0], kNumElementsInSyncQueue));
+    std::vector<uint16_t> readData(mNumMessagesMax);
+    ASSERT_TRUE(mQueue->read(&readData[0], mNumMessagesMax));
+    ASSERT_TRUE(verifyData(&readData[0], mNumMessagesMax));
 }
 
 /*
@@ -814,15 +592,15 @@
  * Verify that the write fails. Verify that availableToRead() method
  * still returns 0 and verify that attempt to read fails.
  */
-TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest2) {
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+TEST_F(SynchronizedReadWriteClient, LargeInputTest2) {
+    ASSERT_EQ(0UL, mQueue->availableToRead());
     const size_t numMessages = 2048;
-    ASSERT_GT(numMessages, kNumElementsInSyncQueue);
-    bool ret = this->requestWriteFmqSync(numMessages);
+    ASSERT_GT(numMessages, mNumMessagesMax);
+    bool ret = mService->requestWriteFmqSync(numMessages);
     ASSERT_FALSE(ret);
-    int32_t readData;
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
-    ASSERT_FALSE(this->mQueue->read(&readData, 1));
+    uint16_t readData;
+    ASSERT_EQ(0UL, mQueue->availableToRead());
+    ASSERT_FALSE(mQueue->read(&readData, 1));
 }
 
 /*
@@ -833,14 +611,14 @@
  * Request mService to read. Verify read count.
  */
 
-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));
+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));
 
-    bool ret = this->requestReadFmqSync(data.size());
+    bool ret = mService->requestReadFmqSync(mNumMessagesMax);
     ASSERT_TRUE(ret);
 }
 
@@ -848,19 +626,19 @@
  * Confirm that the FMQ is empty. Request mService to write to FMQ.
  * Do multiple reads to empty FMQ and verify data.
  */
-TYPED_TEST(SynchronizedReadWriteClient, MultipleRead) {
+TEST_F(SynchronizedReadWriteClient, MultipleRead) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
-    size_t availableToRead = this->mQueue->availableToRead();
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    size_t availableToRead = mQueue->availableToRead();
     size_t expectedCount = 0;
     ASSERT_EQ(expectedCount, availableToRead);
-    bool ret = this->requestWriteFmqSync(numMessages);
+    bool ret = mService->requestWriteFmqSync(numMessages);
     ASSERT_TRUE(ret);
-    int32_t readData[numMessages] = {};
+    uint16_t readData[numMessages] = {};
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
+        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
     }
     ASSERT_TRUE(verifyData(readData, numMessages));
 }
@@ -869,18 +647,18 @@
  * Write to FMQ in bursts.
  * Request mService to read data. Verify the read was successful.
  */
-TYPED_TEST(SynchronizedReadWriteClient, MultipleWrite) {
+TEST_F(SynchronizedReadWriteClient, MultipleWrite) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, kNumElementsInSyncQueue);
-    int32_t data[numMessages];
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    uint16_t data[numMessages];
     initData(&data[0], numMessages);
 
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
+        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
     }
-    bool ret = this->requestReadFmqSync(numMessages);
+    bool ret = mService->requestReadFmqSync(numMessages);
     ASSERT_TRUE(ret);
 }
 
@@ -890,15 +668,15 @@
  * Write mNumMessagesMax messages into the queue. This should cause a
  * wrap around. Request mService to read and verify the data.
  */
-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);
+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);
     ASSERT_TRUE(ret);
-    ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
-    ret = this->requestReadFmqSync(data.size());
+    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
+    ret = mService->requestReadFmqSync(mNumMessagesMax);
     ASSERT_TRUE(ret);
 }
 
@@ -910,70 +688,74 @@
  * Write mNumMessagesMax messages into the queue. This will cause a
  * wrap around. Read and verify the data.
  */
-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);
+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());
     ASSERT_TRUE(ret);
 
     /*
      * The next write and read will have to deal with with wrap arounds.
      */
-    typename TypeParam::MQType::MemTransaction tx;
-    ASSERT_TRUE(this->mQueue->beginWrite(data.size(), &tx));
+    MessageQueueSync::MemTransaction tx;
+    ASSERT_TRUE(mQueue->beginWrite(mNumMessagesMax, &tx));
 
-    ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(), data.size());
+    ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(),  mNumMessagesMax);
 
-    for (size_t i = 0; i < data.size(); i++) {
-        int32_t* ptr = tx.getSlot(i);
+    for (size_t i = 0; i < mNumMessagesMax; i++) {
+        uint16_t* ptr = tx.getSlot(i);
         *ptr = data[i];
     }
 
-    ASSERT_TRUE(this->mQueue->commitWrite(data.size()));
+    ASSERT_TRUE(mQueue->commitWrite(mNumMessagesMax));
 
-    ret = this->requestReadFmqSync(data.size());
+    ret = mService->requestReadFmqSync(mNumMessagesMax);
+
+    ASSERT_TRUE(ret.isOk());
     ASSERT_TRUE(ret);
 }
 
 /*
- * Request this->mService to write a small number of messages
+ * Request mService to write a small number of messages
  * to the FMQ. Read and verify data.
  */
-TYPED_TEST(UnsynchronizedWriteClient, SmallInputReaderTest1) {
+TEST_F(UnsynchronizedWriteClient, SmallInputReaderTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, this->mNumMessagesMax);
-    bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    bool ret = mService->requestWriteFmqUnsync(dataLen);
     ASSERT_TRUE(ret);
-    int32_t readData[dataLen] = {};
-    ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+    uint16_t readData[dataLen] = {};
+    ASSERT_TRUE(mQueue->read(readData, dataLen));
     ASSERT_TRUE(verifyData(readData, dataLen));
 }
 
 /*
  * Write a small number of messages to FMQ. Request
- * this->mService to read and verify that the write was successful.
+ * mService to read and verify that the write was succesful.
  */
-TYPED_TEST(UnsynchronizedWriteClient, SmallInputWriterTest1) {
+TEST_F(UnsynchronizedWriteClient, SmallInputWriterTest1) {
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, this->mNumMessagesMax);
-    int32_t data[dataLen];
+    ASSERT_LE(dataLen, mNumMessagesMax);
+    uint16_t data[dataLen];
     initData(data, dataLen);
-    ASSERT_TRUE(this->mQueue->write(data, dataLen));
-    bool ret = this->requestReadFmqUnsync(dataLen, this->mService);
+    ASSERT_TRUE(mQueue->write(data, dataLen));
+    bool ret = mService->requestReadFmqUnsync(dataLen);
     ASSERT_TRUE(ret);
 }
 
 /*
  * Verify that the FMQ is empty and read fails when it is empty.
  */
-TYPED_TEST(UnsynchronizedWriteClient, ReadWhenEmpty) {
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
+TEST_F(UnsynchronizedWriteClient, ReadWhenEmpty) {
+    ASSERT_EQ(0UL, mQueue->availableToRead());
     const size_t numMessages = 2;
-    ASSERT_LE(numMessages, this->mNumMessagesMax);
-    int32_t readData[numMessages];
-    ASSERT_FALSE(this->mQueue->read(readData, numMessages));
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    uint16_t readData[numMessages];
+    ASSERT_FALSE(mQueue->read(readData, numMessages));
 }
 
 /*
@@ -981,210 +763,187 @@
  * 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 this->mService
- * to read the messages in the FMQ and verify that it is unsuccessful.
+ * the attempted write was successful. Request mService
+ * to read the messages in the FMQ and verify that it is unsuccesful.
  */
 
-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);
+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);
     ASSERT_FALSE(ret);
 }
 
 /*
  * Verify FMQ is empty.
- * Request this->mService to write data equal to queue size.
- * Read and verify data in this->mQueue.
+ * Request mService to write data equal to queue size.
+ * Read and verify data in mQueue.
  */
-TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest1) {
-    bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
+TEST_F(UnsynchronizedWriteClient, LargeInputTest1) {
+    bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
     ASSERT_TRUE(ret);
-    std::vector<int32_t> data(this->mNumMessagesMax);
-    ASSERT_TRUE(this->mQueue->read(&data[0], this->mNumMessagesMax));
-    ASSERT_TRUE(verifyData(&data[0], this->mNumMessagesMax));
+    std::vector<uint16_t> data(mNumMessagesMax);
+    ASSERT_TRUE(mQueue->read(&data[0], mNumMessagesMax));
+    ASSERT_TRUE(verifyData(&data[0], mNumMessagesMax));
 }
 
 /*
- * Request this->mService to write more than maximum number of messages to the FMQ.
+ * Request 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.
  */
-TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest2) {
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
-    const size_t numMessages = this->mNumMessagesMax + 1;
-    bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
+TEST_F(UnsynchronizedWriteClient, LargeInputTest2) {
+    ASSERT_EQ(0UL, mQueue->availableToRead());
+    const size_t numMessages = mNumMessagesMax + 1;
+    bool ret = mService->requestWriteFmqUnsync(numMessages);
     ASSERT_FALSE(ret);
-    int32_t readData;
-    ASSERT_EQ(0UL, this->mQueue->availableToRead());
-    ASSERT_FALSE(this->mQueue->read(&readData, 1));
+    uint16_t readData;
+    ASSERT_EQ(0UL, mQueue->availableToRead());
+    ASSERT_FALSE(mQueue->read(&readData, 1));
 }
 
 /*
  * Write until FMQ is full.
  * Verify that the number of messages available to write
- * 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
+ * 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
  * to check if the reader process can recover from the error condition.
  */
-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));
+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));
 
-    bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
+    bool ret = mService->requestReadFmqUnsync(mNumMessagesMax);
     ASSERT_FALSE(ret);
-    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
+    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
 
-    ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
+    ret = mService->requestReadFmqUnsync(mNumMessagesMax);
     ASSERT_TRUE(ret);
 }
 
 /*
- * Confirm that the FMQ is empty. Request this->mService to write to FMQ.
+ * Confirm that the FMQ is empty. Request mService to write to FMQ.
  * Do multiple reads to empty FMQ and verify data.
  */
-TYPED_TEST(UnsynchronizedWriteClient, MultipleRead) {
+TEST_F(UnsynchronizedWriteClient, MultipleRead) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, this->mNumMessagesMax);
-    size_t availableToRead = this->mQueue->availableToRead();
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    size_t availableToRead = mQueue->availableToRead();
     size_t expectedCount = 0;
     ASSERT_EQ(expectedCount, availableToRead);
-    bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
+    bool ret = mService->requestWriteFmqUnsync(numMessages);
     ASSERT_TRUE(ret);
-    int32_t readData[numMessages] = {};
+    uint16_t readData[numMessages] = {};
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
+        ASSERT_TRUE(mQueue->read(readData + i * chunkSize, chunkSize));
     }
     ASSERT_TRUE(verifyData(readData, numMessages));
 }
 
 /*
  * Write to FMQ in bursts.
- * Request this->mService to read data, verify that it was successful.
+ * Request mService to read data, verify that it was successful.
  */
-TYPED_TEST(UnsynchronizedWriteClient, MultipleWrite) {
+TEST_F(UnsynchronizedWriteClient, MultipleWrite) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t numMessages = chunkSize * chunkNum;
-    ASSERT_LE(numMessages, this->mNumMessagesMax);
-    int32_t data[numMessages];
+    ASSERT_LE(numMessages, mNumMessagesMax);
+    uint16_t data[numMessages];
     initData(data, numMessages);
     for (size_t i = 0; i < chunkNum; i++) {
-        ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
+        ASSERT_TRUE(mQueue->write(data + i * chunkSize, chunkSize));
     }
-    bool ret = this->requestReadFmqUnsync(numMessages, this->mService);
+    bool ret = mService->requestReadFmqUnsync(numMessages);
     ASSERT_TRUE(ret);
 }
 
 /*
  * Write enough messages into the FMQ to fill half of it.
- * 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.
+ * 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.
  */
-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);
+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);
     ASSERT_TRUE(ret);
-    ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
-    ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
+    ASSERT_TRUE(mQueue->write(&data[0], mNumMessagesMax));
+    ret = mService->requestReadFmqUnsync(mNumMessagesMax);
     ASSERT_TRUE(ret);
 }
 
 /*
- * Request this->mService to write a small number of messages
+ * Request mService to write a small number of messages
  * to the FMQ. Read and verify data from two threads configured
  * as readers to the FMQ.
  */
-TYPED_TEST(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
-    typename TypeParam::MQType* mQueue2 = this->newQueue();
-
-    ASSERT_NE(nullptr, mQueue2);
+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());
 
     const size_t dataLen = 16;
-    ASSERT_LE(dataLen, this->mNumMessagesMax);
+    ASSERT_LE(dataLen, mNumMessagesMax);
 
-    bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
+    bool ret = mService->requestWriteFmqUnsync(dataLen);
     ASSERT_TRUE(ret);
 
     pid_t pid;
     if ((pid = fork()) == 0) {
         /* child process */
-        int32_t readData[dataLen] = {};
+        uint16_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 */);
-        int32_t readData[dataLen] = {};
-        ASSERT_TRUE(this->mQueue->read(readData, dataLen));
+        uint16_t readData[dataLen] = {};
+        ASSERT_TRUE(mQueue->read(readData, dataLen));
         ASSERT_TRUE(verifyData(readData, dataLen));
     }
 }
 
 /*
- * Request this->mService to write into the FMQ until it is full.
- * Request this->mService to do another write and verify it is successful.
+ * Request mService to write into the FMQ until it is full.
+ * Request mService to do another write and verify it is successful.
  * Use two reader processes to read and verify that both fail.
  */
-TYPED_TEST(UnsynchronizedWriteClient, OverflowNotificationTest) {
-    typename TypeParam::MQType* mQueue2 = this->newQueue();
-    ASSERT_NE(nullptr, mQueue2);
+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());
 
-    bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
+    bool ret = mService->requestWriteFmqUnsync(mNumMessagesMax);
     ASSERT_TRUE(ret);
-    ret = this->requestWriteFmqUnsync(1, this->mService);
+    ret = mService->requestWriteFmqUnsync(1);
     ASSERT_TRUE(ret);
 
     pid_t pid;
     if ((pid = fork()) == 0) {
         /* child process */
-        std::vector<int32_t> readData(this->mNumMessagesMax);
-        ASSERT_FALSE(mQueue2->read(&readData[0], this->mNumMessagesMax));
+        std::vector<uint16_t> readData(mNumMessagesMax);
+        ASSERT_FALSE(mQueue2->read(&readData[0], mNumMessagesMax));
         exit(0);
     } else {
         ASSERT_GT(pid, 0/* parent should see PID greater than 0 for a good fork */);
-        std::vector<int32_t> readData(this->mNumMessagesMax);
-        ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
+        std::vector<uint16_t> readData(mNumMessagesMax);
+        ASSERT_FALSE(mQueue->read(&readData[0], 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));
-}
