Home | History | Annotate | Download | only in binding
      1 /*
      2  * Copyright (C) 2017 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 
     18 #define LOG_TAG "AAudioBinderClient"
     19 //#define LOG_NDEBUG 0
     20 #include <utils/Log.h>
     21 
     22 #include <binder/IInterface.h>
     23 #include <binder/IServiceManager.h>
     24 #include <binder/ProcessState.h>
     25 #include <utils/Mutex.h>
     26 #include <utils/RefBase.h>
     27 #include <utils/Singleton.h>
     28 #include <media/AudioSystem.h>
     29 
     30 #include <aaudio/AAudio.h>
     31 
     32 #include "AudioEndpointParcelable.h"
     33 #include "binding/AAudioBinderClient.h"
     34 //#include "binding/AAudioStreamRequest.h"
     35 //#include "binding/AAudioStreamConfiguration.h"
     36 //#include "binding/IAAudioService.h"
     37 //#include "binding/AAudioServiceMessage.h"
     38 
     39 //#include "AAudioServiceInterface.h"
     40 
     41 using android::String16;
     42 using android::IServiceManager;
     43 using android::defaultServiceManager;
     44 using android::interface_cast;
     45 using android::IInterface;
     46 using android::IAAudioService;
     47 using android::Mutex;
     48 using android::ProcessState;
     49 using android::sp;
     50 using android::wp;
     51 
     52 using namespace aaudio;
     53 
     54 ANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient);
     55 
     56 // If we don't keep a strong pointer here then this singleton can get deleted!
     57 android::sp<AAudioBinderClient> gKeepBinderClient;
     58 
     59 AAudioBinderClient::AAudioBinderClient()
     60         : AAudioServiceInterface()
     61         , Singleton<AAudioBinderClient>() {
     62     gKeepBinderClient = this; // so this singleton won't get deleted
     63     mAAudioClient = new AAudioClient(this);
     64     ALOGV("%s - this = %p, created mAAudioClient = %p", __func__, this, mAAudioClient.get());
     65 }
     66 
     67 AAudioBinderClient::~AAudioBinderClient() {
     68     ALOGV("%s - destroying %p", __func__, this);
     69     Mutex::Autolock _l(mServiceLock);
     70     if (mAAudioService != 0) {
     71         IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient);
     72     }
     73 }
     74 
     75 // TODO Share code with other service clients.
     76 // Helper function to get access to the "AAudioService" service.
     77 // This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp
     78 const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
     79     sp<IAAudioService> aaudioService;
     80     bool needToRegister = false;
     81     {
     82         Mutex::Autolock _l(mServiceLock);
     83         if (mAAudioService.get() == nullptr) {
     84             sp<IBinder> binder;
     85             sp<IServiceManager> sm = defaultServiceManager();
     86             // Try several times to get the service.
     87             int retries = 4;
     88             do {
     89                 binder = sm->getService(String16(AAUDIO_SERVICE_NAME)); // This will wait a while.
     90                 if (binder.get() != nullptr) {
     91                     break;
     92                 }
     93             } while (retries-- > 0);
     94 
     95             if (binder.get() != nullptr) {
     96                 // Ask for notification if the service dies.
     97                 status_t status = binder->linkToDeath(mAAudioClient);
     98                 // TODO review what we should do if this fails
     99                 if (status != NO_ERROR) {
    100                     ALOGE("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d",
    101                           mAAudioClient.get(), status);
    102                 }
    103                 mAAudioService = interface_cast<IAAudioService>(binder);
    104                 needToRegister = true;
    105                 // Make sure callbacks can be received by mAAudioClient
    106                 ProcessState::self()->startThreadPool();
    107             } else {
    108                 ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
    109             }
    110         }
    111         aaudioService = mAAudioService;
    112     }
    113     // Do this outside the mutex lock.
    114     if (needToRegister && aaudioService.get() != nullptr) { // new client?
    115         aaudioService->registerClient(mAAudioClient);
    116     }
    117     return aaudioService;
    118 }
    119 
    120 void AAudioBinderClient::dropAAudioService() {
    121     Mutex::Autolock _l(mServiceLock);
    122     mAAudioService.clear(); // force a reconnect
    123 }
    124 
    125 /**
    126 * @param request info needed to create the stream
    127 * @param configuration contains information about the created stream
    128 * @return handle to the stream or a negative error
    129 */
    130 aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
    131                                                AAudioStreamConfiguration &configurationOutput) {
    132     aaudio_handle_t stream;
    133     for (int i = 0; i < 2; i++) {
    134         const sp<IAAudioService> &service = getAAudioService();
    135         if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    136 
    137         stream = service->openStream(request, configurationOutput);
    138 
    139         if (stream == AAUDIO_ERROR_NO_SERVICE) {
    140             ALOGE("openStream lost connection to AAudioService.");
    141             dropAAudioService(); // force a reconnect
    142         } else {
    143             break;
    144         }
    145     }
    146     return stream;
    147 }
    148 
    149 aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
    150     const sp<IAAudioService> service = getAAudioService();
    151     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    152     return service->closeStream(streamHandle);
    153 }
    154 
    155 /* Get an immutable description of the in-memory queues
    156 * used to communicate with the underlying HAL or Service.
    157 */
    158 aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
    159                                                          AudioEndpointParcelable &parcelable) {
    160     const sp<IAAudioService> service = getAAudioService();
    161     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    162     return service->getStreamDescription(streamHandle, parcelable);
    163 }
    164 
    165 aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
    166     const sp<IAAudioService> service = getAAudioService();
    167     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    168     return service->startStream(streamHandle);
    169 }
    170 
    171 aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
    172     const sp<IAAudioService> service = getAAudioService();
    173     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    174     return service->pauseStream(streamHandle);
    175 }
    176 
    177 aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
    178     const sp<IAAudioService> service = getAAudioService();
    179     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    180     return service->stopStream(streamHandle);
    181 }
    182 
    183 aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
    184     const sp<IAAudioService> service = getAAudioService();
    185     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    186     return service->flushStream(streamHandle);
    187 }
    188 
    189 /**
    190 * Manage the specified thread as a low latency audio thread.
    191 */
    192 aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
    193                                                         pid_t clientThreadId,
    194                                                         int64_t periodNanoseconds) {
    195     const sp<IAAudioService> service = getAAudioService();
    196     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    197     return service->registerAudioThread(streamHandle,
    198                                         clientThreadId,
    199                                         periodNanoseconds);
    200 }
    201 
    202 aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
    203                                                           pid_t clientThreadId) {
    204     const sp<IAAudioService> service = getAAudioService();
    205     if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
    206     return service->unregisterAudioThread(streamHandle,
    207                                           clientThreadId);
    208 }
    209