/* * 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 "AudioEndpointParcelable" //#define LOG_NDEBUG 0 #include #include #include #include #include #include "binding/AAudioServiceDefinitions.h" #include "binding/RingBufferParcelable.h" #include "binding/AudioEndpointParcelable.h" using android::base::unique_fd; using android::NO_ERROR; using android::status_t; using android::Parcel; using android::Parcelable; using namespace aaudio; /** * Container for information about the message queues plus * general stream information needed by AAudio clients. * It contains no addresses, just sizes, offsets and file descriptors for * shared memory that can be passed through Binder. */ AudioEndpointParcelable::AudioEndpointParcelable() {} AudioEndpointParcelable::~AudioEndpointParcelable() {} /** * Add the file descriptor to the table. * @return index in table or negative error */ int32_t AudioEndpointParcelable::addFileDescriptor(const unique_fd& fd, int32_t sizeInBytes) { if (mNumSharedMemories >= MAX_SHARED_MEMORIES) { return AAUDIO_ERROR_OUT_OF_RANGE; } int32_t index = mNumSharedMemories++; mSharedMemories[index].setup(fd, sizeInBytes); return index; } /** * The read and write must be symmetric. */ status_t AudioEndpointParcelable::writeToParcel(Parcel* parcel) const { status_t status = AAudioConvert_aaudioToAndroidStatus(validate()); if (status != NO_ERROR) goto error; status = parcel->writeInt32(mNumSharedMemories); if (status != NO_ERROR) goto error; for (int i = 0; i < mNumSharedMemories; i++) { status = mSharedMemories[i].writeToParcel(parcel); if (status != NO_ERROR) goto error; } status = mUpMessageQueueParcelable.writeToParcel(parcel); if (status != NO_ERROR) goto error; status = mDownMessageQueueParcelable.writeToParcel(parcel); if (status != NO_ERROR) goto error; status = mUpDataQueueParcelable.writeToParcel(parcel); if (status != NO_ERROR) goto error; status = mDownDataQueueParcelable.writeToParcel(parcel); if (status != NO_ERROR) goto error; return NO_ERROR; error: ALOGE("%s returning %d", __func__, status); return status; } status_t AudioEndpointParcelable::readFromParcel(const Parcel* parcel) { status_t status = parcel->readInt32(&mNumSharedMemories); if (status != NO_ERROR) goto error; for (int i = 0; i < mNumSharedMemories; i++) { mSharedMemories[i].readFromParcel(parcel); if (status != NO_ERROR) goto error; } status = mUpMessageQueueParcelable.readFromParcel(parcel); if (status != NO_ERROR) goto error; status = mDownMessageQueueParcelable.readFromParcel(parcel); if (status != NO_ERROR) goto error; status = mUpDataQueueParcelable.readFromParcel(parcel); if (status != NO_ERROR) goto error; status = mDownDataQueueParcelable.readFromParcel(parcel); if (status != NO_ERROR) goto error; return AAudioConvert_aaudioToAndroidStatus(validate()); error: ALOGE("%s returning %d", __func__, status); return status; } aaudio_result_t AudioEndpointParcelable::resolve(EndpointDescriptor *descriptor) { aaudio_result_t result = mUpMessageQueueParcelable.resolve(mSharedMemories, &descriptor->upMessageQueueDescriptor); if (result != AAUDIO_OK) return result; result = mDownMessageQueueParcelable.resolve(mSharedMemories, &descriptor->downMessageQueueDescriptor); if (result != AAUDIO_OK) return result; result = mDownDataQueueParcelable.resolve(mSharedMemories, &descriptor->dataQueueDescriptor); return result; } aaudio_result_t AudioEndpointParcelable::close() { int err = 0; for (int i = 0; i < mNumSharedMemories; i++) { int lastErr = mSharedMemories[i].close(); if (lastErr < 0) err = lastErr; } return AAudioConvert_androidToAAudioResult(err); } aaudio_result_t AudioEndpointParcelable::validate() const { if (mNumSharedMemories < 0 || mNumSharedMemories >= MAX_SHARED_MEMORIES) { ALOGE("invalid mNumSharedMemories = %d", mNumSharedMemories); return AAUDIO_ERROR_INTERNAL; } return AAUDIO_OK; } void AudioEndpointParcelable::dump() { ALOGD("======================================= BEGIN"); ALOGD("mNumSharedMemories = %d", mNumSharedMemories); for (int i = 0; i < mNumSharedMemories; i++) { mSharedMemories[i].dump(); } ALOGD("mUpMessageQueueParcelable ========="); mUpMessageQueueParcelable.dump(); ALOGD("mDownMessageQueueParcelable ======="); mDownMessageQueueParcelable.dump(); ALOGD("mUpDataQueueParcelable ============"); mUpDataQueueParcelable.dump(); ALOGD("mDownDataQueueParcelable =========="); mDownDataQueueParcelable.dump(); ALOGD("======================================= END"); }