/* * Copyright 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "RingBufferParcelable" //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <stdint.h> #include <binder/Parcelable.h> #include <utility/AAudioUtilities.h> #include "binding/AAudioServiceDefinitions.h" #include "binding/SharedRegionParcelable.h" #include "binding/RingBufferParcelable.h" using namespace aaudio; RingBufferParcelable::RingBufferParcelable(const RingBuffer& parcelable) : mReadCounterParcelable(parcelable.readCounterParcelable), mWriteCounterParcelable(parcelable.writeCounterParcelable), mDataParcelable(parcelable.dataParcelable), mBytesPerFrame(parcelable.bytesPerFrame), mFramesPerBurst(parcelable.framesPerBurst), mCapacityInFrames(parcelable.capacityInFrames), mFlags(static_cast<RingbufferFlags>(parcelable.flags)) { static_assert(sizeof(mFlags) == sizeof(parcelable.flags)); } RingBuffer RingBufferParcelable::parcelable() const { RingBuffer result; result.readCounterParcelable = mReadCounterParcelable.parcelable(); result.writeCounterParcelable = mWriteCounterParcelable.parcelable(); result.dataParcelable = mDataParcelable.parcelable(); result.bytesPerFrame = mBytesPerFrame; result.framesPerBurst = mFramesPerBurst; result.capacityInFrames = mCapacityInFrames; static_assert(sizeof(mFlags) == sizeof(result.flags)); result.flags = static_cast<int32_t>(mFlags); return result; } // TODO This assumes that all three use the same SharedMemoryParcelable void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex, int32_t dataMemoryOffset, int32_t dataSizeInBytes, int32_t readCounterOffset, int32_t writeCounterOffset, int32_t counterSizeBytes) { mReadCounterParcelable.setup({sharedMemoryIndex, readCounterOffset, counterSizeBytes}); mWriteCounterParcelable.setup({sharedMemoryIndex, writeCounterOffset, counterSizeBytes}); mDataParcelable.setup({sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes}); } void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex, int32_t dataMemoryOffset, int32_t dataSizeInBytes) { mReadCounterParcelable.setup({sharedMemoryIndex, 0, 0}); mWriteCounterParcelable.setup({sharedMemoryIndex, 0, 0}); mDataParcelable.setup({sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes}); } void RingBufferParcelable::setupMemory( const SharedRegionParcelable::MemoryInfoTuple& dataMemoryInfo, const SharedRegionParcelable::MemoryInfoTuple& readCounterInfo, const SharedRegionParcelable::MemoryInfoTuple& writeCounterInfo) { mReadCounterParcelable.setup(readCounterInfo); mWriteCounterParcelable.setup(writeCounterInfo); mDataParcelable.setup(dataMemoryInfo); } int32_t RingBufferParcelable::getBytesPerFrame() const { return mBytesPerFrame; } void RingBufferParcelable::setBytesPerFrame(int32_t bytesPerFrame) { mBytesPerFrame = bytesPerFrame; } int32_t RingBufferParcelable::getFramesPerBurst() const { return mFramesPerBurst; } void RingBufferParcelable::setFramesPerBurst(int32_t framesPerBurst) { mFramesPerBurst = framesPerBurst; } int32_t RingBufferParcelable::getCapacityInFrames() const { return mCapacityInFrames; } void RingBufferParcelable::setCapacityInFrames(int32_t capacityInFrames) { mCapacityInFrames = capacityInFrames; } aaudio_result_t RingBufferParcelable::resolve(SharedMemoryParcelable *memoryParcels, RingBufferDescriptor *descriptor) { aaudio_result_t result; result = mReadCounterParcelable.resolve(memoryParcels, (void **) &descriptor->readCounterAddress); if (result != AAUDIO_OK) { return result; } result = mWriteCounterParcelable.resolve(memoryParcels, (void **) &descriptor->writeCounterAddress); if (result != AAUDIO_OK) { return result; } result = mDataParcelable.resolve(memoryParcels, (void **) &descriptor->dataAddress); if (result != AAUDIO_OK) { return result; } descriptor->bytesPerFrame = mBytesPerFrame; descriptor->framesPerBurst = mFramesPerBurst; descriptor->capacityInFrames = mCapacityInFrames; descriptor->flags = mFlags; return AAUDIO_OK; } void RingBufferParcelable::updateMemory(const RingBufferParcelable& parcelable, const std::map<int32_t, int32_t>& memoryIndexMap) { setupMemory(parcelable.mDataParcelable.getMemoryInfo(&memoryIndexMap), parcelable.mReadCounterParcelable.getMemoryInfo(&memoryIndexMap), parcelable.mWriteCounterParcelable.getMemoryInfo(&memoryIndexMap)); setBytesPerFrame(parcelable.getBytesPerFrame()); setFramesPerBurst(parcelable.getFramesPerBurst()); setCapacityInFrames(parcelable.getCapacityInFrames()); } aaudio_result_t RingBufferParcelable::validate() const { if (mCapacityInFrames < 0 || mCapacityInFrames >= 32 * 1024) { ALOGE("invalid mCapacityInFrames = %d", mCapacityInFrames); return AAUDIO_ERROR_INTERNAL; } if (mBytesPerFrame < 0 || mBytesPerFrame >= 256) { ALOGE("invalid mBytesPerFrame = %d", mBytesPerFrame); return AAUDIO_ERROR_INTERNAL; } if (mFramesPerBurst < 0 || mFramesPerBurst >= 16 * 1024) { ALOGE("invalid mFramesPerBurst = %d", mFramesPerBurst); return AAUDIO_ERROR_INTERNAL; } return AAUDIO_OK; } void RingBufferParcelable::dump() { ALOGD("mCapacityInFrames = %d ---------", mCapacityInFrames); if (mCapacityInFrames > 0) { ALOGD("mBytesPerFrame = %d", mBytesPerFrame); ALOGD("mFramesPerBurst = %d", mFramesPerBurst); ALOGD("mFlags = %u", mFlags); mReadCounterParcelable.dump(); mWriteCounterParcelable.dump(); mDataParcelable.dump(); } }