• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 #define LOG_TAG "SharedMemoryWrapper"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20 
21 #include <iomanip>
22 #include <iostream>
23 #include <sys/mman.h>
24 
25 #include "SharedMemoryWrapper.h"
26 
27 namespace aaudio {
28 
29 constexpr int COUNTER_SIZE_IN_BYTES = sizeof(android::fifo_counter_t);
30 constexpr int WRAPPER_SIZE_IN_BYTES = 2 * COUNTER_SIZE_IN_BYTES;
31 
SharedMemoryWrapper()32 SharedMemoryWrapper::SharedMemoryWrapper() {
33     mCounterFd.reset(ashmem_create_region("AAudioSharedMemoryWrapper", WRAPPER_SIZE_IN_BYTES));
34     if (mCounterFd.get() == -1) {
35         ALOGE("allocate() ashmem_create_region() failed %d", errno);
36         return;
37     }
38     int err = ashmem_set_prot_region(mCounterFd.get(), PROT_READ|PROT_WRITE);
39     if (err < 0) {
40         ALOGE("allocate() ashmem_set_prot_region() failed %d", errno);
41         mCounterFd.reset();
42         return;
43     }
44     auto tmpPtr = (uint8_t *) mmap(nullptr, WRAPPER_SIZE_IN_BYTES,
45                                    PROT_READ|PROT_WRITE,
46                                    MAP_SHARED,
47                                    mCounterFd.get(), 0);
48     if (tmpPtr == MAP_FAILED) {
49         ALOGE("allocate() mmap() failed %d", errno);
50         mCounterFd.reset();
51         return;
52     }
53     mCounterMemoryAddress = tmpPtr;
54 
55     mReadCounterAddress = (android::fifo_counter_t*) mCounterMemoryAddress;
56     mWriteCounterAddress = (android::fifo_counter_t*) &mCounterMemoryAddress[COUNTER_SIZE_IN_BYTES];
57 }
58 
~SharedMemoryWrapper()59 SharedMemoryWrapper::~SharedMemoryWrapper()
60 {
61     reset();
62     if (mCounterMemoryAddress != nullptr) {
63         munmap(mCounterMemoryAddress, COUNTER_SIZE_IN_BYTES);
64         mCounterMemoryAddress = nullptr;
65     }
66 }
67 
setupFifoBuffer(android::fifo_frames_t bytesPerFrame,android::fifo_frames_t capacityInFrames)68 aaudio_result_t SharedMemoryWrapper::setupFifoBuffer(android::fifo_frames_t bytesPerFrame,
69                                                      android::fifo_frames_t capacityInFrames) {
70     if (mDataFd.get() == -1) {
71         ALOGE("%s data file descriptor is not initialized", __func__);
72         return AAUDIO_ERROR_INTERNAL;
73     }
74     if (mCounterMemoryAddress == nullptr) {
75         ALOGE("%s the counter memory is not allocated correctly", __func__);
76         return AAUDIO_ERROR_INTERNAL;
77     }
78     mSharedMemorySizeInBytes = bytesPerFrame * capacityInFrames;
79     auto tmpPtr = (uint8_t *) mmap(nullptr, mSharedMemorySizeInBytes,
80                                    PROT_READ|PROT_WRITE,
81                                    MAP_SHARED,
82                                    mDataFd.get(), 0);
83     if (tmpPtr == MAP_FAILED) {
84         ALOGE("allocate() mmap() failed %d", errno);
85         return AAUDIO_ERROR_INTERNAL;
86     }
87     mSharedMemory = tmpPtr;
88 
89     mFifoBuffer = std::make_shared<android::FifoBufferIndirect>(
90             bytesPerFrame, capacityInFrames, mReadCounterAddress,
91             mWriteCounterAddress, mSharedMemory);
92     return AAUDIO_OK;
93 }
94 
reset()95 void SharedMemoryWrapper::reset() {
96     mFifoBuffer.reset();
97     if (mSharedMemory != nullptr) {
98         munmap(mSharedMemory, mSharedMemorySizeInBytes);
99         mSharedMemory = nullptr;
100     }
101     mDataFd.reset();
102 }
103 
fillParcelable(AudioEndpointParcelable * endpointParcelable,RingBufferParcelable & ringBufferParcelable,int32_t bytesPerFrame,int32_t framesPerBurst,int32_t capacityInFrames,CounterFilling counterFilling)104 void SharedMemoryWrapper::fillParcelable(
105         AudioEndpointParcelable* endpointParcelable, RingBufferParcelable &ringBufferParcelable,
106         int32_t bytesPerFrame, int32_t framesPerBurst, int32_t capacityInFrames,
107         CounterFilling counterFilling) {
108     const int capacityInBytes = bytesPerFrame * capacityInFrames;
109     const int dataFdIndex =
110                 endpointParcelable->addFileDescriptor(mDataFd, mSharedMemorySizeInBytes);
111     ringBufferParcelable.setBytesPerFrame(bytesPerFrame);
112     ringBufferParcelable.setFramesPerBurst(framesPerBurst);
113     ringBufferParcelable.setCapacityInFrames(capacityInFrames);
114     if (mCounterFd.get() == -1 || counterFilling == NONE) {
115         // Failed to create shared memory for read/write counter or requesting no filling counters.
116         ALOGD("%s no counter is filled, counterFd=%d", __func__, mCounterFd.get());
117         ringBufferParcelable.setupMemory(dataFdIndex, 0, capacityInBytes);
118     } else {
119         int counterFdIndex =
120                 endpointParcelable->addFileDescriptor(mCounterFd, WRAPPER_SIZE_IN_BYTES);
121         const int readCounterSize = (counterFilling & READ) == NONE ? 0 : COUNTER_SIZE_IN_BYTES;
122         const int writeCounterSize = (counterFilling & WRITE) == NONE ? 0 : COUNTER_SIZE_IN_BYTES;
123         ALOGD("%s counterFdIndex=%d readCounterSize=%d, writeCounterSize=%d",
124               __func__, counterFdIndex, readCounterSize, writeCounterSize);
125         ringBufferParcelable.setupMemory(
126                 {dataFdIndex, 0 /*offset*/, capacityInBytes},
127                 {counterFdIndex, 0 /*offset*/, readCounterSize},
128                 {counterFdIndex, COUNTER_SIZE_IN_BYTES, writeCounterSize});
129     }
130 }
131 
132 } // namespace aaudio
133