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 30 using namespace aaudio; 31 32 RingBufferParcelable::RingBufferParcelable() {} 33 RingBufferParcelable::~RingBufferParcelable() {} 34 35 // TODO This assumes that all three use the same SharedMemoryParcelable 36 void 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 47 void 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 55 int32_t RingBufferParcelable::getBytesPerFrame() { 56 return mBytesPerFrame; 57 } 58 59 void RingBufferParcelable::setBytesPerFrame(int32_t bytesPerFrame) { 60 mBytesPerFrame = bytesPerFrame; 61 } 62 63 int32_t RingBufferParcelable::getFramesPerBurst() { 64 return mFramesPerBurst; 65 } 66 67 void RingBufferParcelable::setFramesPerBurst(int32_t framesPerBurst) { 68 mFramesPerBurst = framesPerBurst; 69 } 70 71 int32_t RingBufferParcelable::getCapacityInFrames() { 72 return mCapacityInFrames; 73 } 74 75 void RingBufferParcelable::setCapacityInFrames(int32_t capacityInFrames) { 76 mCapacityInFrames = capacityInFrames; 77 } 78 79 /** 80 * The read and write must be symmetric. 81 */ 82 status_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; 103 error: 104 ALOGE("%s returning %d", __func__, status); 105 return status; 106 } 107 108 status_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()); 126 error: 127 ALOGE("%s returning %d", __func__, status); 128 return status; 129 } 130 131 aaudio_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 158 aaudio_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 175 void 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