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