Home | History | Annotate | Download | only in binding
      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 "AudioEndpointParcelable"
     18 //#define LOG_NDEBUG 0
     19 #include <utils/Log.h>
     20 
     21 #include <stdint.h>
     22 
     23 #include <binder/Parcel.h>
     24 #include <binder/Parcelable.h>
     25 #include <utility/AAudioUtilities.h>
     26 
     27 #include "binding/AAudioServiceDefinitions.h"
     28 #include "binding/RingBufferParcelable.h"
     29 #include "binding/AudioEndpointParcelable.h"
     30 
     31 using android::base::unique_fd;
     32 using android::NO_ERROR;
     33 using android::status_t;
     34 using android::Parcel;
     35 using android::Parcelable;
     36 
     37 using namespace aaudio;
     38 
     39 /**
     40  * Container for information about the message queues plus
     41  * general stream information needed by AAudio clients.
     42  * It contains no addresses, just sizes, offsets and file descriptors for
     43  * shared memory that can be passed through Binder.
     44  */
     45 AudioEndpointParcelable::AudioEndpointParcelable() {}
     46 
     47 AudioEndpointParcelable::~AudioEndpointParcelable() {}
     48 
     49 /**
     50  * Add the file descriptor to the table.
     51  * @return index in table or negative error
     52  */
     53 int32_t AudioEndpointParcelable::addFileDescriptor(const unique_fd& fd,
     54                                                    int32_t sizeInBytes) {
     55     if (mNumSharedMemories >= MAX_SHARED_MEMORIES) {
     56         return AAUDIO_ERROR_OUT_OF_RANGE;
     57     }
     58     int32_t index = mNumSharedMemories++;
     59     mSharedMemories[index].setup(fd, sizeInBytes);
     60     return index;
     61 }
     62 
     63 /**
     64  * The read and write must be symmetric.
     65  */
     66 status_t AudioEndpointParcelable::writeToParcel(Parcel* parcel) const {
     67     status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
     68     if (status != NO_ERROR) goto error;
     69 
     70     status = parcel->writeInt32(mNumSharedMemories);
     71     if (status != NO_ERROR) goto error;
     72 
     73     for (int i = 0; i < mNumSharedMemories; i++) {
     74         status = mSharedMemories[i].writeToParcel(parcel);
     75         if (status != NO_ERROR) goto error;
     76     }
     77     status = mUpMessageQueueParcelable.writeToParcel(parcel);
     78     if (status != NO_ERROR) goto error;
     79     status = mDownMessageQueueParcelable.writeToParcel(parcel);
     80     if (status != NO_ERROR) goto error;
     81     status = mUpDataQueueParcelable.writeToParcel(parcel);
     82     if (status != NO_ERROR) goto error;
     83     status = mDownDataQueueParcelable.writeToParcel(parcel);
     84     if (status != NO_ERROR) goto error;
     85 
     86     return NO_ERROR;
     87 
     88 error:
     89     ALOGE("%s returning %d", __func__, status);
     90     return status;
     91 }
     92 
     93 status_t AudioEndpointParcelable::readFromParcel(const Parcel* parcel) {
     94     status_t status = parcel->readInt32(&mNumSharedMemories);
     95     if (status != NO_ERROR) goto error;
     96 
     97     for (int i = 0; i < mNumSharedMemories; i++) {
     98         mSharedMemories[i].readFromParcel(parcel);
     99         if (status != NO_ERROR) goto error;
    100     }
    101     status = mUpMessageQueueParcelable.readFromParcel(parcel);
    102     if (status != NO_ERROR) goto error;
    103     status = mDownMessageQueueParcelable.readFromParcel(parcel);
    104     if (status != NO_ERROR) goto error;
    105     status = mUpDataQueueParcelable.readFromParcel(parcel);
    106     if (status != NO_ERROR) goto error;
    107     status = mDownDataQueueParcelable.readFromParcel(parcel);
    108     if (status != NO_ERROR) goto error;
    109 
    110     return AAudioConvert_aaudioToAndroidStatus(validate());
    111 
    112 error:
    113     ALOGE("%s returning %d", __func__, status);
    114     return status;
    115 }
    116 
    117 aaudio_result_t AudioEndpointParcelable::resolve(EndpointDescriptor *descriptor) {
    118     aaudio_result_t result = mUpMessageQueueParcelable.resolve(mSharedMemories,
    119                                                            &descriptor->upMessageQueueDescriptor);
    120     if (result != AAUDIO_OK) return result;
    121     result = mDownMessageQueueParcelable.resolve(mSharedMemories,
    122                                         &descriptor->downMessageQueueDescriptor);
    123     if (result != AAUDIO_OK) return result;
    124 
    125     result = mDownDataQueueParcelable.resolve(mSharedMemories,
    126                                               &descriptor->dataQueueDescriptor);
    127     return result;
    128 }
    129 
    130 aaudio_result_t AudioEndpointParcelable::close() {
    131     int err = 0;
    132     for (int i = 0; i < mNumSharedMemories; i++) {
    133         int lastErr = mSharedMemories[i].close();
    134         if (lastErr < 0) err = lastErr;
    135     }
    136     return AAudioConvert_androidToAAudioResult(err);
    137 }
    138 
    139 aaudio_result_t AudioEndpointParcelable::validate() const {
    140     if (mNumSharedMemories < 0 || mNumSharedMemories >= MAX_SHARED_MEMORIES) {
    141         ALOGE("invalid mNumSharedMemories = %d", mNumSharedMemories);
    142         return AAUDIO_ERROR_INTERNAL;
    143     }
    144     return AAUDIO_OK;
    145 }
    146 
    147 void AudioEndpointParcelable::dump() {
    148     ALOGD("======================================= BEGIN");
    149     ALOGD("mNumSharedMemories = %d", mNumSharedMemories);
    150     for (int i = 0; i < mNumSharedMemories; i++) {
    151         mSharedMemories[i].dump();
    152     }
    153     ALOGD("mUpMessageQueueParcelable =========");
    154     mUpMessageQueueParcelable.dump();
    155     ALOGD("mDownMessageQueueParcelable =======");
    156     mDownMessageQueueParcelable.dump();
    157     ALOGD("mUpDataQueueParcelable ============");
    158     mUpDataQueueParcelable.dump();
    159     ALOGD("mDownDataQueueParcelable ==========");
    160     mDownDataQueueParcelable.dump();
    161     ALOGD("======================================= END");
    162 }
    163 
    164