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