1/* 2 * Copyright 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#define LOG_TAG "RingBufferParcelable" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include <stdint.h> 22 23#include <binder/Parcelable.h> 24#include <utility/AAudioUtilities.h> 25 26#include "binding/AAudioServiceDefinitions.h" 27#include "binding/SharedRegionParcelable.h" 28#include "binding/RingBufferParcelable.h" 29 30using namespace aaudio; 31 32RingBufferParcelable::RingBufferParcelable() {} 33RingBufferParcelable::~RingBufferParcelable() {} 34 35// TODO This assumes that all three use the same SharedMemoryParcelable 36void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex, 37 int32_t dataMemoryOffset, 38 int32_t dataSizeInBytes, 39 int32_t readCounterOffset, 40 int32_t writeCounterOffset, 41 int32_t counterSizeBytes) { 42 mReadCounterParcelable.setup(sharedMemoryIndex, readCounterOffset, counterSizeBytes); 43 mWriteCounterParcelable.setup(sharedMemoryIndex, writeCounterOffset, counterSizeBytes); 44 mDataParcelable.setup(sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes); 45} 46 47void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex, 48 int32_t dataMemoryOffset, 49 int32_t dataSizeInBytes) { 50 mReadCounterParcelable.setup(sharedMemoryIndex, 0, 0); 51 mWriteCounterParcelable.setup(sharedMemoryIndex, 0, 0); 52 mDataParcelable.setup(sharedMemoryIndex, dataMemoryOffset, dataSizeInBytes); 53} 54 55int32_t RingBufferParcelable::getBytesPerFrame() { 56 return mBytesPerFrame; 57} 58 59void RingBufferParcelable::setBytesPerFrame(int32_t bytesPerFrame) { 60 mBytesPerFrame = bytesPerFrame; 61} 62 63int32_t RingBufferParcelable::getFramesPerBurst() { 64 return mFramesPerBurst; 65} 66 67void RingBufferParcelable::setFramesPerBurst(int32_t framesPerBurst) { 68 mFramesPerBurst = framesPerBurst; 69} 70 71int32_t RingBufferParcelable::getCapacityInFrames() { 72 return mCapacityInFrames; 73} 74 75void RingBufferParcelable::setCapacityInFrames(int32_t capacityInFrames) { 76 mCapacityInFrames = capacityInFrames; 77} 78 79/** 80 * The read and write must be symmetric. 81 */ 82status_t RingBufferParcelable::writeToParcel(Parcel* parcel) const { 83 status_t status = AAudioConvert_aaudioToAndroidStatus(validate()); 84 if (status != NO_ERROR) goto error; 85 86 status = parcel->writeInt32(mCapacityInFrames); 87 if (status != NO_ERROR) goto error; 88 if (mCapacityInFrames > 0) { 89 status = parcel->writeInt32(mBytesPerFrame); 90 if (status != NO_ERROR) goto error; 91 status = parcel->writeInt32(mFramesPerBurst); 92 if (status != NO_ERROR) goto error; 93 status = parcel->writeInt32(mFlags); 94 if (status != NO_ERROR) goto error; 95 status = mReadCounterParcelable.writeToParcel(parcel); 96 if (status != NO_ERROR) goto error; 97 status = mWriteCounterParcelable.writeToParcel(parcel); 98 if (status != NO_ERROR) goto error; 99 status = mDataParcelable.writeToParcel(parcel); 100 if (status != NO_ERROR) goto error; 101 } 102 return NO_ERROR; 103error: 104 ALOGE("%s returning %d", __func__, status); 105 return status; 106} 107 108status_t RingBufferParcelable::readFromParcel(const Parcel* parcel) { 109 status_t status = parcel->readInt32(&mCapacityInFrames); 110 if (status != NO_ERROR) goto error; 111 if (mCapacityInFrames > 0) { 112 status = parcel->readInt32(&mBytesPerFrame); 113 if (status != NO_ERROR) goto error; 114 status = parcel->readInt32(&mFramesPerBurst); 115 if (status != NO_ERROR) goto error; 116 status = parcel->readInt32((int32_t *)&mFlags); 117 if (status != NO_ERROR) goto error; 118 status = mReadCounterParcelable.readFromParcel(parcel); 119 if (status != NO_ERROR) goto error; 120 status = mWriteCounterParcelable.readFromParcel(parcel); 121 if (status != NO_ERROR) goto error; 122 status = mDataParcelable.readFromParcel(parcel); 123 if (status != NO_ERROR) goto error; 124 } 125 return AAudioConvert_aaudioToAndroidStatus(validate()); 126error: 127 ALOGE("%s returning %d", __func__, status); 128 return status; 129} 130 131aaudio_result_t RingBufferParcelable::resolve(SharedMemoryParcelable *memoryParcels, RingBufferDescriptor *descriptor) { 132 aaudio_result_t result; 133 134 result = mReadCounterParcelable.resolve(memoryParcels, 135 (void **) &descriptor->readCounterAddress); 136 if (result != AAUDIO_OK) { 137 return result; 138 } 139 140 result = mWriteCounterParcelable.resolve(memoryParcels, 141 (void **) &descriptor->writeCounterAddress); 142 if (result != AAUDIO_OK) { 143 return result; 144 } 145 146 result = mDataParcelable.resolve(memoryParcels, (void **) &descriptor->dataAddress); 147 if (result != AAUDIO_OK) { 148 return result; 149 } 150 151 descriptor->bytesPerFrame = mBytesPerFrame; 152 descriptor->framesPerBurst = mFramesPerBurst; 153 descriptor->capacityInFrames = mCapacityInFrames; 154 descriptor->flags = mFlags; 155 return AAUDIO_OK; 156} 157 158aaudio_result_t RingBufferParcelable::validate() const { 159 if (mCapacityInFrames < 0 || mCapacityInFrames >= 32 * 1024) { 160 ALOGE("invalid mCapacityInFrames = %d", mCapacityInFrames); 161 return AAUDIO_ERROR_INTERNAL; 162 } 163 if (mBytesPerFrame < 0 || mBytesPerFrame >= 256) { 164 ALOGE("invalid mBytesPerFrame = %d", mBytesPerFrame); 165 return AAUDIO_ERROR_INTERNAL; 166 } 167 if (mFramesPerBurst < 0 || mFramesPerBurst >= 16 * 1024) { 168 ALOGE("invalid mFramesPerBurst = %d", mFramesPerBurst); 169 return AAUDIO_ERROR_INTERNAL; 170 } 171 return AAUDIO_OK; 172} 173 174 175void RingBufferParcelable::dump() { 176 ALOGD("mCapacityInFrames = %d ---------", mCapacityInFrames); 177 if (mCapacityInFrames > 0) { 178 ALOGD("mBytesPerFrame = %d", mBytesPerFrame); 179 ALOGD("mFramesPerBurst = %d", mFramesPerBurst); 180 ALOGD("mFlags = %u", mFlags); 181 mReadCounterParcelable.dump(); 182 mWriteCounterParcelable.dump(); 183 mDataParcelable.dump(); 184 } 185} 186