• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 #include <dlfcn.h>
18 #include <oboe/Utilities.h>
19 #include "common/OboeDebug.h"
20 #include "AAudioLoader.h"
21 
22 #define LIB_AAUDIO_NAME "libaaudio.so"
23 
24 namespace oboe {
25 
~AAudioLoader()26 AAudioLoader::~AAudioLoader() {
27     // Issue 360: thread_local variables with non-trivial destructors
28     // will cause segfaults if the containing library is dlclose()ed on
29     // devices running M or newer, or devices before M when using a static STL.
30     // The simple workaround is to not call dlclose.
31     // https://github.com/android/ndk/wiki/Changelog-r22#known-issues
32     //
33     // The libaaudio and libaaudioclient do not use thread_local.
34     // But, to be safe, we should avoid dlclose() if possible.
35     // Because AAudioLoader is a static Singleton, we can safely skip
36     // calling dlclose() without causing a resource leak.
37     LOGI("%s() dlclose(%s) not called, OK", __func__, LIB_AAUDIO_NAME);
38 }
39 
getInstance()40 AAudioLoader* AAudioLoader::getInstance() {
41     static AAudioLoader instance;
42     return &instance;
43 }
44 
open()45 int AAudioLoader::open() {
46     if (mLibHandle != nullptr) {
47         return 0;
48     }
49 
50     // Use RTLD_NOW to avoid the unpredictable behavior that RTLD_LAZY can cause.
51     // Also resolving all the links now will prevent a run-time penalty later.
52     mLibHandle = dlopen(LIB_AAUDIO_NAME, RTLD_NOW);
53     if (mLibHandle == nullptr) {
54         LOGI("AAudioLoader::open() could not find " LIB_AAUDIO_NAME);
55         return -1; // TODO review return code
56     } else {
57         LOGD("AAudioLoader():  dlopen(%s) returned %p", LIB_AAUDIO_NAME, mLibHandle);
58     }
59 
60     // Load all the function pointers.
61     createStreamBuilder        = load_I_PPB("AAudio_createStreamBuilder");
62     builder_openStream         = load_I_PBPPS("AAudioStreamBuilder_openStream");
63 
64     builder_setChannelCount    = load_V_PBI("AAudioStreamBuilder_setChannelCount");
65     if (builder_setChannelCount == nullptr) {
66         // Use old deprecated alias if needed.
67         builder_setChannelCount = load_V_PBI("AAudioStreamBuilder_setSamplesPerFrame");
68     }
69 
70     builder_setBufferCapacityInFrames = load_V_PBI("AAudioStreamBuilder_setBufferCapacityInFrames");
71     builder_setDeviceId        = load_V_PBI("AAudioStreamBuilder_setDeviceId");
72     builder_setDirection       = load_V_PBI("AAudioStreamBuilder_setDirection");
73     builder_setFormat          = load_V_PBI("AAudioStreamBuilder_setFormat");
74     builder_setFramesPerDataCallback = load_V_PBI("AAudioStreamBuilder_setFramesPerDataCallback");
75     builder_setSharingMode     = load_V_PBI("AAudioStreamBuilder_setSharingMode");
76     builder_setPerformanceMode = load_V_PBI("AAudioStreamBuilder_setPerformanceMode");
77     builder_setSampleRate      = load_V_PBI("AAudioStreamBuilder_setSampleRate");
78 
79     if (getSdkVersion() >= __ANDROID_API_P__){
80         builder_setUsage       = load_V_PBI("AAudioStreamBuilder_setUsage");
81         builder_setContentType = load_V_PBI("AAudioStreamBuilder_setContentType");
82         builder_setInputPreset = load_V_PBI("AAudioStreamBuilder_setInputPreset");
83         builder_setSessionId   = load_V_PBI("AAudioStreamBuilder_setSessionId");
84     }
85 
86     builder_delete             = load_I_PB("AAudioStreamBuilder_delete");
87 
88 
89     builder_setDataCallback    = load_V_PBPDPV("AAudioStreamBuilder_setDataCallback");
90     builder_setErrorCallback   = load_V_PBPEPV("AAudioStreamBuilder_setErrorCallback");
91 
92     stream_read                = load_I_PSPVIL("AAudioStream_read");
93 
94     stream_write               = load_I_PSCPVIL("AAudioStream_write");
95 
96     stream_waitForStateChange  = load_I_PSTPTL("AAudioStream_waitForStateChange");
97 
98     stream_getTimestamp        = load_I_PSKPLPL("AAudioStream_getTimestamp");
99 
100     stream_getChannelCount     = load_I_PS("AAudioStream_getChannelCount");
101     if (stream_getChannelCount == nullptr) {
102         // Use old alias if needed.
103         stream_getChannelCount    = load_I_PS("AAudioStream_getSamplesPerFrame");
104     }
105 
106     stream_close               = load_I_PS("AAudioStream_close");
107 
108     stream_getBufferSize       = load_I_PS("AAudioStream_getBufferSizeInFrames");
109     stream_getDeviceId         = load_I_PS("AAudioStream_getDeviceId");
110     stream_getBufferCapacity   = load_I_PS("AAudioStream_getBufferCapacityInFrames");
111     stream_getFormat           = load_F_PS("AAudioStream_getFormat");
112     stream_getFramesPerBurst   = load_I_PS("AAudioStream_getFramesPerBurst");
113     stream_getFramesRead       = load_L_PS("AAudioStream_getFramesRead");
114     stream_getFramesWritten    = load_L_PS("AAudioStream_getFramesWritten");
115     stream_getPerformanceMode  = load_I_PS("AAudioStream_getPerformanceMode");
116     stream_getSampleRate       = load_I_PS("AAudioStream_getSampleRate");
117     stream_getSharingMode      = load_I_PS("AAudioStream_getSharingMode");
118     stream_getState            = load_I_PS("AAudioStream_getState");
119     stream_getXRunCount        = load_I_PS("AAudioStream_getXRunCount");
120 
121     stream_requestStart        = load_I_PS("AAudioStream_requestStart");
122     stream_requestPause        = load_I_PS("AAudioStream_requestPause");
123     stream_requestFlush        = load_I_PS("AAudioStream_requestFlush");
124     stream_requestStop         = load_I_PS("AAudioStream_requestStop");
125 
126     stream_setBufferSize       = load_I_PSI("AAudioStream_setBufferSizeInFrames");
127 
128     convertResultToText        = load_CPH_I("AAudio_convertResultToText");
129 
130     if (getSdkVersion() >= __ANDROID_API_P__){
131         stream_getUsage        = load_I_PS("AAudioStream_getUsage");
132         stream_getContentType  = load_I_PS("AAudioStream_getContentType");
133         stream_getInputPreset  = load_I_PS("AAudioStream_getInputPreset");
134         stream_getSessionId    = load_I_PS("AAudioStream_getSessionId");
135     }
136     return 0;
137 }
138 
AAudioLoader_check(void * proc,const char * functionName)139 static void AAudioLoader_check(void *proc, const char *functionName) {
140     if (proc == nullptr) {
141         LOGW("AAudioLoader could not find %s", functionName);
142     }
143 }
144 
load_I_PPB(const char * functionName)145 AAudioLoader::signature_I_PPB AAudioLoader::load_I_PPB(const char *functionName) {
146     void *proc = dlsym(mLibHandle, functionName);
147     AAudioLoader_check(proc, functionName);
148     return reinterpret_cast<signature_I_PPB>(proc);
149 }
150 
load_CPH_I(const char * functionName)151 AAudioLoader::signature_CPH_I AAudioLoader::load_CPH_I(const char *functionName) {
152     void *proc = dlsym(mLibHandle, functionName);
153     AAudioLoader_check(proc, functionName);
154     return reinterpret_cast<signature_CPH_I>(proc);
155 }
156 
load_V_PBI(const char * functionName)157 AAudioLoader::signature_V_PBI AAudioLoader::load_V_PBI(const char *functionName) {
158     void *proc = dlsym(mLibHandle, functionName);
159     AAudioLoader_check(proc, functionName);
160     return reinterpret_cast<signature_V_PBI>(proc);
161 }
162 
load_V_PBPDPV(const char * functionName)163 AAudioLoader::signature_V_PBPDPV AAudioLoader::load_V_PBPDPV(const char *functionName) {
164     void *proc = dlsym(mLibHandle, functionName);
165     AAudioLoader_check(proc, functionName);
166     return reinterpret_cast<signature_V_PBPDPV>(proc);
167 }
168 
load_V_PBPEPV(const char * functionName)169 AAudioLoader::signature_V_PBPEPV AAudioLoader::load_V_PBPEPV(const char *functionName) {
170     void *proc = dlsym(mLibHandle, functionName);
171     AAudioLoader_check(proc, functionName);
172     return reinterpret_cast<signature_V_PBPEPV>(proc);
173 }
174 
load_I_PSI(const char * functionName)175 AAudioLoader::signature_I_PSI AAudioLoader::load_I_PSI(const char *functionName) {
176     void *proc = dlsym(mLibHandle, functionName);
177     AAudioLoader_check(proc, functionName);
178     return reinterpret_cast<signature_I_PSI>(proc);
179 }
180 
load_I_PS(const char * functionName)181 AAudioLoader::signature_I_PS AAudioLoader::load_I_PS(const char *functionName) {
182     void *proc = dlsym(mLibHandle, functionName);
183     AAudioLoader_check(proc, functionName);
184     return reinterpret_cast<signature_I_PS>(proc);
185 }
186 
load_L_PS(const char * functionName)187 AAudioLoader::signature_L_PS AAudioLoader::load_L_PS(const char *functionName) {
188     void *proc = dlsym(mLibHandle, functionName);
189     AAudioLoader_check(proc, functionName);
190     return reinterpret_cast<signature_L_PS>(proc);
191 }
192 
load_F_PS(const char * functionName)193 AAudioLoader::signature_F_PS AAudioLoader::load_F_PS(const char *functionName) {
194     void *proc = dlsym(mLibHandle, functionName);
195     AAudioLoader_check(proc, functionName);
196     return reinterpret_cast<signature_F_PS>(proc);
197 }
198 
load_B_PS(const char * functionName)199 AAudioLoader::signature_B_PS AAudioLoader::load_B_PS(const char *functionName) {
200     void *proc = dlsym(mLibHandle, functionName);
201     AAudioLoader_check(proc, functionName);
202     return reinterpret_cast<signature_B_PS>(proc);
203 }
204 
load_I_PB(const char * functionName)205 AAudioLoader::signature_I_PB AAudioLoader::load_I_PB(const char *functionName) {
206     void *proc = dlsym(mLibHandle, functionName);
207     AAudioLoader_check(proc, functionName);
208     return reinterpret_cast<signature_I_PB>(proc);
209 }
210 
load_I_PBPPS(const char * functionName)211 AAudioLoader::signature_I_PBPPS AAudioLoader::load_I_PBPPS(const char *functionName) {
212     void *proc = dlsym(mLibHandle, functionName);
213     AAudioLoader_check(proc, functionName);
214     return reinterpret_cast<signature_I_PBPPS>(proc);
215 }
216 
load_I_PSCPVIL(const char * functionName)217 AAudioLoader::signature_I_PSCPVIL AAudioLoader::load_I_PSCPVIL(const char *functionName) {
218     void *proc = dlsym(mLibHandle, functionName);
219     AAudioLoader_check(proc, functionName);
220     return reinterpret_cast<signature_I_PSCPVIL>(proc);
221 }
222 
load_I_PSPVIL(const char * functionName)223 AAudioLoader::signature_I_PSPVIL AAudioLoader::load_I_PSPVIL(const char *functionName) {
224     void *proc = dlsym(mLibHandle, functionName);
225     AAudioLoader_check(proc, functionName);
226     return reinterpret_cast<signature_I_PSPVIL>(proc);
227 }
228 
load_I_PSTPTL(const char * functionName)229 AAudioLoader::signature_I_PSTPTL AAudioLoader::load_I_PSTPTL(const char *functionName) {
230     void *proc = dlsym(mLibHandle, functionName);
231     AAudioLoader_check(proc, functionName);
232     return reinterpret_cast<signature_I_PSTPTL>(proc);
233 }
234 
load_I_PSKPLPL(const char * functionName)235 AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *functionName) {
236     void *proc = dlsym(mLibHandle, functionName);
237     AAudioLoader_check(proc, functionName);
238     return reinterpret_cast<signature_I_PSKPLPL>(proc);
239 }
240 
241 // Ensure that all AAudio primitive data types are int32_t
242 #define ASSERT_INT32(type) static_assert(std::is_same<int32_t, type>::value, \
243 #type" must be int32_t")
244 
245 #define ERRMSG "Oboe constants must match AAudio constants."
246 
247 // These asserts help verify that the Oboe definitions match the equivalent AAudio definitions.
248 // This code is in this .cpp file so it only gets tested once.
249 #ifdef AAUDIO_AAUDIO_H
250 
251     ASSERT_INT32(aaudio_stream_state_t);
252     ASSERT_INT32(aaudio_direction_t);
253     ASSERT_INT32(aaudio_format_t);
254     ASSERT_INT32(aaudio_data_callback_result_t);
255     ASSERT_INT32(aaudio_result_t);
256     ASSERT_INT32(aaudio_sharing_mode_t);
257     ASSERT_INT32(aaudio_performance_mode_t);
258 
259     static_assert((int32_t)StreamState::Uninitialized == AAUDIO_STREAM_STATE_UNINITIALIZED, ERRMSG);
260     static_assert((int32_t)StreamState::Unknown == AAUDIO_STREAM_STATE_UNKNOWN, ERRMSG);
261     static_assert((int32_t)StreamState::Open == AAUDIO_STREAM_STATE_OPEN, ERRMSG);
262     static_assert((int32_t)StreamState::Starting == AAUDIO_STREAM_STATE_STARTING, ERRMSG);
263     static_assert((int32_t)StreamState::Started == AAUDIO_STREAM_STATE_STARTED, ERRMSG);
264     static_assert((int32_t)StreamState::Pausing == AAUDIO_STREAM_STATE_PAUSING, ERRMSG);
265     static_assert((int32_t)StreamState::Paused == AAUDIO_STREAM_STATE_PAUSED, ERRMSG);
266     static_assert((int32_t)StreamState::Flushing == AAUDIO_STREAM_STATE_FLUSHING, ERRMSG);
267     static_assert((int32_t)StreamState::Flushed == AAUDIO_STREAM_STATE_FLUSHED, ERRMSG);
268     static_assert((int32_t)StreamState::Stopping == AAUDIO_STREAM_STATE_STOPPING, ERRMSG);
269     static_assert((int32_t)StreamState::Stopped == AAUDIO_STREAM_STATE_STOPPED, ERRMSG);
270     static_assert((int32_t)StreamState::Closing == AAUDIO_STREAM_STATE_CLOSING, ERRMSG);
271     static_assert((int32_t)StreamState::Closed == AAUDIO_STREAM_STATE_CLOSED, ERRMSG);
272     static_assert((int32_t)StreamState::Disconnected == AAUDIO_STREAM_STATE_DISCONNECTED, ERRMSG);
273 
274     static_assert((int32_t)Direction::Output == AAUDIO_DIRECTION_OUTPUT, ERRMSG);
275     static_assert((int32_t)Direction::Input == AAUDIO_DIRECTION_INPUT, ERRMSG);
276 
277     static_assert((int32_t)AudioFormat::Invalid == AAUDIO_FORMAT_INVALID, ERRMSG);
278     static_assert((int32_t)AudioFormat::Unspecified == AAUDIO_FORMAT_UNSPECIFIED, ERRMSG);
279     static_assert((int32_t)AudioFormat::I16 == AAUDIO_FORMAT_PCM_I16, ERRMSG);
280     static_assert((int32_t)AudioFormat::Float == AAUDIO_FORMAT_PCM_FLOAT, ERRMSG);
281 
282     static_assert((int32_t)DataCallbackResult::Continue == AAUDIO_CALLBACK_RESULT_CONTINUE, ERRMSG);
283     static_assert((int32_t)DataCallbackResult::Stop == AAUDIO_CALLBACK_RESULT_STOP, ERRMSG);
284 
285     static_assert((int32_t)Result::OK == AAUDIO_OK, ERRMSG);
286     static_assert((int32_t)Result::ErrorBase == AAUDIO_ERROR_BASE, ERRMSG);
287     static_assert((int32_t)Result::ErrorDisconnected == AAUDIO_ERROR_DISCONNECTED, ERRMSG);
288     static_assert((int32_t)Result::ErrorIllegalArgument == AAUDIO_ERROR_ILLEGAL_ARGUMENT, ERRMSG);
289     static_assert((int32_t)Result::ErrorInternal == AAUDIO_ERROR_INTERNAL, ERRMSG);
290     static_assert((int32_t)Result::ErrorInvalidState == AAUDIO_ERROR_INVALID_STATE, ERRMSG);
291     static_assert((int32_t)Result::ErrorInvalidHandle == AAUDIO_ERROR_INVALID_HANDLE, ERRMSG);
292     static_assert((int32_t)Result::ErrorUnimplemented == AAUDIO_ERROR_UNIMPLEMENTED, ERRMSG);
293     static_assert((int32_t)Result::ErrorUnavailable == AAUDIO_ERROR_UNAVAILABLE, ERRMSG);
294     static_assert((int32_t)Result::ErrorNoFreeHandles == AAUDIO_ERROR_NO_FREE_HANDLES, ERRMSG);
295     static_assert((int32_t)Result::ErrorNoMemory == AAUDIO_ERROR_NO_MEMORY, ERRMSG);
296     static_assert((int32_t)Result::ErrorNull == AAUDIO_ERROR_NULL, ERRMSG);
297     static_assert((int32_t)Result::ErrorTimeout == AAUDIO_ERROR_TIMEOUT, ERRMSG);
298     static_assert((int32_t)Result::ErrorWouldBlock == AAUDIO_ERROR_WOULD_BLOCK, ERRMSG);
299     static_assert((int32_t)Result::ErrorInvalidFormat == AAUDIO_ERROR_INVALID_FORMAT, ERRMSG);
300     static_assert((int32_t)Result::ErrorOutOfRange == AAUDIO_ERROR_OUT_OF_RANGE, ERRMSG);
301     static_assert((int32_t)Result::ErrorNoService == AAUDIO_ERROR_NO_SERVICE, ERRMSG);
302     static_assert((int32_t)Result::ErrorInvalidRate == AAUDIO_ERROR_INVALID_RATE, ERRMSG);
303 
304     static_assert((int32_t)SharingMode::Exclusive == AAUDIO_SHARING_MODE_EXCLUSIVE, ERRMSG);
305     static_assert((int32_t)SharingMode::Shared == AAUDIO_SHARING_MODE_SHARED, ERRMSG);
306 
307     static_assert((int32_t)PerformanceMode::None == AAUDIO_PERFORMANCE_MODE_NONE, ERRMSG);
308     static_assert((int32_t)PerformanceMode::PowerSaving
309             == AAUDIO_PERFORMANCE_MODE_POWER_SAVING, ERRMSG);
310     static_assert((int32_t)PerformanceMode::LowLatency
311             == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, ERRMSG);
312 
313 // The aaudio_ usage, content and input_preset types were added in NDK 17,
314 // which is the first version to support Android Pie (API 28).
315 #if __NDK_MAJOR__ >= 17
316 
317     ASSERT_INT32(aaudio_usage_t);
318     ASSERT_INT32(aaudio_content_type_t);
319     ASSERT_INT32(aaudio_input_preset_t);
320 
321     static_assert((int32_t)Usage::Media == AAUDIO_USAGE_MEDIA, ERRMSG);
322     static_assert((int32_t)Usage::VoiceCommunication == AAUDIO_USAGE_VOICE_COMMUNICATION, ERRMSG);
323     static_assert((int32_t)Usage::VoiceCommunicationSignalling
324             == AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING, ERRMSG);
325     static_assert((int32_t)Usage::Alarm == AAUDIO_USAGE_ALARM, ERRMSG);
326     static_assert((int32_t)Usage::Notification == AAUDIO_USAGE_NOTIFICATION, ERRMSG);
327     static_assert((int32_t)Usage::NotificationRingtone == AAUDIO_USAGE_NOTIFICATION_RINGTONE, ERRMSG);
328     static_assert((int32_t)Usage::NotificationEvent == AAUDIO_USAGE_NOTIFICATION_EVENT, ERRMSG);
329     static_assert((int32_t)Usage::AssistanceAccessibility == AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY, ERRMSG);
330     static_assert((int32_t)Usage::AssistanceNavigationGuidance
331             == AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, ERRMSG);
332     static_assert((int32_t)Usage::AssistanceSonification == AAUDIO_USAGE_ASSISTANCE_SONIFICATION, ERRMSG);
333     static_assert((int32_t)Usage::Game == AAUDIO_USAGE_GAME, ERRMSG);
334     static_assert((int32_t)Usage::Assistant == AAUDIO_USAGE_ASSISTANT, ERRMSG);
335 
336     static_assert((int32_t)ContentType::Speech == AAUDIO_CONTENT_TYPE_SPEECH, ERRMSG);
337     static_assert((int32_t)ContentType::Music == AAUDIO_CONTENT_TYPE_MUSIC, ERRMSG);
338     static_assert((int32_t)ContentType::Movie == AAUDIO_CONTENT_TYPE_MOVIE, ERRMSG);
339     static_assert((int32_t)ContentType::Sonification == AAUDIO_CONTENT_TYPE_SONIFICATION, ERRMSG);
340 
341     static_assert((int32_t)InputPreset::Generic == AAUDIO_INPUT_PRESET_GENERIC, ERRMSG);
342     static_assert((int32_t)InputPreset::Camcorder == AAUDIO_INPUT_PRESET_CAMCORDER, ERRMSG);
343     static_assert((int32_t)InputPreset::VoiceRecognition == AAUDIO_INPUT_PRESET_VOICE_RECOGNITION, ERRMSG);
344     static_assert((int32_t)InputPreset::VoiceCommunication
345             == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION, ERRMSG);
346     static_assert((int32_t)InputPreset::Unprocessed == AAUDIO_INPUT_PRESET_UNPROCESSED, ERRMSG);
347 
348     static_assert((int32_t)SessionId::None == AAUDIO_SESSION_ID_NONE, ERRMSG);
349     static_assert((int32_t)SessionId::Allocate == AAUDIO_SESSION_ID_ALLOCATE, ERRMSG);
350 
351 #endif // __NDK_MAJOR__ >= 17
352 
353 #endif // AAUDIO_AAUDIO_H
354 
355 } // namespace oboe
356