1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include <gtest/gtest.h>
18 #ifndef GTEST_IS_THREADSAFE
19 #error "GTest did not detect pthread library."
20 #endif
21 
22 #include <aidl/android/fmq/test/FixedParcelable.h>
23 #include <aidl/android/fmq/test/ITestAidlMsgQ.h>
24 #include <android-base/logging.h>
25 #include <android/binder_manager.h>
26 #include <android/binder_process.h>
27 #include <android/hardware/tests/msgq/1.0/ITestMsgQ.h>
28 #include <fmq/AidlMessageQueue.h>
29 #include <fmq/EventFlag.h>
30 #include <fmq/MessageQueue.h>
31 #include <hidl/ServiceManagement.h>
32 
33 // libutils:
34 using android::OK;
35 using android::sp;
36 using android::status_t;
37 
38 // generated
39 using ::aidl::android::fmq::test::EventFlagBits;
40 using ::aidl::android::fmq::test::FixedParcelable;
41 using ::aidl::android::fmq::test::ITestAidlMsgQ;
42 using android::hardware::tests::msgq::V1_0::ITestMsgQ;
43 
44 // libhidl
45 using android::hardware::kSynchronizedReadWrite;
46 using android::hardware::kUnsynchronizedWrite;
47 using android::hardware::MessageQueue;
48 using android::hardware::MQDescriptorSync;
49 using android::hardware::MQDescriptorUnsync;
50 using android::hardware::details::waitForHwService;
51 
52 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
53 using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
54 using android::hardware::kSynchronizedReadWrite;
55 using android::hardware::kUnsynchronizedWrite;
56 
57 typedef android::AidlMessageQueue<int32_t, SynchronizedReadWrite> AidlMessageQueueSync;
58 typedef android::AidlMessageQueue<int32_t, UnsynchronizedWrite> AidlMessageQueueUnsync;
59 typedef android::hardware::MessageQueue<int32_t, kSynchronizedReadWrite> MessageQueueSync;
60 typedef android::hardware::MessageQueue<int32_t, kUnsynchronizedWrite> MessageQueueUnsync;
61 static const std::string kServiceName = "BnTestAidlMsgQ";
62 static constexpr size_t kNumElementsInSyncQueue = (PAGE_SIZE - 16) / sizeof(int32_t);
63 
64 enum class SetupType {
65     SINGLE_FD,
66     DOUBLE_FD,
67 };
68 
69 template <typename T, SetupType setupType>
70 class TestParamTypes {
71   public:
72     typedef T MQType;
73     static constexpr bool UserFd = setupType == SetupType::DOUBLE_FD;
74 };
75 
76 // Run everything on both the AIDL and HIDL versions with one and two FDs
77 typedef ::testing::Types<TestParamTypes<AidlMessageQueueSync, SetupType::SINGLE_FD>,
78                          TestParamTypes<MessageQueueSync, SetupType::SINGLE_FD>,
79                          TestParamTypes<AidlMessageQueueSync, SetupType::DOUBLE_FD>,
80                          TestParamTypes<MessageQueueSync, SetupType::DOUBLE_FD>>
81         SyncTypes;
82 typedef ::testing::Types<TestParamTypes<AidlMessageQueueUnsync, SetupType::SINGLE_FD>,
83                          TestParamTypes<MessageQueueUnsync, SetupType::SINGLE_FD>,
84                          TestParamTypes<AidlMessageQueueUnsync, SetupType::DOUBLE_FD>,
85                          TestParamTypes<MessageQueueUnsync, SetupType::DOUBLE_FD>>
86         UnsyncTypes;
87 
88 template <typename T>
89 class ClientSyncTestBase : public ::testing::Test {};
90 
91 // Specialize for AIDL
92 template <>
93 class ClientSyncTestBase<AidlMessageQueueSync> : public ::testing::Test {
94   protected:
waitGetTestService()95     static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
96         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
97         ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
98         return ITestAidlMsgQ::fromBinder(binder);
99     }
configureFmqSyncReadWrite(AidlMessageQueueSync * mq)100     bool configureFmqSyncReadWrite(AidlMessageQueueSync* mq) {
101         bool result = false;
102         auto ret = mService->configureFmqSyncReadWrite(mq->dupeDesc(), &result);
103         return result && ret.isOk();
104     }
requestReadFmqSync(size_t dataLen)105     bool requestReadFmqSync(size_t dataLen) {
106         bool result = false;
107         auto ret = mService->requestReadFmqSync(dataLen, &result);
108         return result && ret.isOk();
109     }
requestWriteFmqSync(size_t dataLen)110     bool requestWriteFmqSync(size_t dataLen) {
111         bool result = false;
112         auto ret = mService->requestWriteFmqSync(dataLen, &result);
113         return result && ret.isOk();
114     }
115 
116     std::shared_ptr<ITestAidlMsgQ> mService;
117 };
118 
119 // Specialize for HIDL
120 template <>
121 class ClientSyncTestBase<MessageQueueSync> : public ::testing::Test {
122   protected:
waitGetTestService()123     static sp<ITestMsgQ> waitGetTestService() {
124         android::hardware::details::setTrebleTestingOverride(true);
125         // waitForHwService is required because ITestMsgQ is not in manifest.xml.
126         // "Real" HALs shouldn't be doing this.
127         waitForHwService(ITestMsgQ::descriptor, "default");
128         return ITestMsgQ::getService();
129     }
configureFmqSyncReadWrite(MessageQueueSync * mq)130     bool configureFmqSyncReadWrite(MessageQueueSync* mq) {
131         auto ret = mService->configureFmqSyncReadWrite(*mq->getDesc());
132         return ret && ret.isOk();
133     }
requestReadFmqSync(size_t dataLen)134     bool requestReadFmqSync(size_t dataLen) {
135         auto ret = mService->requestReadFmqSync(dataLen);
136         return ret && ret.isOk();
137     }
requestWriteFmqSync(size_t dataLen)138     bool requestWriteFmqSync(size_t dataLen) {
139         auto ret = mService->requestWriteFmqSync(dataLen);
140         return ret && ret.isOk();
141     }
142 
143     sp<ITestMsgQ> mService;
144 };
145 
146 template <typename T>
147 class ClientUnsyncTestBase : public ::testing::Test {};
148 
149 // Specialize for AIDL
150 template <>
151 class ClientUnsyncTestBase<AidlMessageQueueUnsync> : public ::testing::Test {
152   protected:
waitGetTestService()153     static std::shared_ptr<ITestAidlMsgQ> waitGetTestService() {
154         const std::string instance = std::string() + ITestAidlMsgQ::descriptor + "/default";
155         ndk::SpAIBinder binder(AServiceManager_getService(instance.c_str()));
156         return ITestAidlMsgQ::fromBinder(binder);
157     }
getFmqUnsyncWrite(bool configureFmq,bool userFd,std::shared_ptr<ITestAidlMsgQ> service,AidlMessageQueueUnsync ** queue)158     bool getFmqUnsyncWrite(bool configureFmq, bool userFd, std::shared_ptr<ITestAidlMsgQ> service,
159                            AidlMessageQueueUnsync** queue) {
160         bool result = false;
161         aidl::android::hardware::common::fmq::MQDescriptor<int32_t, UnsynchronizedWrite> desc;
162         auto ret = service->getFmqUnsyncWrite(configureFmq, userFd, &desc, &result);
163         *queue = new (std::nothrow) AidlMessageQueueUnsync(desc);
164         return result && ret.isOk();
165     }
166 
getQueue(AidlMessageQueueUnsync ** fmq,bool setupQueue,bool userFd)167     std::shared_ptr<ITestAidlMsgQ> getQueue(AidlMessageQueueUnsync** fmq, bool setupQueue,
168                                             bool userFd) {
169         std::shared_ptr<ITestAidlMsgQ> service = waitGetTestService();
170         if (service == nullptr) return nullptr;
171         getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
172         return service;
173     }
174 
requestReadFmqUnsync(size_t dataLen,std::shared_ptr<ITestAidlMsgQ> service)175     bool requestReadFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
176         bool result = false;
177         auto ret = service->requestReadFmqUnsync(dataLen, &result);
178         return result && ret.isOk();
179     }
requestWriteFmqUnsync(size_t dataLen,std::shared_ptr<ITestAidlMsgQ> service)180     bool requestWriteFmqUnsync(size_t dataLen, std::shared_ptr<ITestAidlMsgQ> service) {
181         bool result = false;
182         auto ret = service->requestWriteFmqUnsync(dataLen, &result);
183         return result && ret.isOk();
184     }
newQueue()185     AidlMessageQueueUnsync* newQueue() {
186         if (mQueue->isValid())
187             return new (std::nothrow) AidlMessageQueueUnsync(mQueue->dupeDesc());
188         else
189             return nullptr;
190     }
191 
192     std::shared_ptr<ITestAidlMsgQ> mService;
193     AidlMessageQueueUnsync* mQueue = nullptr;
194 };
195 
196 // Specialize for HIDL
197 template <>
198 class ClientUnsyncTestBase<MessageQueueUnsync> : public ::testing::Test {
199   protected:
waitGetTestService()200     static sp<ITestMsgQ> waitGetTestService() {
201         android::hardware::details::setTrebleTestingOverride(true);
202         // waitForHwService is required because ITestMsgQ is not in manifest.xml.
203         // "Real" HALs shouldn't be doing this.
204         waitForHwService(ITestMsgQ::descriptor, "default");
205         return ITestMsgQ::getService();
206     }
getFmqUnsyncWrite(bool configureFmq,bool userFd,sp<ITestMsgQ> service,MessageQueueUnsync ** queue)207     bool getFmqUnsyncWrite(bool configureFmq, bool userFd, sp<ITestMsgQ> service,
208                            MessageQueueUnsync** queue) {
209         if (!service) {
210             return false;
211         }
212         service->getFmqUnsyncWrite(configureFmq, userFd,
213                                    [queue](bool ret, const MQDescriptorUnsync<int32_t>& in) {
214                                        ASSERT_TRUE(ret);
215                                        *queue = new (std::nothrow) MessageQueueUnsync(in);
216                                    });
217         return true;
218     }
219 
getQueue(MessageQueueUnsync ** fmq,bool setupQueue,bool userFd)220     sp<ITestMsgQ> getQueue(MessageQueueUnsync** fmq, bool setupQueue, bool userFd) {
221         sp<ITestMsgQ> service = waitGetTestService();
222         if (service == nullptr) return nullptr;
223         getFmqUnsyncWrite(setupQueue, userFd, service, fmq);
224         return service;
225     }
226 
requestReadFmqUnsync(size_t dataLen,sp<ITestMsgQ> service)227     bool requestReadFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
228         auto ret = service->requestReadFmqUnsync(dataLen);
229         return ret && ret.isOk();
230     }
requestWriteFmqUnsync(size_t dataLen,sp<ITestMsgQ> service)231     bool requestWriteFmqUnsync(size_t dataLen, sp<ITestMsgQ> service) {
232         auto ret = service->requestWriteFmqUnsync(dataLen);
233         return ret && ret.isOk();
234     }
235 
newQueue()236     MessageQueueUnsync* newQueue() {
237         return new (std::nothrow) MessageQueueUnsync(*mQueue->getDesc());
238     }
239 
240     sp<ITestMsgQ> mService;
241     MessageQueueUnsync* mQueue = nullptr;
242 };
243 
244 TYPED_TEST_CASE(UnsynchronizedWriteClientMultiProcess, UnsyncTypes);
245 template <typename T>
246 class UnsynchronizedWriteClientMultiProcess : public ClientUnsyncTestBase<typename T::MQType> {};
247 
248 TYPED_TEST_CASE(SynchronizedReadWriteClient, SyncTypes);
249 template <typename T>
250 class SynchronizedReadWriteClient : public ClientSyncTestBase<typename T::MQType> {
251   protected:
TearDown()252     virtual void TearDown() {
253         delete mQueue;
254     }
255 
SetUp()256     virtual void SetUp() {
257         this->mService = this->waitGetTestService();
258         ASSERT_NE(this->mService, nullptr);
259         ASSERT_TRUE(this->mService->isRemote());
260         static constexpr size_t kSyncElementSizeBytes = sizeof(int32_t);
261         android::base::unique_fd ringbufferFd;
262         if (T::UserFd) {
263             ringbufferFd.reset(::ashmem_create_region(
264                     "SyncReadWrite", kNumElementsInSyncQueue * kSyncElementSizeBytes));
265         }
266         // create a queue on the client side
267         mQueue = new (std::nothrow) typename T::MQType(
268                 kNumElementsInSyncQueue, true /* configure event flag word */,
269                 std::move(ringbufferFd), kNumElementsInSyncQueue * kSyncElementSizeBytes);
270         ASSERT_NE(nullptr, mQueue);
271         ASSERT_TRUE(mQueue->isValid());
272         ASSERT_EQ(mQueue->getQuantumCount(), kNumElementsInSyncQueue);
273 
274         // tell server to set up the queue on its end
275         ASSERT_TRUE(this->configureFmqSyncReadWrite(mQueue));
276     }
277 
278     typename T::MQType* mQueue = nullptr;
279 };
280 
281 TYPED_TEST_CASE(UnsynchronizedWriteClient, UnsyncTypes);
282 template <typename T>
283 class UnsynchronizedWriteClient : public ClientUnsyncTestBase<typename T::MQType> {
284   protected:
TearDown()285     virtual void TearDown() { delete this->mQueue; }
286 
SetUp()287     virtual void SetUp() {
288         this->mService = this->waitGetTestService();
289         ASSERT_NE(this->mService, nullptr);
290         ASSERT_TRUE(this->mService->isRemote());
291         this->getFmqUnsyncWrite(true, false, this->mService, &this->mQueue);
292         ASSERT_NE(nullptr, this->mQueue);
293         ASSERT_TRUE(this->mQueue->isValid());
294         mNumMessagesMax = this->mQueue->getQuantumCount();
295     }
296 
297     size_t mNumMessagesMax = 0;
298 };
299 
300 /*
301  * Utility function to verify data read from the fast message queue.
302  */
verifyData(int32_t * data,size_t count)303 bool verifyData(int32_t* data, size_t count) {
304     for (size_t i = 0; i < count; i++) {
305         if (data[i] != i) return false;
306     }
307     return true;
308 }
309 
310 /*
311  * Utility function to initialize data to be written to the FMQ
312  */
initData(int32_t * data,size_t count)313 inline void initData(int32_t* data, size_t count) {
314     for (size_t i = 0; i < count; i++) {
315         data[i] = i;
316     }
317 }
318 
319 /*
320  * Verify that for an unsynchronized flavor of FMQ, multiple readers
321  * can recover from a write overflow condition.
322  */
TYPED_TEST(UnsynchronizedWriteClientMultiProcess,MultipleReadersAfterOverflow)323 TYPED_TEST(UnsynchronizedWriteClientMultiProcess, MultipleReadersAfterOverflow) {
324     const size_t dataLen = 16;
325 
326     pid_t pid;
327     /* creating first reader process */
328     if ((pid = fork()) == 0) {
329         typename TypeParam::MQType* queue = nullptr;
330         auto service =
331                 this->getQueue(&queue, true /* setupQueue */, TypeParam::UserFd /* userFd */);
332         ASSERT_NE(service, nullptr);
333         ASSERT_TRUE(service->isRemote());
334         ASSERT_NE(queue, nullptr);
335         ASSERT_TRUE(queue->isValid());
336 
337         size_t numMessagesMax = queue->getQuantumCount();
338 
339         // The following two writes will cause a write overflow.
340         auto ret = this->requestWriteFmqUnsync(numMessagesMax, service);
341         ASSERT_TRUE(ret);
342 
343         ret = this->requestWriteFmqUnsync(1, service);
344         ASSERT_TRUE(ret);
345 
346         // The following read should fail due to the overflow.
347         std::vector<int32_t> readData(numMessagesMax);
348         ASSERT_FALSE(queue->read(&readData[0], numMessagesMax));
349 
350         /*
351          * Request another write to verify that the reader can recover from the
352          * overflow condition.
353          */
354         ASSERT_LT(dataLen, numMessagesMax);
355         ret = this->requestWriteFmqUnsync(dataLen, service);
356         ASSERT_TRUE(ret);
357 
358         // Verify that the read is successful.
359         ASSERT_TRUE(queue->read(&readData[0], dataLen));
360         ASSERT_TRUE(verifyData(&readData[0], dataLen));
361 
362         delete queue;
363         exit(0);
364     }
365 
366     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
367 
368     int status;
369     // wait for the first reader process to exit.
370     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
371 
372     // creating second reader process.
373     if ((pid = fork()) == 0) {
374         typename TypeParam::MQType* queue = nullptr;
375         auto service = this->getQueue(&queue, false /* setupQueue */, false /* userFd */);
376         ASSERT_NE(service, nullptr);
377         ASSERT_TRUE(service->isRemote());
378         ASSERT_NE(queue, nullptr);
379         ASSERT_TRUE(queue->isValid());
380 
381         // This read should fail due to the write overflow.
382         std::vector<int32_t> readData(dataLen);
383         ASSERT_FALSE(queue->read(&readData[0], dataLen));
384 
385         /*
386          * Request another write to verify that the process that recover from
387          * the overflow condition.
388          */
389         auto ret = this->requestWriteFmqUnsync(dataLen, service);
390         ASSERT_TRUE(ret);
391 
392         // verify that the read is successful.
393         ASSERT_TRUE(queue->read(&readData[0], dataLen));
394         ASSERT_TRUE(verifyData(&readData[0], dataLen));
395 
396         delete queue;
397         exit(0);
398     }
399 
400     ASSERT_GT(pid, 0 /* parent should see PID greater than 0 for a good fork */);
401     ASSERT_EQ(pid, waitpid(pid, &status, 0 /* options */));
402 }
403 
404 /*
405  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
406  * using the EventFlag object owned by FMQ.
407  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWrite1)408 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite1) {
409     const size_t dataLen = 64;
410     bool ret = false;
411     /*
412      * Request service to perform a blocking read. This call is oneway and will
413      * return immediately.
414      */
415     this->mService->requestBlockingRead(dataLen);
416     {
417         std::array<int32_t, dataLen> data = {0};
418         ret = this->mQueue->writeBlocking(
419                 data.data(), data.size(),
420                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
421                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
422                 5000000000 /* timeOutNanos */);
423         ASSERT_TRUE(ret);
424     }
425     {
426         std::array<int32_t, kNumElementsInSyncQueue> data = {0};
427         ret = this->mQueue->writeBlocking(
428                 data.data(), data.size(),
429                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
430                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
431                 5000000000 /* timeOutNanos */);
432         ASSERT_TRUE(ret);
433     }
434 }
435 
436 /*
437  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
438  * using the EventFlag object owned by FMQ and using the default EventFlag
439  * notification bit mask.
440  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWrite2)441 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWrite2) {
442     const size_t dataLen = 64;
443     bool ret = false;
444 
445     /*
446      * Request service to perform a blocking read using default EventFlag
447      * notification bit mask. This call is oneway and will
448      * return immediately.
449      */
450     this->mService->requestBlockingReadDefaultEventFlagBits(dataLen);
451 
452     /* Cause a context switch to allow service to block */
453     sched_yield();
454     {
455         std::array<int32_t, dataLen> data = {0};
456         ret = this->mQueue->writeBlocking(data.data(), data.size());
457         ASSERT_TRUE(ret);
458     }
459 
460     /*
461      * If the blocking read was successful, another write of size
462      * kNumElementsInSyncQueue will succeed.
463      */
464     {
465         std::array<int32_t, kNumElementsInSyncQueue> data = {0};
466         ret = this->mQueue->writeBlocking(data.data(), data.size(), 5000000000 /* timeOutNanos */);
467         ASSERT_TRUE(ret);
468     }
469 }
470 
471 /*
472  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
473  * using the EventFlag object owned by FMQ.
474  * Each write operation writes the same amount of data as a single read
475  * operation.
476  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat1)477 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat1) {
478     const size_t dataLen = 64;
479     bool ret = false;
480 
481     /*
482      * Request service to perform a blocking read of 64 elements. This call is
483      * oneway and will return immediately.
484      */
485     const size_t writeCount = kNumElementsInSyncQueue;
486     this->mService->requestBlockingReadRepeat(dataLen, writeCount);
487     /*
488      * Write 64 elements into the queue for the service to consume
489      */
490     {
491         std::array<int32_t, dataLen> data = {0};
492         for (size_t i = 0; i < writeCount; i++) {
493             ret = this->mQueue->writeBlocking(
494                     data.data(), data.size(),
495                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
496                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
497                     5000000000 /* timeOutNanos */);
498             ASSERT_TRUE(ret);
499         }
500     }
501     /*
502      * The queue should be totally empty now, so filling it up entirely with one
503      * blocking write should be successful.
504      */
505     {
506         std::array<int32_t, kNumElementsInSyncQueue> data = {0};
507         ret = this->mQueue->writeBlocking(
508                 data.data(), data.size(),
509                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
510                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
511                 5000000000 /* timeOutNanos */);
512 
513         ASSERT_TRUE(ret);
514     }
515 }
516 
517 /*
518  * Test that repeated blocking reads and writes work using readBlocking()/writeBlocking() APIs
519  * using the EventFlag object owned by FMQ. Each read operation reads twice the
520  * amount of data as a single write.
521  *
522  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat2)523 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat2) {
524     const size_t dataLen = 64;
525     bool ret = false;
526     /*
527      * Request service to perform a repeated blocking read. This call is oneway
528      * and will return immediately. It will read 64 * 2 elements with each
529      * blocking read, for a total of writeCount / 2 calls.
530      */
531     const size_t writeCount = kNumElementsInSyncQueue;
532     this->mService->requestBlockingReadRepeat(dataLen * 2, writeCount / 2);
533     /*
534      * Write 64 elements into the queue writeCount times
535      */
536     {
537         std::array<int32_t, dataLen> data = {0};
538         for (size_t i = 0; i < writeCount; i++) {
539             ret = this->mQueue->writeBlocking(
540                     data.data(), data.size(),
541                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
542                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
543                     5000000000 /* timeOutNanos */);
544             ASSERT_TRUE(ret);
545         }
546     }
547     /*
548      * The queue should be totally empty now, so filling it up entirely with one
549      * blocking write should be successful.
550      */
551     {
552         std::array<int32_t, kNumElementsInSyncQueue> data = {0};
553         ret = this->mQueue->writeBlocking(
554                 data.data(), data.size(),
555                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
556                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
557                 5000000000 /* timeOutNanos */);
558         ASSERT_TRUE(ret);
559     }
560 }
561 
562 /*
563  * Test that basic blocking works using readBlocking()/writeBlocking() APIs
564  * using the EventFlag object owned by FMQ. Each write operation writes twice
565  * the amount of data as a single read.
566  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteRepeat3)567 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteRepeat3) {
568     const size_t dataLen = 64;
569     bool ret = false;
570 
571     /*
572      * Request service to perform a repeated blocking read. This call is oneway
573      * and will return immediately. It will read 64 / 2 elements with each
574      * blocking read, for a total of writeCount * 2 calls.
575      */
576     size_t writeCount = 1024;
577     this->mService->requestBlockingReadRepeat(dataLen / 2, writeCount * 2);
578     /*
579      * Write 64 elements into the queue writeCount times
580      */
581     {
582         std::array<int32_t, dataLen> data = {0};
583         for (size_t i = 0; i < writeCount; i++) {
584             ret = this->mQueue->writeBlocking(
585                     data.data(), data.size(),
586                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
587                     static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
588                     5000000000 /* timeOutNanos */);
589             ASSERT_TRUE(ret);
590         }
591     }
592     /*
593      * The queue should be totally empty now, so filling it up entirely with one
594      * blocking write should be successful.
595      */
596     {
597         std::array<int32_t, kNumElementsInSyncQueue> data = {0};
598         ret = this->mQueue->writeBlocking(
599                 data.data(), data.size(),
600                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
601                 static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY),
602                 5000000000 /* timeOutNanos */);
603         ASSERT_TRUE(ret);
604     }
605 }
606 
607 /*
608  * Test that writeBlocking()/readBlocking() APIs do not block on
609  * attempts to write/read 0 messages and return true.
610  */
TYPED_TEST(SynchronizedReadWriteClient,BlockingReadWriteZeroMessages)611 TYPED_TEST(SynchronizedReadWriteClient, BlockingReadWriteZeroMessages) {
612     int32_t data = 0;
613 
614     /*
615      * Trigger a blocking write for zero messages with no timeout.
616      */
617     bool ret = this->mQueue->writeBlocking(
618             &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
619             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
620     ASSERT_TRUE(ret);
621 
622     /*
623      * Trigger a blocking read for zero messages with no timeout.
624      */
625     ret = this->mQueue->readBlocking(
626             &data, 0, static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_FULL),
627             static_cast<uint32_t>(ITestMsgQ::EventFlagBits::FMQ_NOT_EMPTY));
628     ASSERT_TRUE(ret);
629 }
630 
631 /*
632  * Request mService to write a small number of messages
633  * to the FMQ. Read and verify data.
634  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputReaderTest1)635 TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest1) {
636     const size_t dataLen = 16;
637     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
638     bool ret = this->requestWriteFmqSync(dataLen);
639     ASSERT_TRUE(ret);
640     int32_t readData[dataLen] = {};
641     ASSERT_TRUE(this->mQueue->read(readData, dataLen));
642     ASSERT_TRUE(verifyData(readData, dataLen));
643 }
644 
645 /*
646  * Request mService to write a message to the queue followed by a beginRead().
647  * Get a pointer to the memory region for the that first message. Set the write
648  * counter to the last byte in the ring buffer. Request another write from
649  * mService. The write should fail because the write address is misaligned.
650  */
TYPED_TEST(SynchronizedReadWriteClient,MisalignedWriteCounter)651 TYPED_TEST(SynchronizedReadWriteClient, MisalignedWriteCounter) {
652     if (TypeParam::UserFd) {
653         // When using the second FD for the ring buffer, we can't get to the read/write
654         // counters from a pointer to the ring buffer, so no sense in testing.
655         GTEST_SKIP();
656     }
657     const size_t dataLen = 1;
658     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
659     bool ret = this->requestWriteFmqSync(dataLen);
660     ASSERT_TRUE(ret);
661     // begin read and get a MemTransaction object for the first object in the queue
662     typename TypeParam::MQType::MemTransaction tx;
663     ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
664     // get a pointer to the beginning of the ring buffer
665     const auto& region = tx.getFirstRegion();
666     int32_t* firstStart = region.getAddress();
667 
668     // because this is the first location in the ring buffer, we can get
669     // access to the read and write pointer stored in the fd. 8 bytes back for the
670     // write counter and 16 bytes back for the read counter
671     uint64_t* writeCntr = (uint64_t*)((uint8_t*)firstStart - 8);
672 
673     // set it to point to the very last byte in the ring buffer
674     *(writeCntr) = this->mQueue->getQuantumCount() * this->mQueue->getQuantumSize() - 1;
675     ASSERT_TRUE(*writeCntr % sizeof(int32_t) != 0);
676 
677     // this is not actually necessary, but it's the expected the pattern.
678     this->mQueue->commitRead(dataLen);
679 
680     // This next write will be misaligned and will overlap outside of the ring buffer.
681     // The write should fail.
682     ret = this->requestWriteFmqSync(dataLen);
683     EXPECT_FALSE(ret);
684 }
685 
686 /*
687  * Request mService to write a small number of messages
688  * to the FMQ. Read and verify each message using
689  * beginRead/Commit read APIs.
690  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputReaderTest2)691 TYPED_TEST(SynchronizedReadWriteClient, SmallInputReaderTest2) {
692     const size_t dataLen = 16;
693     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
694     auto ret = this->requestWriteFmqSync(dataLen);
695     ASSERT_TRUE(ret);
696 
697     typename TypeParam::MQType::MemTransaction tx;
698     ASSERT_TRUE(this->mQueue->beginRead(dataLen, &tx));
699 
700     auto first = tx.getFirstRegion();
701     auto second = tx.getSecondRegion();
702     size_t firstRegionLength = first.getLength();
703 
704     for (size_t i = 0; i < dataLen; i++) {
705         if (i < firstRegionLength) {
706             ASSERT_EQ(i, *(first.getAddress() + i));
707         } else {
708             ASSERT_EQ(i, *(second.getAddress() + i - firstRegionLength));
709         }
710     }
711 
712     ASSERT_TRUE(this->mQueue->commitRead(dataLen));
713 }
714 
715 /*
716  * Write a small number of messages to FMQ. Request
717  * mService to read and verify that the write was successful.
718  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputWriterTest1)719 TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest1) {
720     const size_t dataLen = 16;
721     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
722     size_t originalCount = this->mQueue->availableToWrite();
723     int32_t data[dataLen];
724     initData(data, dataLen);
725     ASSERT_TRUE(this->mQueue->write(data, dataLen));
726     bool ret = this->requestReadFmqSync(dataLen);
727     ASSERT_TRUE(ret);
728     size_t availableCount = this->mQueue->availableToWrite();
729     ASSERT_EQ(originalCount, availableCount);
730 }
731 
732 /*
733  * Write a small number of messages to FMQ using the beginWrite()/CommitWrite()
734  * APIs. Request mService to read and verify that the write was successful.
735  */
TYPED_TEST(SynchronizedReadWriteClient,SmallInputWriterTest2)736 TYPED_TEST(SynchronizedReadWriteClient, SmallInputWriterTest2) {
737     const size_t dataLen = 16;
738     ASSERT_LE(dataLen, kNumElementsInSyncQueue);
739     size_t originalCount = this->mQueue->availableToWrite();
740     int32_t data[dataLen];
741     initData(data, dataLen);
742 
743     typename TypeParam::MQType::MemTransaction tx;
744     ASSERT_TRUE(this->mQueue->beginWrite(dataLen, &tx));
745 
746     auto first = tx.getFirstRegion();
747     auto second = tx.getSecondRegion();
748 
749     size_t firstRegionLength = first.getLength();
750     int32_t* firstBaseAddress = first.getAddress();
751     int32_t* secondBaseAddress = second.getAddress();
752 
753     for (size_t i = 0; i < dataLen; i++) {
754         if (i < firstRegionLength) {
755             *(firstBaseAddress + i) = i;
756         } else {
757             *(secondBaseAddress + i - firstRegionLength) = i;
758         }
759     }
760 
761     ASSERT_TRUE(this->mQueue->commitWrite(dataLen));
762 
763     auto ret = this->requestReadFmqSync(dataLen);
764     // ASSERT_TRUE(ret.isOk());
765     ASSERT_TRUE(ret);
766     size_t availableCount = this->mQueue->availableToWrite();
767     ASSERT_EQ(originalCount, availableCount);
768 }
769 
770 /*
771  * Verify that the FMQ is empty and read fails when it is empty.
772  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWhenEmpty)773 TYPED_TEST(SynchronizedReadWriteClient, ReadWhenEmpty) {
774     ASSERT_EQ(0UL, this->mQueue->availableToRead());
775     const size_t numMessages = 2;
776     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
777     int32_t readData[numMessages];
778     ASSERT_FALSE(this->mQueue->read(readData, numMessages));
779 }
780 
781 /*
782  * Verify FMQ is empty.
783  * Write enough messages to fill it.
784  * Verify availableToWrite() method returns is zero.
785  * Try writing another message and verify that
786  * the attempted write was unsuccessful. Request mService
787  * to read and verify the messages in the FMQ.
788  */
TYPED_TEST(SynchronizedReadWriteClient,WriteWhenFull)789 TYPED_TEST(SynchronizedReadWriteClient, WriteWhenFull) {
790     std::array<int32_t, kNumElementsInSyncQueue> data = {0};
791     initData(data.data(), data.size());
792     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
793     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
794     ASSERT_FALSE(this->mQueue->write(&data[0], 1));
795     bool ret = this->requestReadFmqSync(data.size());
796     ASSERT_TRUE(ret);
797 }
798 
799 /*
800  * Verify FMQ is empty.
801  * Request mService to write data equal to queue size.
802  * Read and verify data in mQueue.
803  */
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest1)804 TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest1) {
805     bool ret = this->requestWriteFmqSync(kNumElementsInSyncQueue);
806     ASSERT_TRUE(ret);
807     std::vector<int32_t> readData(kNumElementsInSyncQueue);
808     ASSERT_TRUE(this->mQueue->read(&readData[0], kNumElementsInSyncQueue));
809     ASSERT_TRUE(verifyData(&readData[0], kNumElementsInSyncQueue));
810 }
811 
812 /*
813  * Request mService to write more than maximum number of messages to the FMQ.
814  * Verify that the write fails. Verify that availableToRead() method
815  * still returns 0 and verify that attempt to read fails.
816  */
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest2)817 TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest2) {
818     ASSERT_EQ(0UL, this->mQueue->availableToRead());
819     const size_t numMessages = 2048;
820     ASSERT_GT(numMessages, kNumElementsInSyncQueue);
821     bool ret = this->requestWriteFmqSync(numMessages);
822     ASSERT_FALSE(ret);
823     int32_t readData;
824     ASSERT_EQ(0UL, this->mQueue->availableToRead());
825     ASSERT_FALSE(this->mQueue->read(&readData, 1));
826 }
827 
828 /*
829  * Write until FMQ is full.
830  * Verify that the number of messages available to write
831  * is equal to mNumMessagesMax.
832  * Verify that another write attempt fails.
833  * Request mService to read. Verify read count.
834  */
835 
TYPED_TEST(SynchronizedReadWriteClient,LargeInputTest3)836 TYPED_TEST(SynchronizedReadWriteClient, LargeInputTest3) {
837     std::array<int32_t, kNumElementsInSyncQueue> data = {0};
838     initData(data.data(), data.size());
839     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
840     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
841     ASSERT_FALSE(this->mQueue->write(data.data(), 1));
842 
843     bool ret = this->requestReadFmqSync(data.size());
844     ASSERT_TRUE(ret);
845 }
846 
847 /*
848  * Confirm that the FMQ is empty. Request mService to write to FMQ.
849  * Do multiple reads to empty FMQ and verify data.
850  */
TYPED_TEST(SynchronizedReadWriteClient,MultipleRead)851 TYPED_TEST(SynchronizedReadWriteClient, MultipleRead) {
852     const size_t chunkSize = 100;
853     const size_t chunkNum = 5;
854     const size_t numMessages = chunkSize * chunkNum;
855     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
856     size_t availableToRead = this->mQueue->availableToRead();
857     size_t expectedCount = 0;
858     ASSERT_EQ(expectedCount, availableToRead);
859     bool ret = this->requestWriteFmqSync(numMessages);
860     ASSERT_TRUE(ret);
861     int32_t readData[numMessages] = {};
862     for (size_t i = 0; i < chunkNum; i++) {
863         ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
864     }
865     ASSERT_TRUE(verifyData(readData, numMessages));
866 }
867 
868 /*
869  * Write to FMQ in bursts.
870  * Request mService to read data. Verify the read was successful.
871  */
TYPED_TEST(SynchronizedReadWriteClient,MultipleWrite)872 TYPED_TEST(SynchronizedReadWriteClient, MultipleWrite) {
873     const size_t chunkSize = 100;
874     const size_t chunkNum = 5;
875     const size_t numMessages = chunkSize * chunkNum;
876     ASSERT_LE(numMessages, kNumElementsInSyncQueue);
877     int32_t data[numMessages];
878     initData(&data[0], numMessages);
879 
880     for (size_t i = 0; i < chunkNum; i++) {
881         ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
882     }
883     bool ret = this->requestReadFmqSync(numMessages);
884     ASSERT_TRUE(ret);
885 }
886 
887 /*
888  * Write enough messages into the FMQ to fill half of it.
889  * Request mService to read back the same.
890  * Write mNumMessagesMax messages into the queue. This should cause a
891  * wrap around. Request mService to read and verify the data.
892  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWriteWrapAround)893 TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround) {
894     size_t numMessages = kNumElementsInSyncQueue / 2;
895     std::array<int32_t, kNumElementsInSyncQueue> data = {0};
896     initData(data.data(), data.size());
897     ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
898     bool ret = this->requestReadFmqSync(numMessages);
899     ASSERT_TRUE(ret);
900     ASSERT_TRUE(this->mQueue->write(data.data(), data.size()));
901     ret = this->requestReadFmqSync(data.size());
902     ASSERT_TRUE(ret);
903 }
904 
905 /*
906  * Use beginWrite/commitWrite/getSlot APIs to test wrap arounds are handled
907  * correctly.
908  * Write enough messages into the FMQ to fill half of it
909  * and read back the same.
910  * Write mNumMessagesMax messages into the queue. This will cause a
911  * wrap around. Read and verify the data.
912  */
TYPED_TEST(SynchronizedReadWriteClient,ReadWriteWrapAround2)913 TYPED_TEST(SynchronizedReadWriteClient, ReadWriteWrapAround2) {
914     size_t numMessages = kNumElementsInSyncQueue / 2;
915     std::array<int32_t, kNumElementsInSyncQueue> data = {0};
916     initData(data.data(), data.size());
917     ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
918     auto ret = this->requestReadFmqSync(numMessages);
919     ASSERT_TRUE(ret);
920 
921     /*
922      * The next write and read will have to deal with with wrap arounds.
923      */
924     typename TypeParam::MQType::MemTransaction tx;
925     ASSERT_TRUE(this->mQueue->beginWrite(data.size(), &tx));
926 
927     ASSERT_EQ(tx.getFirstRegion().getLength() + tx.getSecondRegion().getLength(), data.size());
928 
929     for (size_t i = 0; i < data.size(); i++) {
930         int32_t* ptr = tx.getSlot(i);
931         *ptr = data[i];
932     }
933 
934     ASSERT_TRUE(this->mQueue->commitWrite(data.size()));
935 
936     ret = this->requestReadFmqSync(data.size());
937     ASSERT_TRUE(ret);
938 }
939 
940 /*
941  * Request this->mService to write a small number of messages
942  * to the FMQ. Read and verify data.
943  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputReaderTest1)944 TYPED_TEST(UnsynchronizedWriteClient, SmallInputReaderTest1) {
945     const size_t dataLen = 16;
946     ASSERT_LE(dataLen, this->mNumMessagesMax);
947     bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
948     ASSERT_TRUE(ret);
949     int32_t readData[dataLen] = {};
950     ASSERT_TRUE(this->mQueue->read(readData, dataLen));
951     ASSERT_TRUE(verifyData(readData, dataLen));
952 }
953 
954 /*
955  * Write a small number of messages to FMQ. Request
956  * this->mService to read and verify that the write was successful.
957  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputWriterTest1)958 TYPED_TEST(UnsynchronizedWriteClient, SmallInputWriterTest1) {
959     const size_t dataLen = 16;
960     ASSERT_LE(dataLen, this->mNumMessagesMax);
961     int32_t data[dataLen];
962     initData(data, dataLen);
963     ASSERT_TRUE(this->mQueue->write(data, dataLen));
964     bool ret = this->requestReadFmqUnsync(dataLen, this->mService);
965     ASSERT_TRUE(ret);
966 }
967 
968 /*
969  * Verify that the FMQ is empty and read fails when it is empty.
970  */
TYPED_TEST(UnsynchronizedWriteClient,ReadWhenEmpty)971 TYPED_TEST(UnsynchronizedWriteClient, ReadWhenEmpty) {
972     ASSERT_EQ(0UL, this->mQueue->availableToRead());
973     const size_t numMessages = 2;
974     ASSERT_LE(numMessages, this->mNumMessagesMax);
975     int32_t readData[numMessages];
976     ASSERT_FALSE(this->mQueue->read(readData, numMessages));
977 }
978 
979 /*
980  * Verify FMQ is empty.
981  * Write enough messages to fill it.
982  * Verify availableToWrite() method returns is zero.
983  * Try writing another message and verify that
984  * the attempted write was successful. Request this->mService
985  * to read the messages in the FMQ and verify that it is unsuccessful.
986  */
987 
TYPED_TEST(UnsynchronizedWriteClient,WriteWhenFull)988 TYPED_TEST(UnsynchronizedWriteClient, WriteWhenFull) {
989     std::vector<int32_t> data(this->mNumMessagesMax);
990     initData(&data[0], this->mNumMessagesMax);
991     ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
992     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
993     ASSERT_TRUE(this->mQueue->write(&data[0], 1));
994     bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
995     ASSERT_FALSE(ret);
996 }
997 
998 /*
999  * Verify FMQ is empty.
1000  * Request this->mService to write data equal to queue size.
1001  * Read and verify data in this->mQueue.
1002  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest1)1003 TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest1) {
1004     bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
1005     ASSERT_TRUE(ret);
1006     std::vector<int32_t> data(this->mNumMessagesMax);
1007     ASSERT_TRUE(this->mQueue->read(&data[0], this->mNumMessagesMax));
1008     ASSERT_TRUE(verifyData(&data[0], this->mNumMessagesMax));
1009 }
1010 
1011 /*
1012  * Request this->mService to write more than maximum number of messages to the FMQ.
1013  * Verify that the write fails. Verify that availableToRead() method
1014  * still returns 0 and verify that attempt to read fails.
1015  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest2)1016 TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest2) {
1017     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1018     const size_t numMessages = this->mNumMessagesMax + 1;
1019     bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
1020     ASSERT_FALSE(ret);
1021     int32_t readData;
1022     ASSERT_EQ(0UL, this->mQueue->availableToRead());
1023     ASSERT_FALSE(this->mQueue->read(&readData, 1));
1024 }
1025 
1026 /*
1027  * Write until FMQ is full.
1028  * Verify that the number of messages available to write
1029  * is equal to this->mNumMessagesMax.
1030  * Verify that another write attempt is successful.
1031  * Request this->mService to read. Verify that read is unsuccessful.
1032  * Perform another write and verify that the read is successful
1033  * to check if the reader process can recover from the error condition.
1034  */
TYPED_TEST(UnsynchronizedWriteClient,LargeInputTest3)1035 TYPED_TEST(UnsynchronizedWriteClient, LargeInputTest3) {
1036     std::vector<int32_t> data(this->mNumMessagesMax);
1037     initData(&data[0], this->mNumMessagesMax);
1038     ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1039     ASSERT_EQ(0UL, this->mQueue->availableToWrite());
1040     ASSERT_TRUE(this->mQueue->write(&data[0], 1));
1041 
1042     bool ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
1043     ASSERT_FALSE(ret);
1044     ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1045 
1046     ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
1047     ASSERT_TRUE(ret);
1048 }
1049 
1050 /*
1051  * Confirm that the FMQ is empty. Request this->mService to write to FMQ.
1052  * Do multiple reads to empty FMQ and verify data.
1053  */
TYPED_TEST(UnsynchronizedWriteClient,MultipleRead)1054 TYPED_TEST(UnsynchronizedWriteClient, MultipleRead) {
1055     const size_t chunkSize = 100;
1056     const size_t chunkNum = 5;
1057     const size_t numMessages = chunkSize * chunkNum;
1058     ASSERT_LE(numMessages, this->mNumMessagesMax);
1059     size_t availableToRead = this->mQueue->availableToRead();
1060     size_t expectedCount = 0;
1061     ASSERT_EQ(expectedCount, availableToRead);
1062     bool ret = this->requestWriteFmqUnsync(numMessages, this->mService);
1063     ASSERT_TRUE(ret);
1064     int32_t readData[numMessages] = {};
1065     for (size_t i = 0; i < chunkNum; i++) {
1066         ASSERT_TRUE(this->mQueue->read(readData + i * chunkSize, chunkSize));
1067     }
1068     ASSERT_TRUE(verifyData(readData, numMessages));
1069 }
1070 
1071 /*
1072  * Write to FMQ in bursts.
1073  * Request this->mService to read data, verify that it was successful.
1074  */
TYPED_TEST(UnsynchronizedWriteClient,MultipleWrite)1075 TYPED_TEST(UnsynchronizedWriteClient, MultipleWrite) {
1076     const size_t chunkSize = 100;
1077     const size_t chunkNum = 5;
1078     const size_t numMessages = chunkSize * chunkNum;
1079     ASSERT_LE(numMessages, this->mNumMessagesMax);
1080     int32_t data[numMessages];
1081     initData(data, numMessages);
1082     for (size_t i = 0; i < chunkNum; i++) {
1083         ASSERT_TRUE(this->mQueue->write(data + i * chunkSize, chunkSize));
1084     }
1085     bool ret = this->requestReadFmqUnsync(numMessages, this->mService);
1086     ASSERT_TRUE(ret);
1087 }
1088 
1089 /*
1090  * Write enough messages into the FMQ to fill half of it.
1091  * Request this->mService to read back the same.
1092  * Write this->mNumMessagesMax messages into the queue. This should cause a
1093  * wrap around. Request this->mService to read and verify the data.
1094  */
TYPED_TEST(UnsynchronizedWriteClient,ReadWriteWrapAround)1095 TYPED_TEST(UnsynchronizedWriteClient, ReadWriteWrapAround) {
1096     size_t numMessages = this->mNumMessagesMax / 2;
1097     std::vector<int32_t> data(this->mNumMessagesMax);
1098     initData(&data[0], this->mNumMessagesMax);
1099     ASSERT_TRUE(this->mQueue->write(&data[0], numMessages));
1100     bool ret = this->requestReadFmqUnsync(numMessages, this->mService);
1101     ASSERT_TRUE(ret);
1102     ASSERT_TRUE(this->mQueue->write(&data[0], this->mNumMessagesMax));
1103     ret = this->requestReadFmqUnsync(this->mNumMessagesMax, this->mService);
1104     ASSERT_TRUE(ret);
1105 }
1106 
1107 /*
1108  * Request this->mService to write a small number of messages
1109  * to the FMQ. Read and verify data from two threads configured
1110  * as readers to the FMQ.
1111  */
TYPED_TEST(UnsynchronizedWriteClient,SmallInputMultipleReaderTest)1112 TYPED_TEST(UnsynchronizedWriteClient, SmallInputMultipleReaderTest) {
1113     typename TypeParam::MQType* mQueue2 = this->newQueue();
1114 
1115     ASSERT_NE(nullptr, mQueue2);
1116 
1117     const size_t dataLen = 16;
1118     ASSERT_LE(dataLen, this->mNumMessagesMax);
1119 
1120     bool ret = this->requestWriteFmqUnsync(dataLen, this->mService);
1121     ASSERT_TRUE(ret);
1122 
1123     pid_t pid;
1124     if ((pid = fork()) == 0) {
1125         /* child process */
1126         int32_t readData[dataLen] = {};
1127         ASSERT_TRUE(mQueue2->read(readData, dataLen));
1128         ASSERT_TRUE(verifyData(readData, dataLen));
1129         exit(0);
1130     } else {
1131         ASSERT_GT(pid,
1132                   0 /* parent should see PID greater than 0 for a good fork */);
1133         int32_t readData[dataLen] = {};
1134         ASSERT_TRUE(this->mQueue->read(readData, dataLen));
1135         ASSERT_TRUE(verifyData(readData, dataLen));
1136     }
1137 }
1138 
1139 /*
1140  * Request this->mService to write into the FMQ until it is full.
1141  * Request this->mService to do another write and verify it is successful.
1142  * Use two reader processes to read and verify that both fail.
1143  */
TYPED_TEST(UnsynchronizedWriteClient,OverflowNotificationTest)1144 TYPED_TEST(UnsynchronizedWriteClient, OverflowNotificationTest) {
1145     typename TypeParam::MQType* mQueue2 = this->newQueue();
1146     ASSERT_NE(nullptr, mQueue2);
1147 
1148     bool ret = this->requestWriteFmqUnsync(this->mNumMessagesMax, this->mService);
1149     ASSERT_TRUE(ret);
1150     ret = this->requestWriteFmqUnsync(1, this->mService);
1151     ASSERT_TRUE(ret);
1152 
1153     pid_t pid;
1154     if ((pid = fork()) == 0) {
1155         /* child process */
1156         std::vector<int32_t> readData(this->mNumMessagesMax);
1157         ASSERT_FALSE(mQueue2->read(&readData[0], this->mNumMessagesMax));
1158         exit(0);
1159     } else {
1160         ASSERT_GT(pid, 0/* parent should see PID greater than 0 for a good fork */);
1161         std::vector<int32_t> readData(this->mNumMessagesMax);
1162         ASSERT_FALSE(this->mQueue->read(&readData[0], this->mNumMessagesMax));
1163     }
1164 }
1165 
1166 /*
1167  * Make sure a valid queue can be created with different supported types.
1168  * All fundamental or native types should work. An AIDL parcelable that is
1169  * annotated with @FixedSize is supported. A parcelable without it, will cause
1170  * a compilation error.
1171  */
1172 typedef ::testing::Types<FixedParcelable, EventFlagBits, bool, int8_t, char, char16_t, int32_t,
1173                          int64_t, float, double>
1174         AidlTypeCheckTypes;
1175 
1176 template <typename T>
1177 class AidlTypeChecks : public ::testing::Test {};
1178 
1179 TYPED_TEST_CASE(AidlTypeChecks, AidlTypeCheckTypes);
1180 
TYPED_TEST(AidlTypeChecks,FixedSizeParcelableTest)1181 TYPED_TEST(AidlTypeChecks, FixedSizeParcelableTest) {
1182     android::AidlMessageQueue<TypeParam, UnsynchronizedWrite> queue =
1183             android::AidlMessageQueue<TypeParam, UnsynchronizedWrite>(64);
1184     ASSERT_TRUE(queue.isValid());
1185     // Make sure we can do a simple write/read of any value.
1186     TypeParam writeData[1];
1187     TypeParam readData[1];
1188     EXPECT_TRUE(queue.write(writeData, 1));
1189     EXPECT_TRUE(queue.read(readData, 1));
1190 }
1191