Reland "Add template arguments to MQDescriptor for AIDL" am: 1b2d0a6a13 am: 889a826008

Original change: https://android-review.googlesource.com/c/platform/system/libfmq/+/1434352

Change-Id: I66917d2fe7b0b75a68159f4f32e3d78c24e18255
diff --git a/include/fmq/AidlMQDescriptorShim.h b/include/fmq/AidlMQDescriptorShim.h
index ea5fed9..eb4bbc2 100644
--- a/include/fmq/AidlMQDescriptorShim.h
+++ b/include/fmq/AidlMQDescriptorShim.h
@@ -18,18 +18,25 @@
 #include <cutils/native_handle.h>
 #include <fmq/MQDescriptorBase.h>
 #include <limits>
+#include <type_traits>
 
 namespace android {
 namespace details {
 
 using aidl::android::hardware::common::GrantorDescriptor;
 using aidl::android::hardware::common::MQDescriptor;
+using aidl::android::hardware::common::SynchronizedReadWrite;
+using aidl::android::hardware::common::UnsynchronizedWrite;
 using android::hardware::MQFlavor;
 
 template <typename T, MQFlavor flavor>
 struct AidlMQDescriptorShim {
     // Takes ownership of handle
-    AidlMQDescriptorShim(const MQDescriptor& desc);
+    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,
@@ -71,7 +78,10 @@
 };
 
 template <typename T, MQFlavor flavor>
-AidlMQDescriptorShim<T, flavor>::AidlMQDescriptorShim(const MQDescriptor& desc)
+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.
diff --git a/include/fmq/AidlMessageQueue.h b/include/fmq/AidlMessageQueue.h
index fe4edc4..eaef087 100644
--- a/include/fmq/AidlMessageQueue.h
+++ b/include/fmq/AidlMessageQueue.h
@@ -17,22 +17,41 @@
 #pragma once
 
 #include <aidl/android/hardware/common/MQDescriptor.h>
+#include <aidl/android/hardware/common/SynchronizedReadWrite.h>
+#include <aidl/android/hardware/common/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::MQDescriptor;
+using aidl::android::hardware::common::SynchronizedReadWrite;
+using aidl::android::hardware::common::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;
 
-template <typename T, MQFlavor flavor>
-struct AidlMessageQueue final : public MessageQueueBase<AidlMQDescriptorShim, T, flavor> {
-    typedef AidlMQDescriptorShim<T, flavor> Descriptor;
+template <typename T, typename U>
+struct AidlMessageQueue final
+    : public MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value> {
+    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
@@ -43,7 +62,7 @@
      * @param resetPointers Boolean indicating whether the read/write pointers
      * should be reset or not.
      */
-    AidlMessageQueue(const MQDescriptor& desc, bool resetPointers = true);
+    AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers = true);
     ~AidlMessageQueue() = default;
 
     /**
@@ -55,7 +74,7 @@
      * also be allocated and mapped for an EventFlag word.
      */
     AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false);
-    MQDescriptor dupeDesc();
+    MQDescriptor<T, U> dupeDesc();
 
   private:
     AidlMessageQueue(const AidlMessageQueue& other) = delete;
@@ -63,19 +82,19 @@
     AidlMessageQueue() = delete;
 };
 
-template <typename T, MQFlavor flavor>
-AidlMessageQueue<T, flavor>::AidlMessageQueue(const MQDescriptor& desc, bool resetPointers)
-    : MessageQueueBase<AidlMQDescriptorShim, T, flavor>(Descriptor(desc), resetPointers) {}
+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, MQFlavor flavor>
-AidlMessageQueue<T, flavor>::AidlMessageQueue(size_t numElementsInQueue,
-                                              bool configureEventFlagWord)
-    : MessageQueueBase<AidlMQDescriptorShim, T, flavor>(numElementsInQueue,
-                                                        configureEventFlagWord) {}
+template <typename T, typename U>
+AidlMessageQueue<T, U>::AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord)
+    : MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>(
+              numElementsInQueue, configureEventFlagWord) {}
 
-template <typename T, MQFlavor flavor>
-MQDescriptor AidlMessageQueue<T, flavor>::dupeDesc() {
-    auto* shim = MessageQueueBase<AidlMQDescriptorShim, T, flavor>::getDesc();
+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::GrantorDescriptor> grantors;
         for (const auto& grantor : shim->grantors()) {
@@ -83,14 +102,14 @@
                     .offset = static_cast<int32_t>(grantor.offset),
                     .extent = static_cast<int64_t>(grantor.extent)});
         }
-        return MQDescriptor{
+        return MQDescriptor<T, U>{
                 .quantum = static_cast<int32_t>(shim->getQuantum()),
                 .grantors = grantors,
                 .flags = static_cast<int32_t>(shim->getFlags()),
                 .fileDescriptor = ndk::ScopedFileDescriptor(dup(shim->handle()->data[0])),
         };
     } else {
-        return MQDescriptor();
+        return MQDescriptor<T, U>();
     }
 }
 
diff --git a/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl b/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
index 7b57e8c..6540ed3 100644
--- a/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
+++ b/tests/aidl/android/fmq/test/ITestAidlMsgQ.aidl
@@ -17,6 +17,8 @@
 package android.fmq.test;
 
 import android.hardware.common.MQDescriptor;
+import android.hardware.common.SynchronizedReadWrite;
+import android.hardware.common.UnsynchronizedWrite;
 
 /**
  * Test interface for MQDescriptor.
@@ -31,7 +33,7 @@
      *
      * @return True if the setup is successful.
      */
-    boolean configureFmqSyncReadWrite(in MQDescriptor mqDesc);
+    boolean configureFmqSyncReadWrite(in MQDescriptor<int, SynchronizedReadWrite> mqDesc);
 
     /**
      * This method requests the service to return an MQDescriptor to
@@ -47,7 +49,7 @@
      * set up by the service. Client can use it to set up the FMQ at its end.
      */
     boolean getFmqUnsyncWrite(in boolean configureFmq,
-        out MQDescriptor mqDesc);
+        out MQDescriptor<int, UnsynchronizedWrite> mqDesc);
 
     /**
      * This method requests the service to trigger a blocking read.
diff --git a/tests/aidl/default/TestAidlMsgQ.cpp b/tests/aidl/default/TestAidlMsgQ.cpp
index 2c5bd69..baec3e6 100644
--- a/tests/aidl/default/TestAidlMsgQ.cpp
+++ b/tests/aidl/default/TestAidlMsgQ.cpp
@@ -22,8 +22,8 @@
 namespace test {
 
 // Methods from ::aidl::android::fmq::test::ITestAidlMsgQ follow.
-ndk::ScopedAStatus TestAidlMsgQ::configureFmqSyncReadWrite(const MQDescriptor& mqDesc,
-                                                           bool* _aidl_return) {
+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);
@@ -39,8 +39,8 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus TestAidlMsgQ::getFmqUnsyncWrite(bool configureFmq, MQDescriptor* mqDesc,
-                                                   bool* _aidl_return) {
+ndk::ScopedAStatus TestAidlMsgQ::getFmqUnsyncWrite(
+        bool configureFmq, MQDescriptor<int32_t, UnsynchronizedWrite>* mqDesc, bool* _aidl_return) {
     if (configureFmq) {
         static constexpr size_t kNumElementsInQueue = 1024;
         mFmqUnsynchronized.reset(new (std::nothrow)
diff --git a/tests/aidl/default/TestAidlMsgQ.h b/tests/aidl/default/TestAidlMsgQ.h
index fc142b5..1a65406 100644
--- a/tests/aidl/default/TestAidlMsgQ.h
+++ b/tests/aidl/default/TestAidlMsgQ.h
@@ -30,6 +30,8 @@
 using ::aidl::android::fmq::test::ITestAidlMsgQ;
 
 using ::aidl::android::hardware::common::MQDescriptor;
+using ::aidl::android::hardware::common::SynchronizedReadWrite;
+using ::aidl::android::hardware::common::UnsynchronizedWrite;
 using ::android::hardware::kSynchronizedReadWrite;
 using ::android::hardware::kUnsynchronizedWrite;
 using ::android::hardware::MQFlavor;
@@ -37,15 +39,17 @@
 using ::android::AidlMessageQueue;
 
 struct TestAidlMsgQ : public BnTestAidlMsgQ {
-    typedef AidlMessageQueue<int32_t, kSynchronizedReadWrite> MessageQueueSync;
-    typedef AidlMessageQueue<int32_t, kUnsynchronizedWrite> MessageQueueUnsync;
+    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& mqDesc,
-                                                 bool* _aidl_return) override;
-    ndk::ScopedAStatus getFmqUnsyncWrite(bool configureFmq, MQDescriptor* mqDesc,
+    ndk::ScopedAStatus configureFmqSyncReadWrite(
+            const MQDescriptor<int32_t, SynchronizedReadWrite>& mqDesc,
+            bool* _aidl_return) override;
+    ndk::ScopedAStatus getFmqUnsyncWrite(bool configureFmq,
+                                         MQDescriptor<int32_t, UnsynchronizedWrite>* mqDesc,
                                          bool* _aidl_return) override;
     ndk::ScopedAStatus requestBlockingRead(int32_t count) override;
     ndk::ScopedAStatus requestBlockingReadDefaultEventFlagBits(int32_t count) override;
diff --git a/tests/fmq_unit_tests.cpp b/tests/fmq_unit_tests.cpp
index 0066d60..718867b 100644
--- a/tests/fmq_unit_tests.cpp
+++ b/tests/fmq_unit_tests.cpp
@@ -24,6 +24,8 @@
 #include <sstream>
 #include <thread>
 
+using aidl::android::hardware::common::SynchronizedReadWrite;
+using aidl::android::hardware::common::UnsynchronizedWrite;
 using android::hardware::kSynchronizedReadWrite;
 using android::hardware::kUnsynchronizedWrite;
 
@@ -32,11 +34,11 @@
     kFmqNotFull = 1 << 1,
 };
 
-typedef android::AidlMessageQueue<uint8_t, kSynchronizedReadWrite> AidlMessageQueueSync;
-typedef android::AidlMessageQueue<uint8_t, kUnsynchronizedWrite> AidlMessageQueueUnsync;
+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, kSynchronizedReadWrite> AidlMessageQueueSync16;
+typedef android::AidlMessageQueue<uint16_t, SynchronizedReadWrite> AidlMessageQueueSync16;
 typedef android::hardware::MessageQueue<uint16_t, kSynchronizedReadWrite> MessageQueueSync16;
 
 // Run everything on both the AIDL and HIDL versions with sync and unsync flavors
@@ -73,10 +75,10 @@
     size_t mNumMessagesMax = 0;
 };
 
-TYPED_TEST_CASE(UnsynchronizedWrite, UnsyncTypes);
+TYPED_TEST_CASE(UnsynchronizedWriteTest, UnsyncTypes);
 
 template <typename T>
-class UnsynchronizedWrite : public TestBase<T> {
+class UnsynchronizedWriteTest : public TestBase<T> {
   protected:
     virtual void TearDown() {
         delete mQueue;
@@ -243,7 +245,7 @@
 }
 
 TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptor) {
-    aidl::android::hardware::common::MQDescriptor desc;
+    aidl::android::hardware::common::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
     desc.quantum = -10;
     AidlMessageQueueSync16* fmq = new (std::nothrow) AidlMessageQueueSync16(desc);
     ASSERT_NE(nullptr, fmq);
@@ -254,7 +256,7 @@
 }
 
 TEST_F(AidlOnlyBadQueueConfig, NegativeAidlDescriptorGrantor) {
-    aidl::android::hardware::common::MQDescriptor desc;
+    aidl::android::hardware::common::MQDescriptor<uint16_t, SynchronizedReadWrite> desc;
     desc.quantum = 2;
     desc.flags = 0;
     desc.grantors.push_back(
@@ -700,7 +702,7 @@
 /*
  * Verify that a few bytes of data can be successfully written and read.
  */
-TYPED_TEST(UnsynchronizedWrite, SmallInputTest1) {
+TYPED_TEST(UnsynchronizedWriteTest, SmallInputTest1) {
     const size_t dataLen = 16;
     ASSERT_LE(dataLen, this->mNumMessagesMax);
     uint8_t data[dataLen];
@@ -715,7 +717,7 @@
 /*
  * Verify that read() returns false when trying to read from an empty queue.
  */
-TYPED_TEST(UnsynchronizedWrite, ReadWhenEmpty) {
+TYPED_TEST(UnsynchronizedWriteTest, ReadWhenEmpty) {
     ASSERT_EQ(0UL, this->mQueue->availableToRead());
     const size_t dataLen = 2;
     ASSERT_TRUE(dataLen < this->mNumMessagesMax);
@@ -727,7 +729,7 @@
  * Write the queue when full. Verify that a subsequent writes is succesful.
  * Verify that availableToWrite() returns 0 as expected.
  */
-TYPED_TEST(UnsynchronizedWrite, WriteWhenFull1) {
+TYPED_TEST(UnsynchronizedWriteTest, WriteWhenFull1) {
     ASSERT_EQ(0UL, this->mQueue->availableToRead());
     std::vector<uint8_t> data(this->mNumMessagesMax);
 
@@ -745,7 +747,7 @@
  * using beginRead()/commitRead() is succesful.
  * Verify that the next read fails as expected for unsynchronized flavor.
  */
-TYPED_TEST(UnsynchronizedWrite, WriteWhenFull2) {
+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));
@@ -768,7 +770,7 @@
  * Verify that the write is successful and the subsequent read
  * returns the expected data.
  */
-TYPED_TEST(UnsynchronizedWrite, LargeInputTest1) {
+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));
@@ -782,7 +784,7 @@
  * Verify that it fails. Verify that a subsequent read fails and
  * the queue is still empty.
  */
-TYPED_TEST(UnsynchronizedWrite, LargeInputTest2) {
+TYPED_TEST(UnsynchronizedWriteTest, LargeInputTest2) {
     ASSERT_EQ(0UL, this->mQueue->availableToRead());
     const size_t dataLen = 4096;
     ASSERT_GT(dataLen, this->mNumMessagesMax);
@@ -800,7 +802,7 @@
  * the attempt is succesful. Verify that the read fails
  * as expected.
  */
-TYPED_TEST(UnsynchronizedWrite, LargeInputTest3) {
+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));
@@ -812,7 +814,7 @@
 /*
  * Verify that multiple reads one after the other return expected data.
  */
-TYPED_TEST(UnsynchronizedWrite, MultipleRead) {
+TYPED_TEST(UnsynchronizedWriteTest, MultipleRead) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t dataLen = chunkSize * chunkNum;
@@ -830,7 +832,7 @@
 /*
  * Verify that multiple writes one after the other happens correctly.
  */
-TYPED_TEST(UnsynchronizedWrite, MultipleWrite) {
+TYPED_TEST(UnsynchronizedWriteTest, MultipleWrite) {
     const size_t chunkSize = 100;
     const size_t chunkNum = 5;
     const size_t dataLen = chunkSize * chunkNum;
@@ -853,7 +855,7 @@
  * Write mNumMessagesMax messages into the queue. This will cause a
  * wrap around. Read and verify the data.
  */
-TYPED_TEST(UnsynchronizedWrite, ReadWriteWrapAround) {
+TYPED_TEST(UnsynchronizedWriteTest, ReadWriteWrapAround) {
     size_t numMessages = this->mNumMessagesMax - 1;
     std::vector<uint8_t> data(this->mNumMessagesMax);
     std::vector<uint8_t> readData(this->mNumMessagesMax);
diff --git a/tests/msgq_test_client.cpp b/tests/msgq_test_client.cpp
index 042708f..a1648de 100644
--- a/tests/msgq_test_client.cpp
+++ b/tests/msgq_test_client.cpp
@@ -46,11 +46,13 @@
 using android::hardware::MQDescriptorUnsync;
 using android::hardware::details::waitForHwService;
 
+using aidl::android::hardware::common::SynchronizedReadWrite;
+using aidl::android::hardware::common::UnsynchronizedWrite;
 using android::hardware::kSynchronizedReadWrite;
 using android::hardware::kUnsynchronizedWrite;
 
-typedef android::AidlMessageQueue<int32_t, kSynchronizedReadWrite> AidlMessageQueueSync;
-typedef android::AidlMessageQueue<int32_t, kUnsynchronizedWrite> AidlMessageQueueUnsync;
+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";
@@ -133,7 +135,7 @@
     bool getFmqUnsyncWrite(bool configureFmq, std::shared_ptr<ITestAidlMsgQ> service,
                            AidlMessageQueueUnsync** queue) {
         bool result = false;
-        aidl::android::hardware::common::MQDescriptor desc;
+        aidl::android::hardware::common::MQDescriptor<int32_t, UnsynchronizedWrite> desc;
         auto ret = service->getFmqUnsyncWrite(configureFmq, &desc, &result);
         *queue = new (std::nothrow) AidlMessageQueueUnsync(desc);
         return result && ret.isOk();
@@ -712,7 +714,6 @@
  * the attempted write was unsuccessful. 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());