/* * 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::media::SharedFileRegion; using android::NO_ERROR; using android::status_t; using namespace aaudio; AudioEndpointParcelable::AudioEndpointParcelable(Endpoint&& parcelable) : mUpMessageQueueParcelable(std::move(parcelable.upMessageQueueParcelable)), mDownMessageQueueParcelable(std::move(parcelable.downMessageQueueParcelable)), mUpDataQueueParcelable(std::move(parcelable.upDataQueueParcelable)), mDownDataQueueParcelable(std::move(parcelable.downDataQueueParcelable)), mNumSharedMemories(parcelable.sharedMemories.size()) { for (size_t i = 0; i < parcelable.sharedMemories.size() && i < MAX_SHARED_MEMORIES; ++i) { // Re-construct. mSharedMemories[i].~SharedMemoryParcelable(); new(&mSharedMemories[i]) SharedMemoryParcelable(std::move(parcelable.sharedMemories[i])); } } AudioEndpointParcelable& AudioEndpointParcelable::operator=(Endpoint&& parcelable) { this->~AudioEndpointParcelable(); new(this) AudioEndpointParcelable(std::move(parcelable)); return *this; } Endpoint AudioEndpointParcelable::parcelable()&& { Endpoint result; result.upMessageQueueParcelable = std::move(mUpMessageQueueParcelable).parcelable(); result.downMessageQueueParcelable = std::move(mDownMessageQueueParcelable).parcelable(); result.upDataQueueParcelable = std::move(mUpDataQueueParcelable).parcelable(); result.downDataQueueParcelable = std::move(mDownDataQueueParcelable).parcelable(); result.sharedMemories.reserve(std::min(mNumSharedMemories, MAX_SHARED_MEMORIES)); for (size_t i = 0; i < mNumSharedMemories && i < MAX_SHARED_MEMORIES; ++i) { result.sharedMemories.emplace_back(std::move(mSharedMemories[i]).parcelable()); } return result; } /** * 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; } 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"); }