Move FMQ tests to hardware/interfaces

Test: FMQ unit tests pass
Bug: 32284445

Change-Id: I1daf563560d12fc7a4433ae98876331c37509980
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
new file mode 100644
index 0000000..b53fcd3
--- /dev/null
+++ b/tests/msgq/1.0/default/Android.bp
@@ -0,0 +1,19 @@
+cc_library_shared {
+    name: "android.hardware.tests.msgq@1.0-impl",
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: [
+        "TestMsgQ.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.tests.msgq@1.0",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/tests/msgq/1.0/default/TestMsgQ.cpp b/tests/msgq/1.0/default/TestMsgQ.cpp
new file mode 100644
index 0000000..7cc4f5b
--- /dev/null
+++ b/tests/msgq/1.0/default/TestMsgQ.cpp
@@ -0,0 +1,135 @@
+#include "TestMsgQ.h"
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace msgq {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::tests::msgq::V1_0::ITestMsgQ follow.
+Return<void> TestMsgQ::configureFmqSyncReadWrite(configureFmqSyncReadWrite_cb _hidl_cb) {
+    static constexpr size_t kNumElementsInQueue = 1024;
+    mFmqSynchronized.reset(new (std::nothrow) MessageQueueSync(
+            kNumElementsInQueue, true /* configureEventFlagWord */));
+    if ((mFmqSynchronized == nullptr) || (mFmqSynchronized->isValid() == false)) {
+        _hidl_cb(false /* ret */, MessageQueueSync::Descriptor());
+    } else {
+        /*
+         * Initialize the EventFlag word with bit FMQ_NOT_FULL.
+         */
+        auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord();
+        if (evFlagWordPtr != nullptr) {
+            std::atomic_init(evFlagWordPtr,
+                             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL));
+        }
+        _hidl_cb(true /* ret */, *mFmqSynchronized->getDesc());
+    }
+    return Void();
+}
+
+Return<void> TestMsgQ::getFmqUnsyncWrite(bool configureFmq, getFmqUnsyncWrite_cb _hidl_cb) {
+    if (configureFmq) {
+        static constexpr size_t kNumElementsInQueue = 1024;
+        mFmqUnsynchronized.reset(new (std::nothrow) MessageQueueUnsync(kNumElementsInQueue));
+    }
+    if ((mFmqUnsynchronized == nullptr) ||
+        (mFmqUnsynchronized->isValid() == false)) {
+        _hidl_cb(false /* ret */, MessageQueueUnsync::Descriptor());
+    } else {
+        _hidl_cb(true /* ret */, *mFmqUnsynchronized->getDesc());
+    }
+    return Void();
+}
+
+Return<bool> TestMsgQ::requestWriteFmqSync(int32_t count) {
+    std::vector<uint16_t> data(count);
+    for (int i = 0; i < count; i++) {
+        data[i] = i;
+    }
+    bool result = mFmqSynchronized->write(&data[0], count);
+    return result;
+}
+
+Return<bool> TestMsgQ::requestReadFmqSync(int32_t count) {
+    std::vector<uint16_t> data(count);
+    bool result = mFmqSynchronized->read(&data[0], count)
+            && verifyData(&data[0], count);
+    return result;
+}
+
+Return<bool> TestMsgQ::requestWriteFmqUnsync(int32_t count) {
+    std::vector<uint16_t> data(count);
+    for (int i = 0; i < count; i++) {
+        data[i] = i;
+    }
+    bool result = mFmqUnsynchronized->write(&data[0], count);
+    return result;
+}
+
+Return<bool> TestMsgQ::requestReadFmqUnsync(int32_t count) {
+    std::vector<uint16_t> data(count);
+    bool result =
+            mFmqUnsynchronized->read(&data[0], count) && verifyData(&data[0], count);
+    return result;
+}
+
+Return<void> TestMsgQ::requestBlockingRead(int32_t count) {
+    std::vector<uint16_t> data(count);
+    bool result = mFmqSynchronized->readBlocking(
+            &data[0],
+            count,
+            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+            static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+            5000000000 /* timeOutNanos */);
+
+    if (result == false) {
+        ALOGE("Blocking read fails");
+    }
+    return Void();
+}
+
+Return<void> TestMsgQ::requestBlockingReadDefaultEventFlagBits(int32_t count) {
+    std::vector<uint16_t> data(count);
+    bool result = mFmqSynchronized->readBlocking(
+            &data[0],
+            count);
+
+    if (result == false) {
+        ALOGE("Blocking read fails");
+    }
+
+    return Void();
+}
+
+Return<void> TestMsgQ::requestBlockingReadRepeat(int32_t count, int32_t numIter) {
+    std::vector<uint16_t> data(count);
+    for (int i = 0; i < numIter; i++) {
+        bool result = mFmqSynchronized->readBlocking(
+                &data[0],
+                count,
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
+                static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
+                5000000000 /* timeOutNanos */);
+
+        if (result == false) {
+            ALOGE("Blocking read fails");
+            break;
+        }
+    }
+    return Void();
+}
+
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+ITestMsgQ* HIDL_FETCH_ITestMsgQ(const char* /* name */) {
+    return new TestMsgQ();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace msgq
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
diff --git a/tests/msgq/1.0/default/TestMsgQ.h b/tests/msgq/1.0/default/TestMsgQ.h
new file mode 100644
index 0000000..760d931
--- /dev/null
+++ b/tests/msgq/1.0/default/TestMsgQ.h
@@ -0,0 +1,77 @@
+#ifndef ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H
+#define ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H
+
+#include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <fmq/MessageQueue.h>
+#include <fmq/EventFlag.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace msgq {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tests::msgq::V1_0::ITestMsgQ;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::kUnsynchronizedWrite;
+using android::hardware::MQDescriptorSync;
+using android::hardware::MQDescriptorUnsync;
+
+using android::hardware::MessageQueue;
+
+struct TestMsgQ : public ITestMsgQ {
+    typedef MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync;
+    typedef MessageQueue<uint16_t, kUnsynchronizedWrite> MessageQueueUnsync;
+
+    TestMsgQ() : mFmqSynchronized(nullptr), mFmqUnsynchronized(nullptr) {}
+
+    // Methods from ::android::hardware::tests::msgq::V1_0::ITestMsgQ follow.
+    Return<void> configureFmqSyncReadWrite(configureFmqSyncReadWrite_cb _hidl_cb) override;
+    Return<void> getFmqUnsyncWrite(bool configureFmq, getFmqUnsyncWrite_cb _hidl_cb) override;
+    Return<bool> requestWriteFmqSync(int32_t count) override;
+    Return<bool> requestReadFmqSync(int32_t count) override;
+    Return<bool> requestWriteFmqUnsync(int32_t count) override;
+    Return<bool> requestReadFmqUnsync(int32_t count) override;
+    Return<void> requestBlockingRead(int32_t count) override;
+    Return<void> requestBlockingReadDefaultEventFlagBits(int32_t count) override;
+    Return<void> requestBlockingReadRepeat(int32_t count, int32_t numIter) override;
+
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+private:
+    std::unique_ptr<MessageQueueSync> mFmqSynchronized;
+    std::unique_ptr<MessageQueueUnsync> mFmqUnsynchronized;
+
+    /*
+     * Utility function to verify data read from the fast message queue.
+     */
+    bool verifyData(uint16_t* data, int count) {
+        for (int i = 0; i < count; i++) {
+            if (data[i] != i) return false;
+        }
+        return true;
+    }
+};
+
+extern "C" ITestMsgQ* HIDL_FETCH_ITestMsgQ(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace msgq
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H