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 // Unit tests for AAudio Marshalling of RingBuffer information.
18
19 #include <stdlib.h>
20 #include <math.h>
21
22 #include <android-base/unique_fd.h>
23 #include <binder/Parcel.h>
24 #include <binder/Parcelable.h>
25 #include <cutils/ashmem.h>
26 #include <gtest/gtest.h>
27 #include <sys/mman.h>
28
29 #include <aaudio/AAudio.h>
30 #include <binding/AudioEndpointParcelable.h>
31
32 using android::base::unique_fd;
33 using namespace android;
34 using namespace aaudio;
35
36 // Test adding one value.
TEST(test_marshalling,aaudio_one_read_write)37 TEST(test_marshalling, aaudio_one_read_write) {
38 Parcel parcel;
39 size_t pos = parcel.dataPosition();
40 const int arbitraryValue = 235;
41 parcel.writeInt32(arbitraryValue);
42 parcel.setDataPosition(pos);
43 int32_t y;
44 parcel.readInt32(&y);
45 EXPECT_EQ(arbitraryValue, y);
46 }
47
48 // Test SharedMemoryParcel.
TEST(test_marshalling,aaudio_shared_memory)49 TEST(test_marshalling, aaudio_shared_memory) {
50 SharedMemoryParcelable sharedMemoryA;
51 SharedMemoryParcelable sharedMemoryB;
52 const size_t memSizeBytes = 840;
53 unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
54 ASSERT_LE(0, fd);
55 sharedMemoryA.setup(fd, memSizeBytes);
56 void *region1;
57 EXPECT_EQ(AAUDIO_OK, sharedMemoryA.resolve(0, 16, ®ion1)); // fits in region
58 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(-2, 16, ®ion1)); // offset is negative
59 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, ®ion1)); // size too big
60 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, ®ion1)); // goes past the end
61 int32_t *buffer1 = (int32_t *)region1;
62 buffer1[0] = 98735; // arbitrary value
63
64 Parcel parcel;
65 size_t pos = parcel.dataPosition();
66 sharedMemoryA.writeToParcel(&parcel);
67
68 parcel.setDataPosition(pos);
69 sharedMemoryB.readFromParcel(&parcel);
70 EXPECT_EQ(sharedMemoryA.getSizeInBytes(), sharedMemoryB.getSizeInBytes());
71
72 // should see same value at two different addresses
73 void *region2;
74 EXPECT_EQ(AAUDIO_OK, sharedMemoryB.resolve(0, 16, ®ion2));
75 int32_t *buffer2 = (int32_t *)region2;
76 EXPECT_NE(buffer1, buffer2);
77 EXPECT_EQ(buffer1[0], buffer2[0]);
78 }
79
80 // Test SharedRegionParcel.
TEST(test_marshalling,aaudio_shared_region)81 TEST(test_marshalling, aaudio_shared_region) {
82 SharedMemoryParcelable sharedMemories[2];
83 SharedRegionParcelable sharedRegionA;
84 SharedRegionParcelable sharedRegionB;
85 const size_t memSizeBytes = 840;
86 unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
87 ASSERT_LE(0, fd);
88 sharedMemories[0].setup(fd, memSizeBytes);
89 int32_t regionOffset1 = 32;
90 int32_t regionSize1 = 16;
91 sharedRegionA.setup(0, regionOffset1, regionSize1);
92
93 void *region1;
94 EXPECT_EQ(AAUDIO_OK, sharedRegionA.resolve(sharedMemories, ®ion1));
95 int32_t *buffer1 = (int32_t *)region1;
96 buffer1[0] = 336677; // arbitrary value
97
98 Parcel parcel;
99 size_t pos = parcel.dataPosition();
100 sharedRegionA.writeToParcel(&parcel);
101
102 parcel.setDataPosition(pos);
103 sharedRegionB.readFromParcel(&parcel);
104
105 // should see same value
106 void *region2;
107 EXPECT_EQ(AAUDIO_OK, sharedRegionB.resolve(sharedMemories, ®ion2));
108 int32_t *buffer2 = (int32_t *)region2;
109 EXPECT_EQ(buffer1[0], buffer2[0]);
110 }
111
112 // Test RingBufferParcelable.
TEST(test_marshalling,aaudio_ring_buffer_parcelable)113 TEST(test_marshalling, aaudio_ring_buffer_parcelable) {
114 SharedMemoryParcelable sharedMemories[2];
115 RingBufferParcelable ringBufferA;
116 RingBufferParcelable ringBufferB;
117
118 const size_t bytesPerFrame = 8;
119 const size_t framesPerBurst = 32;
120 const size_t dataSizeBytes = 2048;
121 const int32_t counterSizeBytes = sizeof(int64_t);
122 const size_t memSizeBytes = dataSizeBytes + (2 * counterSizeBytes);
123
124 unique_fd fd(ashmem_create_region("TestMarshalling Z", memSizeBytes));
125 ASSERT_LE(0, fd);
126 sharedMemories[0].setup(fd, memSizeBytes);
127
128 int32_t sharedMemoryIndex = 0;
129 // arrange indices and data in the shared memory
130 int32_t readOffset = 0;
131 int32_t writeOffset = readOffset + counterSizeBytes;
132 int32_t dataOffset = writeOffset + counterSizeBytes;
133 ringBufferA.setupMemory(sharedMemoryIndex, dataOffset, dataSizeBytes,
134 readOffset, writeOffset, counterSizeBytes);
135 ringBufferA.setFramesPerBurst(framesPerBurst);
136 ringBufferA.setBytesPerFrame(bytesPerFrame);
137 ringBufferA.setCapacityInFrames(dataSizeBytes / bytesPerFrame);
138
139 // setup A
140 RingBufferDescriptor descriptorA;
141 EXPECT_EQ(AAUDIO_OK, ringBufferA.resolve(sharedMemories, &descriptorA));
142 descriptorA.dataAddress[0] = 95;
143 descriptorA.dataAddress[1] = 57;
144 descriptorA.readCounterAddress[0] = 17;
145 descriptorA.writeCounterAddress[0] = 39;
146
147 // write A to parcel
148 Parcel parcel;
149 size_t pos = parcel.dataPosition();
150 ringBufferA.writeToParcel(&parcel);
151
152 // read B from parcel
153 parcel.setDataPosition(pos);
154 ringBufferB.readFromParcel(&parcel);
155
156 RingBufferDescriptor descriptorB;
157 EXPECT_EQ(AAUDIO_OK, ringBufferB.resolve(sharedMemories, &descriptorB));
158
159 // A and B should match
160 EXPECT_EQ(descriptorA.dataAddress[0], descriptorB.dataAddress[0]);
161 EXPECT_EQ(descriptorA.dataAddress[1], descriptorB.dataAddress[1]);
162 EXPECT_EQ(descriptorA.readCounterAddress[0], descriptorB.readCounterAddress[0]);
163 EXPECT_EQ(descriptorA.writeCounterAddress[0], descriptorB.writeCounterAddress[0]);
164
165 EXPECT_EQ(ringBufferA.getFramesPerBurst(), ringBufferB.getFramesPerBurst());
166 EXPECT_EQ(ringBufferA.getBytesPerFrame(), ringBufferB.getBytesPerFrame());
167 EXPECT_EQ(ringBufferA.getCapacityInFrames(), ringBufferB.getCapacityInFrames());
168 }
169