Home | History | Annotate | Download | only in binding
      1 /*
      2  * Copyright (C) 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 #include <aaudio/AAudio.h>
     18 
     19 #include "binding/AudioEndpointParcelable.h"
     20 #include "binding/AAudioStreamRequest.h"
     21 #include "binding/AAudioServiceDefinitions.h"
     22 #include "binding/AAudioStreamConfiguration.h"
     23 #include "binding/IAAudioService.h"
     24 #include "utility/AAudioUtilities.h"
     25 
     26 namespace android {
     27 
     28 using aaudio::aaudio_handle_t;
     29 
     30 /**
     31  * This is used by the AAudio Client to talk to the AAudio Service.
     32  *
     33  * The order of parameters in the Parcels must match with code in AAudioService.cpp.
     34  */
     35 class BpAAudioService : public BpInterface<IAAudioService>
     36 {
     37 public:
     38     explicit BpAAudioService(const sp<IBinder>& impl)
     39         : BpInterface<IAAudioService>(impl)
     40     {
     41     }
     42 
     43     virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
     44                                      aaudio::AAudioStreamConfiguration &configurationOutput) override {
     45         Parcel data, reply;
     46         // send command
     47         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
     48         ALOGV("BpAAudioService::client openStream --------------------");
     49         // request.dump();
     50         request.writeToParcel(&data);
     51         status_t err = remote()->transact(OPEN_STREAM, data, &reply);
     52         ALOGV("BpAAudioService::client openStream returned %d", err);
     53         if (err != NO_ERROR) {
     54             ALOGE("BpAAudioService::client openStream transact failed %d", err);
     55             return AAudioConvert_androidToAAudioResult(err);
     56         }
     57         // parse reply
     58         aaudio_handle_t stream;
     59         err = reply.readInt32(&stream);
     60         if (err != NO_ERROR) {
     61             ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
     62             return AAudioConvert_androidToAAudioResult(err);
     63         } else if (stream < 0) {
     64             ALOGE("BpAAudioService::client OPEN_STREAM passed stream %d", stream);
     65             return stream;
     66         }
     67         err = configurationOutput.readFromParcel(&reply);
     68         if (err != NO_ERROR) {
     69             ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
     70             closeStream(stream);
     71             return AAudioConvert_androidToAAudioResult(err);
     72         }
     73         return stream;
     74     }
     75 
     76     virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
     77         Parcel data, reply;
     78         // send command
     79         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
     80         data.writeInt32(streamHandle);
     81         status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
     82         if (err != NO_ERROR) {
     83             ALOGE("BpAAudioService::client closeStream transact failed %d", err);
     84             return AAudioConvert_androidToAAudioResult(err);
     85         }
     86         // parse reply
     87         aaudio_result_t res;
     88         reply.readInt32(&res);
     89         return res;
     90     }
     91 
     92     virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
     93                                                aaudio::AudioEndpointParcelable &parcelable)   {
     94         Parcel data, reply;
     95         // send command
     96         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
     97         data.writeInt32(streamHandle);
     98         status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
     99         if (err != NO_ERROR) {
    100             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
    101             return AAudioConvert_androidToAAudioResult(err);
    102         }
    103         // parse reply
    104         aaudio_result_t result;
    105         err = reply.readInt32(&result);
    106         if (err != NO_ERROR) {
    107             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
    108             return AAudioConvert_androidToAAudioResult(err);
    109         } else if (result != AAUDIO_OK) {
    110             ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
    111             return result;
    112         }
    113         err = parcelable.readFromParcel(&reply);;
    114         if (err != NO_ERROR) {
    115             ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
    116             return AAudioConvert_androidToAAudioResult(err);
    117         }
    118         //parcelable.dump();
    119         result = parcelable.validate();
    120         if (result != AAUDIO_OK) {
    121             ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION validation fails %d", result);
    122             return result;
    123         }
    124         return result;
    125     }
    126 
    127     // TODO should we wait for a reply?
    128     virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
    129         Parcel data, reply;
    130         // send command
    131         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    132         data.writeInt32(streamHandle);
    133         status_t err = remote()->transact(START_STREAM, data, &reply);
    134         if (err != NO_ERROR) {
    135             return AAudioConvert_androidToAAudioResult(err);
    136         }
    137         // parse reply
    138         aaudio_result_t res;
    139         reply.readInt32(&res);
    140         return res;
    141     }
    142 
    143     virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
    144         Parcel data, reply;
    145         // send command
    146         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    147         data.writeInt32(streamHandle);
    148         status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
    149         if (err != NO_ERROR) {
    150             return AAudioConvert_androidToAAudioResult(err);
    151         }
    152         // parse reply
    153         aaudio_result_t res;
    154         reply.readInt32(&res);
    155         return res;
    156     }
    157 
    158     virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
    159         Parcel data, reply;
    160         // send command
    161         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    162         data.writeInt32(streamHandle);
    163         status_t err = remote()->transact(STOP_STREAM, data, &reply);
    164         if (err != NO_ERROR) {
    165             return AAudioConvert_androidToAAudioResult(err);
    166         }
    167         // parse reply
    168         aaudio_result_t res;
    169         reply.readInt32(&res);
    170         return res;
    171     }
    172 
    173     virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
    174         Parcel data, reply;
    175         // send command
    176         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    177         data.writeInt32(streamHandle);
    178         status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
    179         if (err != NO_ERROR) {
    180             return AAudioConvert_androidToAAudioResult(err);
    181         }
    182         // parse reply
    183         aaudio_result_t res;
    184         reply.readInt32(&res);
    185         return res;
    186     }
    187 
    188     virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
    189                                               pid_t clientProcessId,
    190                                               pid_t clientThreadId,
    191                                               int64_t periodNanoseconds)
    192     override {
    193         Parcel data, reply;
    194         // send command
    195         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    196         data.writeInt32(streamHandle);
    197         data.writeInt32((int32_t) clientProcessId);
    198         data.writeInt32((int32_t) clientThreadId);
    199         data.writeInt64(periodNanoseconds);
    200         status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
    201         if (err != NO_ERROR) {
    202             return AAudioConvert_androidToAAudioResult(err);
    203         }
    204         // parse reply
    205         aaudio_result_t res;
    206         reply.readInt32(&res);
    207         return res;
    208     }
    209 
    210     virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
    211                                                   pid_t clientProcessId,
    212                                                   pid_t clientThreadId)
    213     override {
    214         Parcel data, reply;
    215         // send command
    216         data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
    217         data.writeInt32(streamHandle);
    218         data.writeInt32((int32_t) clientProcessId);
    219         data.writeInt32((int32_t) clientThreadId);
    220         status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
    221         if (err != NO_ERROR) {
    222             return AAudioConvert_androidToAAudioResult(err);
    223         }
    224         // parse reply
    225         aaudio_result_t res;
    226         reply.readInt32(&res);
    227         return res;
    228     }
    229 
    230 };
    231 
    232 // Implement an interface to the service.
    233 // This is here so that you don't have to link with libaaudio static library.
    234 IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
    235 
    236 // The order of parameters in the Parcels must match with code in BpAAudioService
    237 
    238 status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
    239                                         Parcel* reply, uint32_t flags) {
    240     aaudio_handle_t stream;
    241     aaudio::AAudioStreamRequest request;
    242     aaudio::AAudioStreamConfiguration configuration;
    243     pid_t pid;
    244     pid_t tid;
    245     int64_t nanoseconds;
    246     aaudio_result_t result;
    247     ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
    248     data.checkInterface(this);
    249 
    250     switch(code) {
    251         case OPEN_STREAM: {
    252             request.readFromParcel(&data);
    253 
    254             //ALOGD("BnAAudioService::client openStream request dump --------------------");
    255             //request.dump();
    256 
    257             stream = openStream(request, configuration);
    258             //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", stream);
    259             reply->writeInt32(stream);
    260             configuration.writeToParcel(reply);
    261             return NO_ERROR;
    262         } break;
    263 
    264         case CLOSE_STREAM: {
    265             data.readInt32(&stream);
    266             result = closeStream(stream);
    267             //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
    268             //      stream, result);
    269             reply->writeInt32(result);
    270             return NO_ERROR;
    271         } break;
    272 
    273         case GET_STREAM_DESCRIPTION: {
    274             data.readInt32(&stream);
    275             aaudio::AudioEndpointParcelable parcelable;
    276             result = getStreamDescription(stream, parcelable);
    277             if (result != AAUDIO_OK) {
    278                 return AAudioConvert_aaudioToAndroidStatus(result);
    279             }
    280             result = parcelable.validate();
    281             if (result != AAUDIO_OK) {
    282                 ALOGE("BnAAudioService::onTransact getStreamDescription() returns %d", result);
    283                 parcelable.dump();
    284                 return AAudioConvert_aaudioToAndroidStatus(result);
    285             }
    286             reply->writeInt32(result);
    287             parcelable.writeToParcel(reply);
    288             return NO_ERROR;
    289         } break;
    290 
    291         case START_STREAM: {
    292             data.readInt32(&stream);
    293             result = startStream(stream);
    294             ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
    295                     stream, result);
    296             reply->writeInt32(result);
    297             return NO_ERROR;
    298         } break;
    299 
    300         case PAUSE_STREAM: {
    301             data.readInt32(&stream);
    302             result = pauseStream(stream);
    303             ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
    304                   stream, result);
    305             reply->writeInt32(result);
    306             return NO_ERROR;
    307         } break;
    308 
    309         case STOP_STREAM: {
    310             data.readInt32(&stream);
    311             result = stopStream(stream);
    312             ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
    313                   stream, result);
    314             reply->writeInt32(result);
    315             return NO_ERROR;
    316         } break;
    317 
    318         case FLUSH_STREAM: {
    319             data.readInt32(&stream);
    320             result = flushStream(stream);
    321             ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
    322                     stream, result);
    323             reply->writeInt32(result);
    324             return NO_ERROR;
    325         } break;
    326 
    327         case REGISTER_AUDIO_THREAD: {
    328             data.readInt32(&stream);
    329             data.readInt32(&pid);
    330             data.readInt32(&tid);
    331             data.readInt64(&nanoseconds);
    332             result = registerAudioThread(stream, pid, tid, nanoseconds);
    333             ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
    334                     stream, result);
    335             reply->writeInt32(result);
    336             return NO_ERROR;
    337         } break;
    338 
    339         case UNREGISTER_AUDIO_THREAD: {
    340             data.readInt32(&stream);
    341             data.readInt32(&pid);
    342             data.readInt32(&tid);
    343             result = unregisterAudioThread(stream, pid, tid);
    344             ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
    345                     stream, result);
    346             reply->writeInt32(result);
    347             return NO_ERROR;
    348         } break;
    349 
    350         default:
    351             // ALOGW("BnAAudioService::onTransact not handled %u", code);
    352             return BBinder::onTransact(code, data, reply, flags);
    353     }
    354 }
    355 
    356 } /* namespace android */
    357