1*be431cd8SAndroid Build Coastguard Worker /*
2*be431cd8SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*be431cd8SAndroid Build Coastguard Worker *
4*be431cd8SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*be431cd8SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*be431cd8SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*be431cd8SAndroid Build Coastguard Worker *
8*be431cd8SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*be431cd8SAndroid Build Coastguard Worker *
10*be431cd8SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*be431cd8SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*be431cd8SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*be431cd8SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*be431cd8SAndroid Build Coastguard Worker * limitations under the License.
15*be431cd8SAndroid Build Coastguard Worker */
16*be431cd8SAndroid Build Coastguard Worker
17*be431cd8SAndroid Build Coastguard Worker #include "TestAidlMsgQ.h"
18*be431cd8SAndroid Build Coastguard Worker
19*be431cd8SAndroid Build Coastguard Worker namespace aidl {
20*be431cd8SAndroid Build Coastguard Worker namespace android {
21*be431cd8SAndroid Build Coastguard Worker namespace fmq {
22*be431cd8SAndroid Build Coastguard Worker namespace test {
23*be431cd8SAndroid Build Coastguard Worker
24*be431cd8SAndroid Build Coastguard Worker // Methods from ::aidl::android::fmq::test::ITestAidlMsgQ follow.
configureFmqSyncReadWrite(const MQDescriptor<int32_t,SynchronizedReadWrite> & mqDesc,bool * _aidl_return)25*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::configureFmqSyncReadWrite(
26*be431cd8SAndroid Build Coastguard Worker const MQDescriptor<int32_t, SynchronizedReadWrite>& mqDesc, bool* _aidl_return) {
27*be431cd8SAndroid Build Coastguard Worker mFmqSynchronized.reset(new (std::nothrow) TestAidlMsgQ::MessageQueueSync(mqDesc));
28*be431cd8SAndroid Build Coastguard Worker if ((mFmqSynchronized == nullptr) || (mFmqSynchronized->isValid() == false)) {
29*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
30*be431cd8SAndroid Build Coastguard Worker }
31*be431cd8SAndroid Build Coastguard Worker /*
32*be431cd8SAndroid Build Coastguard Worker * Initialize the EventFlag word with bit FMQ_NOT_FULL.
33*be431cd8SAndroid Build Coastguard Worker */
34*be431cd8SAndroid Build Coastguard Worker auto evFlagWordPtr = mFmqSynchronized->getEventFlagWord();
35*be431cd8SAndroid Build Coastguard Worker if (evFlagWordPtr != nullptr) {
36*be431cd8SAndroid Build Coastguard Worker std::atomic_init(evFlagWordPtr, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL));
37*be431cd8SAndroid Build Coastguard Worker }
38*be431cd8SAndroid Build Coastguard Worker *_aidl_return = true;
39*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
40*be431cd8SAndroid Build Coastguard Worker }
41*be431cd8SAndroid Build Coastguard Worker
getFmqUnsyncWrite(bool configureFmq,bool userFd,MQDescriptor<int32_t,UnsynchronizedWrite> * mqDesc,bool * _aidl_return)42*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::getFmqUnsyncWrite(
43*be431cd8SAndroid Build Coastguard Worker bool configureFmq, bool userFd, MQDescriptor<int32_t, UnsynchronizedWrite>* mqDesc,
44*be431cd8SAndroid Build Coastguard Worker bool* _aidl_return) {
45*be431cd8SAndroid Build Coastguard Worker if (configureFmq) {
46*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kNumElementsInQueue = 1024;
47*be431cd8SAndroid Build Coastguard Worker static constexpr size_t kElementSizeBytes = sizeof(int32_t);
48*be431cd8SAndroid Build Coastguard Worker ::android::base::unique_fd ringbufferFd;
49*be431cd8SAndroid Build Coastguard Worker if (userFd) {
50*be431cd8SAndroid Build Coastguard Worker ringbufferFd.reset(
51*be431cd8SAndroid Build Coastguard Worker ::ashmem_create_region("UnsyncWrite", kNumElementsInQueue * kElementSizeBytes));
52*be431cd8SAndroid Build Coastguard Worker }
53*be431cd8SAndroid Build Coastguard Worker mFmqUnsynchronized.reset(new (std::nothrow) TestAidlMsgQ::MessageQueueUnsync(
54*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue, false, std::move(ringbufferFd),
55*be431cd8SAndroid Build Coastguard Worker kNumElementsInQueue * kElementSizeBytes));
56*be431cd8SAndroid Build Coastguard Worker }
57*be431cd8SAndroid Build Coastguard Worker
58*be431cd8SAndroid Build Coastguard Worker if ((mFmqUnsynchronized == nullptr) || (mFmqUnsynchronized->isValid() == false) ||
59*be431cd8SAndroid Build Coastguard Worker (mqDesc == nullptr)) {
60*be431cd8SAndroid Build Coastguard Worker *_aidl_return = false;
61*be431cd8SAndroid Build Coastguard Worker } else {
62*be431cd8SAndroid Build Coastguard Worker *mqDesc = mFmqUnsynchronized->dupeDesc();
63*be431cd8SAndroid Build Coastguard Worker // set write-protection so readers can't mmap and write
64*be431cd8SAndroid Build Coastguard Worker int res = ashmem_set_prot_region(mqDesc->handle.fds[0].get(), PROT_READ);
65*be431cd8SAndroid Build Coastguard Worker if (res == -1) {
66*be431cd8SAndroid Build Coastguard Worker ALOGE("Failed to set write protection: %s", strerror(errno));
67*be431cd8SAndroid Build Coastguard Worker *_aidl_return = false;
68*be431cd8SAndroid Build Coastguard Worker } else {
69*be431cd8SAndroid Build Coastguard Worker *_aidl_return = true;
70*be431cd8SAndroid Build Coastguard Worker }
71*be431cd8SAndroid Build Coastguard Worker }
72*be431cd8SAndroid Build Coastguard Worker
73*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
74*be431cd8SAndroid Build Coastguard Worker }
75*be431cd8SAndroid Build Coastguard Worker
requestBlockingRead(int32_t count)76*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestBlockingRead(int32_t count) {
77*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
78*be431cd8SAndroid Build Coastguard Worker bool result = mFmqSynchronized->readBlocking(
79*be431cd8SAndroid Build Coastguard Worker &data[0], count, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL),
80*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(EventFlagBits::FMQ_NOT_EMPTY), 5000000000 /* timeOutNanos */);
81*be431cd8SAndroid Build Coastguard Worker
82*be431cd8SAndroid Build Coastguard Worker if (result == false) {
83*be431cd8SAndroid Build Coastguard Worker ALOGE("Blocking read fails");
84*be431cd8SAndroid Build Coastguard Worker }
85*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
86*be431cd8SAndroid Build Coastguard Worker }
87*be431cd8SAndroid Build Coastguard Worker
requestBlockingReadDefaultEventFlagBits(int32_t count)88*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestBlockingReadDefaultEventFlagBits(int32_t count) {
89*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
90*be431cd8SAndroid Build Coastguard Worker bool result = mFmqSynchronized->readBlocking(&data[0], count);
91*be431cd8SAndroid Build Coastguard Worker
92*be431cd8SAndroid Build Coastguard Worker if (result == false) {
93*be431cd8SAndroid Build Coastguard Worker ALOGE("Blocking read fails");
94*be431cd8SAndroid Build Coastguard Worker }
95*be431cd8SAndroid Build Coastguard Worker
96*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
97*be431cd8SAndroid Build Coastguard Worker }
98*be431cd8SAndroid Build Coastguard Worker
requestBlockingReadRepeat(int32_t count,int32_t numIter)99*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestBlockingReadRepeat(int32_t count, int32_t numIter) {
100*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
101*be431cd8SAndroid Build Coastguard Worker for (int i = 0; i < numIter; i++) {
102*be431cd8SAndroid Build Coastguard Worker bool result = mFmqSynchronized->readBlocking(
103*be431cd8SAndroid Build Coastguard Worker &data[0], count, static_cast<uint32_t>(EventFlagBits::FMQ_NOT_FULL),
104*be431cd8SAndroid Build Coastguard Worker static_cast<uint32_t>(EventFlagBits::FMQ_NOT_EMPTY), 5000000000 /* timeOutNanos */);
105*be431cd8SAndroid Build Coastguard Worker
106*be431cd8SAndroid Build Coastguard Worker if (result == false) {
107*be431cd8SAndroid Build Coastguard Worker ALOGE("Blocking read fails");
108*be431cd8SAndroid Build Coastguard Worker break;
109*be431cd8SAndroid Build Coastguard Worker }
110*be431cd8SAndroid Build Coastguard Worker }
111*be431cd8SAndroid Build Coastguard Worker
112*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
113*be431cd8SAndroid Build Coastguard Worker }
114*be431cd8SAndroid Build Coastguard Worker
requestReadFmqSync(int32_t count,bool * _aidl_return)115*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestReadFmqSync(int32_t count, bool* _aidl_return) {
116*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
117*be431cd8SAndroid Build Coastguard Worker bool result = mFmqSynchronized->read(&data[0], count) && verifyData(&data[0], count);
118*be431cd8SAndroid Build Coastguard Worker *_aidl_return = result;
119*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
120*be431cd8SAndroid Build Coastguard Worker }
121*be431cd8SAndroid Build Coastguard Worker
requestReadFmqUnsync(int32_t count,bool * _aidl_return)122*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestReadFmqUnsync(int32_t count, bool* _aidl_return) {
123*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
124*be431cd8SAndroid Build Coastguard Worker bool result = mFmqUnsynchronized->read(&data[0], count) && verifyData(&data[0], count);
125*be431cd8SAndroid Build Coastguard Worker *_aidl_return = result;
126*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
127*be431cd8SAndroid Build Coastguard Worker }
128*be431cd8SAndroid Build Coastguard Worker
requestWriteFmqSync(int32_t count,bool * _aidl_return)129*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestWriteFmqSync(int32_t count, bool* _aidl_return) {
130*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
131*be431cd8SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
132*be431cd8SAndroid Build Coastguard Worker data[i] = i;
133*be431cd8SAndroid Build Coastguard Worker }
134*be431cd8SAndroid Build Coastguard Worker bool result = mFmqSynchronized->write(&data[0], count);
135*be431cd8SAndroid Build Coastguard Worker *_aidl_return = result;
136*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
137*be431cd8SAndroid Build Coastguard Worker }
138*be431cd8SAndroid Build Coastguard Worker
requestWriteFmqUnsync(int32_t count,bool * _aidl_return)139*be431cd8SAndroid Build Coastguard Worker ndk::ScopedAStatus TestAidlMsgQ::requestWriteFmqUnsync(int32_t count, bool* _aidl_return) {
140*be431cd8SAndroid Build Coastguard Worker std::vector<int32_t> data(count);
141*be431cd8SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
142*be431cd8SAndroid Build Coastguard Worker data[i] = i;
143*be431cd8SAndroid Build Coastguard Worker }
144*be431cd8SAndroid Build Coastguard Worker if (!mFmqUnsynchronized) {
145*be431cd8SAndroid Build Coastguard Worker ALOGE("Unsynchronized queue is not configured.");
146*be431cd8SAndroid Build Coastguard Worker *_aidl_return = false;
147*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
148*be431cd8SAndroid Build Coastguard Worker }
149*be431cd8SAndroid Build Coastguard Worker bool result = mFmqUnsynchronized->write(&data[0], count);
150*be431cd8SAndroid Build Coastguard Worker *_aidl_return = result;
151*be431cd8SAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
152*be431cd8SAndroid Build Coastguard Worker }
153*be431cd8SAndroid Build Coastguard Worker
154*be431cd8SAndroid Build Coastguard Worker } // namespace test
155*be431cd8SAndroid Build Coastguard Worker } // namespace fmq
156*be431cd8SAndroid Build Coastguard Worker } // namespace android
157*be431cd8SAndroid Build Coastguard Worker } // namespace aidl
158