blob: 49213dc52eeac1b5880bcf74f97120822834b932 [file] [log] [blame]
Phil Burkd0ffd622016-12-21 11:50:41 -08001/*
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
Phil Burk5ed503c2017-02-01 09:38:15 -080017// Unit tests for AAudio Marshalling of RingBuffer information.
Phil Burkd0ffd622016-12-21 11:50:41 -080018
19#include <stdlib.h>
20#include <math.h>
21
Phil Burke72481c2017-08-08 13:20:45 -070022#include <android-base/unique_fd.h>
Phil Burkd0ffd622016-12-21 11:50:41 -080023#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
Phil Burka4eb0d82017-04-12 15:44:06 -070029#include <aaudio/AAudio.h>
Phil Burkd0ffd622016-12-21 11:50:41 -080030#include <binding/AudioEndpointParcelable.h>
31
Phil Burke72481c2017-08-08 13:20:45 -070032using android::base::unique_fd;
Phil Burkd0ffd622016-12-21 11:50:41 -080033using namespace android;
Phil Burk5ed503c2017-02-01 09:38:15 -080034using namespace aaudio;
Phil Burkd0ffd622016-12-21 11:50:41 -080035
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -070036template<typename T>
37T copy(const T& object) {
38 return T(object);
39}
40
41template<>
42SharedMemoryParcelable copy<SharedMemoryParcelable>(const SharedMemoryParcelable& object) {
43 return object.dup();
44}
45
46template<typename T>
47void writeToParcel(const T& object, Parcel* parcel) {
48 copy(object).parcelable().writeToParcel(parcel);
49}
50
51template<typename T>
52T readFromParcel(const Parcel& parcel) {
53 using ParcelType = std::decay_t<decltype(std::declval<T>().parcelable())>;
54 ParcelType parcelable;
55 parcelable.readFromParcel(&parcel);
56 return T(std::move(parcelable));
57}
58
Phil Burkd0ffd622016-12-21 11:50:41 -080059// Test adding one value.
Phil Burk5ed503c2017-02-01 09:38:15 -080060TEST(test_marshalling, aaudio_one_read_write) {
Phil Burkd0ffd622016-12-21 11:50:41 -080061 Parcel parcel;
62 size_t pos = parcel.dataPosition();
63 const int arbitraryValue = 235;
64 parcel.writeInt32(arbitraryValue);
65 parcel.setDataPosition(pos);
66 int32_t y;
67 parcel.readInt32(&y);
68 EXPECT_EQ(arbitraryValue, y);
69}
70
71// Test SharedMemoryParcel.
Phil Burk5ed503c2017-02-01 09:38:15 -080072TEST(test_marshalling, aaudio_shared_memory) {
Phil Burkd0ffd622016-12-21 11:50:41 -080073 SharedMemoryParcelable sharedMemoryA;
Phil Burkd0ffd622016-12-21 11:50:41 -080074 const size_t memSizeBytes = 840;
Phil Burke72481c2017-08-08 13:20:45 -070075 unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
Phil Burkd0ffd622016-12-21 11:50:41 -080076 ASSERT_LE(0, fd);
77 sharedMemoryA.setup(fd, memSizeBytes);
78 void *region1;
Phil Burk5ed503c2017-02-01 09:38:15 -080079 EXPECT_EQ(AAUDIO_OK, sharedMemoryA.resolve(0, 16, &region1)); // fits in region
80 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(-2, 16, &region1)); // offset is negative
81 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, &region1)); // size too big
82 EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, &region1)); // goes past the end
Phil Burkd0ffd622016-12-21 11:50:41 -080083 int32_t *buffer1 = (int32_t *)region1;
84 buffer1[0] = 98735; // arbitrary value
85
86 Parcel parcel;
87 size_t pos = parcel.dataPosition();
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -070088 writeToParcel(sharedMemoryA, &parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -080089
90 parcel.setDataPosition(pos);
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -070091 SharedMemoryParcelable sharedMemoryB = readFromParcel<SharedMemoryParcelable>(parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -080092 EXPECT_EQ(sharedMemoryA.getSizeInBytes(), sharedMemoryB.getSizeInBytes());
93
94 // should see same value at two different addresses
95 void *region2;
Phil Burk5ed503c2017-02-01 09:38:15 -080096 EXPECT_EQ(AAUDIO_OK, sharedMemoryB.resolve(0, 16, &region2));
Phil Burkd0ffd622016-12-21 11:50:41 -080097 int32_t *buffer2 = (int32_t *)region2;
98 EXPECT_NE(buffer1, buffer2);
99 EXPECT_EQ(buffer1[0], buffer2[0]);
100}
101
102// Test SharedRegionParcel.
Phil Burk5ed503c2017-02-01 09:38:15 -0800103TEST(test_marshalling, aaudio_shared_region) {
Phil Burkd0ffd622016-12-21 11:50:41 -0800104 SharedMemoryParcelable sharedMemories[2];
105 SharedRegionParcelable sharedRegionA;
Phil Burkd0ffd622016-12-21 11:50:41 -0800106 const size_t memSizeBytes = 840;
Phil Burke72481c2017-08-08 13:20:45 -0700107 unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
Phil Burkd0ffd622016-12-21 11:50:41 -0800108 ASSERT_LE(0, fd);
109 sharedMemories[0].setup(fd, memSizeBytes);
110 int32_t regionOffset1 = 32;
111 int32_t regionSize1 = 16;
112 sharedRegionA.setup(0, regionOffset1, regionSize1);
113
114 void *region1;
Phil Burk5ed503c2017-02-01 09:38:15 -0800115 EXPECT_EQ(AAUDIO_OK, sharedRegionA.resolve(sharedMemories, &region1));
Phil Burkd0ffd622016-12-21 11:50:41 -0800116 int32_t *buffer1 = (int32_t *)region1;
117 buffer1[0] = 336677; // arbitrary value
118
119 Parcel parcel;
120 size_t pos = parcel.dataPosition();
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -0700121 writeToParcel(sharedRegionA, &parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -0800122
123 parcel.setDataPosition(pos);
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -0700124 SharedRegionParcelable sharedRegionB = readFromParcel<SharedRegionParcelable>(parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -0800125
126 // should see same value
127 void *region2;
Phil Burk5ed503c2017-02-01 09:38:15 -0800128 EXPECT_EQ(AAUDIO_OK, sharedRegionB.resolve(sharedMemories, &region2));
Phil Burkd0ffd622016-12-21 11:50:41 -0800129 int32_t *buffer2 = (int32_t *)region2;
130 EXPECT_EQ(buffer1[0], buffer2[0]);
131}
132
133// Test RingBufferParcelable.
Phil Burk5ed503c2017-02-01 09:38:15 -0800134TEST(test_marshalling, aaudio_ring_buffer_parcelable) {
Phil Burkd0ffd622016-12-21 11:50:41 -0800135 SharedMemoryParcelable sharedMemories[2];
136 RingBufferParcelable ringBufferA;
Phil Burkd0ffd622016-12-21 11:50:41 -0800137
138 const size_t bytesPerFrame = 8;
139 const size_t framesPerBurst = 32;
140 const size_t dataSizeBytes = 2048;
141 const int32_t counterSizeBytes = sizeof(int64_t);
142 const size_t memSizeBytes = dataSizeBytes + (2 * counterSizeBytes);
143
Phil Burke72481c2017-08-08 13:20:45 -0700144 unique_fd fd(ashmem_create_region("TestMarshalling Z", memSizeBytes));
Phil Burkd0ffd622016-12-21 11:50:41 -0800145 ASSERT_LE(0, fd);
146 sharedMemories[0].setup(fd, memSizeBytes);
147
148 int32_t sharedMemoryIndex = 0;
149 // arrange indices and data in the shared memory
150 int32_t readOffset = 0;
151 int32_t writeOffset = readOffset + counterSizeBytes;
152 int32_t dataOffset = writeOffset + counterSizeBytes;
153 ringBufferA.setupMemory(sharedMemoryIndex, dataOffset, dataSizeBytes,
154 readOffset, writeOffset, counterSizeBytes);
155 ringBufferA.setFramesPerBurst(framesPerBurst);
156 ringBufferA.setBytesPerFrame(bytesPerFrame);
157 ringBufferA.setCapacityInFrames(dataSizeBytes / bytesPerFrame);
158
159 // setup A
160 RingBufferDescriptor descriptorA;
Phil Burk5ed503c2017-02-01 09:38:15 -0800161 EXPECT_EQ(AAUDIO_OK, ringBufferA.resolve(sharedMemories, &descriptorA));
Phil Burkd0ffd622016-12-21 11:50:41 -0800162 descriptorA.dataAddress[0] = 95;
163 descriptorA.dataAddress[1] = 57;
164 descriptorA.readCounterAddress[0] = 17;
165 descriptorA.writeCounterAddress[0] = 39;
166
167 // write A to parcel
168 Parcel parcel;
169 size_t pos = parcel.dataPosition();
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -0700170 writeToParcel(ringBufferA, &parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -0800171
172 // read B from parcel
173 parcel.setDataPosition(pos);
Ytai Ben-Tsvic5f45872020-08-18 10:39:44 -0700174 RingBufferParcelable ringBufferB = readFromParcel<RingBufferParcelable>(parcel);
Phil Burkd0ffd622016-12-21 11:50:41 -0800175
176 RingBufferDescriptor descriptorB;
Phil Burk5ed503c2017-02-01 09:38:15 -0800177 EXPECT_EQ(AAUDIO_OK, ringBufferB.resolve(sharedMemories, &descriptorB));
Phil Burkd0ffd622016-12-21 11:50:41 -0800178
179 // A and B should match
180 EXPECT_EQ(descriptorA.dataAddress[0], descriptorB.dataAddress[0]);
181 EXPECT_EQ(descriptorA.dataAddress[1], descriptorB.dataAddress[1]);
182 EXPECT_EQ(descriptorA.readCounterAddress[0], descriptorB.readCounterAddress[0]);
183 EXPECT_EQ(descriptorA.writeCounterAddress[0], descriptorB.writeCounterAddress[0]);
184
185 EXPECT_EQ(ringBufferA.getFramesPerBurst(), ringBufferB.getFramesPerBurst());
186 EXPECT_EQ(ringBufferA.getBytesPerFrame(), ringBufferB.getBytesPerFrame());
187 EXPECT_EQ(ringBufferA.getCapacityInFrames(), ringBufferB.getCapacityInFrames());
188}