Adding AidlMessageQueue

This adds an AIDL compatible version of MessageQueue that returns an
AIDL parcelable to be passed between processes. The returned parcelable
is used to create a new instance of the MessageQueue.

Tests were run on 32-bit Cuttlefish as well as 64-bit Flame device.

Test: atest fmq_unit_tests && system/tools/hidl/test/run_all_device_tests.sh
Bug: 142326204

Change-Id: I0fac5065c6d5d0686aa6fd48ca1109417246718c
diff --git a/tests/aidl/default/TestAidlMsgQ.cpp b/tests/aidl/default/TestAidlMsgQ.cpp
new file mode 100644
index 0000000..0d6153e
--- /dev/null
+++ b/tests/aidl/default/TestAidlMsgQ.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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& 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, MQDescriptor* mqDesc,
+                                                   bool* _aidl_return) {
+    if (configureFmq) {
+        static constexpr size_t kNumElementsInQueue = 1024;
+        mFmqUnsynchronized.reset(new (std::nothrow)
+                                         TestAidlMsgQ::MessageQueueUnsync(kNumElementsInQueue));
+    }
+
+    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<uint16_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<uint16_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<uint16_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<uint16_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<uint16_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<uint16_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<uint16_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