1 /* 2 * Copyright (C) 2017 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 "SharedMemoryProxy" 18 //#define LOG_NDEBUG 0 19 #include <log/log.h> 20 21 #include <errno.h> 22 #include <string.h> 23 24 #include <aaudio/AAudio.h> 25 #include "SharedMemoryProxy.h" 26 27 using namespace aaudio; 28 29 SharedMemoryProxy::~SharedMemoryProxy() 30 { 31 if (mOriginalSharedMemory != nullptr) { 32 munmap(mOriginalSharedMemory, mSharedMemorySizeInBytes); 33 mOriginalSharedMemory = nullptr; 34 } 35 if (mProxySharedMemory != nullptr) { 36 munmap(mProxySharedMemory, mSharedMemorySizeInBytes); 37 close(mProxyFileDescriptor); 38 mProxySharedMemory = nullptr; 39 } 40 } 41 42 aaudio_result_t SharedMemoryProxy::open(int originalFD, int32_t capacityInBytes) { 43 mOriginalFileDescriptor = originalFD; 44 mSharedMemorySizeInBytes = capacityInBytes; 45 46 mProxyFileDescriptor = ashmem_create_region("AAudioProxyDataBuffer", mSharedMemorySizeInBytes); 47 if (mProxyFileDescriptor < 0) { 48 ALOGE("open() ashmem_create_region() failed %d", errno); 49 return AAUDIO_ERROR_INTERNAL; 50 } 51 int err = ashmem_set_prot_region(mProxyFileDescriptor, PROT_READ|PROT_WRITE); 52 if (err < 0) { 53 ALOGE("open() ashmem_set_prot_region() failed %d", errno); 54 close(mProxyFileDescriptor); 55 mProxyFileDescriptor = -1; 56 return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 57 } 58 59 // Get original memory address. 60 mOriginalSharedMemory = (uint8_t *) mmap(0, mSharedMemorySizeInBytes, 61 PROT_READ|PROT_WRITE, 62 MAP_SHARED, 63 mOriginalFileDescriptor, 0); 64 if (mOriginalSharedMemory == MAP_FAILED) { 65 ALOGE("open() original mmap(%d) failed %d (%s)", 66 mOriginalFileDescriptor, errno, strerror(errno)); 67 return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 68 } 69 70 // Map the fd to the same memory addresses. 71 mProxySharedMemory = (uint8_t *) mmap(mOriginalSharedMemory, mSharedMemorySizeInBytes, 72 PROT_READ|PROT_WRITE, 73 MAP_SHARED, 74 mProxyFileDescriptor, 0); 75 if (mProxySharedMemory != mOriginalSharedMemory) { 76 ALOGE("open() proxy mmap(%d) failed %d", mProxyFileDescriptor, errno); 77 munmap(mOriginalSharedMemory, mSharedMemorySizeInBytes); 78 mOriginalSharedMemory = nullptr; 79 close(mProxyFileDescriptor); 80 mProxyFileDescriptor = -1; 81 return AAUDIO_ERROR_INTERNAL; // TODO convert errno to a better AAUDIO_ERROR; 82 } 83 84 return AAUDIO_OK; 85 } 86