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 32using android::base::unique_fd; 33using namespace android; 34using namespace aaudio; 35 36// Test adding one value. 37TEST(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. 49TEST(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. 81TEST(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. 113TEST(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