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