1c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/* 2c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Copyright (C) 2017 The Android Open Source Project 3c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 4c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * you may not use this file except in compliance with the License. 6c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * You may obtain a copy of the License at 7c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 8c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * http://www.apache.org/licenses/LICENSE-2.0 9c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 10c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Unless required by applicable law or agreed to in writing, software 11c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * See the License for the specific language governing permissions and 14c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * limitations under the License. 15c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */ 16c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 17c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 18fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk#define LOG_TAG "AAudioBinderClient" 19c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk//#define LOG_NDEBUG 0 20c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/Log.h> 21c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 2211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <binder/IInterface.h> 23c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <binder/IServiceManager.h> 2411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <binder/ProcessState.h> 25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/Mutex.h> 26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/RefBase.h> 279b3f8ef290bd5ad392f5eba8a0f0a8ddd331b54fPhil Burk#include <utils/Singleton.h> 2811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include <media/AudioSystem.h> 29c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 30c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <aaudio/AAudio.h> 31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 32c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AudioEndpointParcelable.h" 3311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk#include "binding/AAudioBinderClient.h" 3411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#include "binding/AAudioStreamRequest.h" 3511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#include "binding/AAudioStreamConfiguration.h" 3611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#include "binding/IAAudioService.h" 3711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#include "binding/AAudioServiceMessage.h" 38c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 3911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk//#include "AAudioServiceInterface.h" 40c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 41c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::String16; 42c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::IServiceManager; 43c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::defaultServiceManager; 44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::interface_cast; 4511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkusing android::IInterface; 46c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::IAAudioService; 47c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::Mutex; 482bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burkusing android::ProcessState; 49c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing android::sp; 5011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkusing android::wp; 51c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace aaudio; 53c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 549b3f8ef290bd5ad392f5eba8a0f0a8ddd331b54fPhil BurkANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient); 559b3f8ef290bd5ad392f5eba8a0f0a8ddd331b54fPhil Burk 562bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk// If we don't keep a strong pointer here then this singleton can get deleted! 572bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burkandroid::sp<AAudioBinderClient> gKeepBinderClient; 582bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk 5911e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioBinderClient::AAudioBinderClient() 6011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk : AAudioServiceInterface() 6111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk , Singleton<AAudioBinderClient>() { 622bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk gKeepBinderClient = this; // so this singleton won't get deleted 6311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mAAudioClient = new AAudioClient(this); 64fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("%s - this = %p, created mAAudioClient = %p", __func__, this, mAAudioClient.get()); 6511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 6611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 6711e8d335b1da528ee771b19b63df23ae6fd52f41Phil BurkAAudioBinderClient::~AAudioBinderClient() { 68fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGV("%s - destroying %p", __func__, this); 6911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk Mutex::Autolock _l(mServiceLock); 7011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk if (mAAudioService != 0) { 7111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient); 7211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 7311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk} 7411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 75c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk// TODO Share code with other service clients. 76c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk// Helper function to get access to the "AAudioService" service. 77c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk// This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp 7811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkconst sp<IAAudioService> AAudioBinderClient::getAAudioService() { 7911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<IAAudioService> aaudioService; 8011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk bool needToRegister = false; 8111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk { 8211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk Mutex::Autolock _l(mServiceLock); 832bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (mAAudioService.get() == nullptr) { 8411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<IBinder> binder; 8511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk sp<IServiceManager> sm = defaultServiceManager(); 8611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // Try several times to get the service. 8711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk int retries = 4; 8811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk do { 8911e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk binder = sm->getService(String16(AAUDIO_SERVICE_NAME)); // This will wait a while. 902bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (binder.get() != nullptr) { 9111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk break; 9211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 9311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } while (retries-- > 0); 9411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk 952bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (binder.get() != nullptr) { 9611e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // Ask for notification if the service dies. 9711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk status_t status = binder->linkToDeath(mAAudioClient); 98c7abac4329e15cda4bbbd25f8fc4a93b70d70d0aPhil Burk // TODO review what we should do if this fails 99c7abac4329e15cda4bbbd25f8fc4a93b70d70d0aPhil Burk if (status != NO_ERROR) { 100c7abac4329e15cda4bbbd25f8fc4a93b70d70d0aPhil Burk ALOGE("getAAudioService: linkToDeath(mAAudioClient = %p) returned %d", 101c7abac4329e15cda4bbbd25f8fc4a93b70d70d0aPhil Burk mAAudioClient.get(), status); 102c7abac4329e15cda4bbbd25f8fc4a93b70d70d0aPhil Burk } 10311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mAAudioService = interface_cast<IAAudioService>(binder); 10411e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk needToRegister = true; 10511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // Make sure callbacks can be received by mAAudioClient 1062bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk ProcessState::self()->startThreadPool(); 10711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } else { 10811e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME); 109c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 11111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk aaudioService = mAAudioService; 11211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk } 11311e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk // Do this outside the mutex lock. 1142bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (needToRegister && aaudioService.get() != nullptr) { // new client? 11511e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk aaudioService->registerClient(mAAudioClient); 116c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 11711e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk return aaudioService; 118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 12011e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burkvoid AAudioBinderClient::dropAAudioService() { 12111e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk Mutex::Autolock _l(mServiceLock); 12211e8d335b1da528ee771b19b63df23ae6fd52f41Phil Burk mAAudioService.clear(); // force a reconnect 12371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk} 124c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 125c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 126c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk* @param request info needed to create the stream 127c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk* @param configuration contains information about the created stream 128c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk* @return handle to the stream or a negative error 129c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk*/ 130c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request, 131c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk AAudioStreamConfiguration &configurationOutput) { 13271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk aaudio_handle_t stream; 13371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk for (int i = 0; i < 2; i++) { 13471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk const sp<IAAudioService> &service = getAAudioService(); 1352bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 136c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 13771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk stream = service->openStream(request, configurationOutput); 13871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk 13971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (stream == AAUDIO_ERROR_NO_SERVICE) { 140fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("openStream lost connection to AAudioService."); 14171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk dropAAudioService(); // force a reconnect 14271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } else { 14371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk break; 14471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 14571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 14671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return stream; 147c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 148c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 149c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) { 1502bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1512bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 152c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return service->closeStream(streamHandle); 153c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 154c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 155c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/* Get an immutable description of the in-memory queues 156c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk* used to communicate with the underlying HAL or Service. 157c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk*/ 158c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle, 159c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk AudioEndpointParcelable &parcelable) { 1602bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1612bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 162c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return service->getStreamDescription(streamHandle, parcelable); 163c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 164c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 165c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) { 1662bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1672bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 168c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return service->startStream(streamHandle); 169c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 170c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 171c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) { 1722bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1732bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 17471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return service->pauseStream(streamHandle); 17571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk} 17671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk 17771f35bb687476694882a617ba4a810a0bb56fe23Phil Burkaaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) { 1782bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1792bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 18071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return service->stopStream(streamHandle); 181c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 182c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 183c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) { 1842bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1852bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 18671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return service->flushStream(streamHandle); 187c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 188c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 189c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 190c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk* Manage the specified thread as a low latency audio thread. 191c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk*/ 192c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle, 193c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk pid_t clientThreadId, 194c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk int64_t periodNanoseconds) { 1952bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 1962bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 197c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return service->registerAudioThread(streamHandle, 198c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk clientThreadId, 199c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk periodNanoseconds); 200c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 201c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 202c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle, 203c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk pid_t clientThreadId) { 2042bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk const sp<IAAudioService> service = getAAudioService(); 2052bc7c1838703993e126bfe9a21fee053b6c0ab67Phil Burk if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE; 206c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return service->unregisterAudioThread(streamHandle, 207c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk clientThreadId); 208c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 209