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 "AAudio" 19 //#define LOG_NDEBUG 0 20 #include <utils/Log.h> 21 22 #include <binder/IServiceManager.h> 23 #include <utils/Mutex.h> 24 #include <utils/RefBase.h> 25 #include <utils/Singleton.h> 26 27 #include <aaudio/AAudio.h> 28 29 #include "AudioEndpointParcelable.h" 30 #include "binding/AAudioStreamRequest.h" 31 #include "binding/AAudioStreamConfiguration.h" 32 #include "binding/IAAudioService.h" 33 #include "binding/AAudioServiceMessage.h" 34 35 #include "AAudioBinderClient.h" 36 #include "AAudioServiceInterface.h" 37 38 using android::String16; 39 using android::IServiceManager; 40 using android::defaultServiceManager; 41 using android::interface_cast; 42 using android::IAAudioService; 43 using android::Mutex; 44 using android::sp; 45 46 using namespace aaudio; 47 48 static android::Mutex gServiceLock; 49 static sp<IAAudioService> gAAudioService; 50 51 ANDROID_SINGLETON_STATIC_INSTANCE(AAudioBinderClient); 52 53 // TODO Share code with other service clients. 54 // Helper function to get access to the "AAudioService" service. 55 // This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp 56 static const sp<IAAudioService> getAAudioService() { 57 sp<IBinder> binder; 58 Mutex::Autolock _l(gServiceLock); 59 if (gAAudioService == 0) { 60 sp<IServiceManager> sm = defaultServiceManager(); 61 // Try several times to get the service. 62 int retries = 4; 63 do { 64 binder = sm->getService(String16(AAUDIO_SERVICE_NAME)); // This will wait a while. 65 if (binder != 0) { 66 break; 67 } 68 } while (retries-- > 0); 69 70 if (binder != 0) { 71 // TODO Add linkToDeath() like in frameworks/av/media/libaudioclient/AudioSystem.cpp 72 // TODO Create a DeathRecipient that disconnects all active streams. 73 gAAudioService = interface_cast<IAAudioService>(binder); 74 } else { 75 ALOGE("AudioStreamInternal could not get %s", AAUDIO_SERVICE_NAME); 76 } 77 } 78 return gAAudioService; 79 } 80 81 static void dropAAudioService() { 82 Mutex::Autolock _l(gServiceLock); 83 gAAudioService.clear(); // force a reconnect 84 } 85 86 AAudioBinderClient::AAudioBinderClient() 87 : AAudioServiceInterface() 88 , Singleton<AAudioBinderClient>() {} 89 90 AAudioBinderClient::~AAudioBinderClient() {} 91 92 /** 93 * @param request info needed to create the stream 94 * @param configuration contains information about the created stream 95 * @return handle to the stream or a negative error 96 */ 97 aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request, 98 AAudioStreamConfiguration &configurationOutput) { 99 aaudio_handle_t stream; 100 for (int i = 0; i < 2; i++) { 101 const sp<IAAudioService> &service = getAAudioService(); 102 if (service == 0) { 103 return AAUDIO_ERROR_NO_SERVICE; 104 } 105 106 stream = service->openStream(request, configurationOutput); 107 108 if (stream == AAUDIO_ERROR_NO_SERVICE) { 109 ALOGE("AAudioBinderClient: lost connection to AAudioService."); 110 dropAAudioService(); // force a reconnect 111 } else { 112 break; 113 } 114 } 115 return stream; 116 } 117 118 aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) { 119 const sp<IAAudioService> &service = getAAudioService(); 120 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 121 return service->closeStream(streamHandle); 122 } 123 124 /* Get an immutable description of the in-memory queues 125 * used to communicate with the underlying HAL or Service. 126 */ 127 aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle, 128 AudioEndpointParcelable &parcelable) { 129 const sp<IAAudioService> &service = getAAudioService(); 130 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 131 return service->getStreamDescription(streamHandle, parcelable); 132 } 133 134 aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) { 135 const sp<IAAudioService> &service = getAAudioService(); 136 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 137 return service->startStream(streamHandle); 138 } 139 140 aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) { 141 const sp<IAAudioService> &service = getAAudioService(); 142 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 143 return service->pauseStream(streamHandle); 144 } 145 146 aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) { 147 const sp<IAAudioService> &service = getAAudioService(); 148 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 149 return service->stopStream(streamHandle); 150 } 151 152 aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) { 153 const sp<IAAudioService> &service = getAAudioService(); 154 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 155 return service->flushStream(streamHandle); 156 } 157 158 /** 159 * Manage the specified thread as a low latency audio thread. 160 */ 161 aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle, 162 pid_t clientProcessId, 163 pid_t clientThreadId, 164 int64_t periodNanoseconds) { 165 const sp<IAAudioService> &service = getAAudioService(); 166 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 167 return service->registerAudioThread(streamHandle, 168 clientProcessId, 169 clientThreadId, 170 periodNanoseconds); 171 } 172 173 aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle, 174 pid_t clientProcessId, 175 pid_t clientThreadId) { 176 const sp<IAAudioService> &service = getAAudioService(); 177 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 178 return service->unregisterAudioThread(streamHandle, 179 clientProcessId, 180 clientThreadId); 181 } 182