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 "lb2/oboe/src/aaudio/AAudioLoader.h"
18 
19 #include <dlfcn.h>
20 
21 #include "lb2/logging.h"
22 
23 #define LIB_AAUDIO_NAME "libaaudio.so"
24 
~AAudioLoader()25 AAudioLoader::~AAudioLoader() {
26     close(); // TODO dangerous from a destructor, require caller to close()
27 }
28 
getInstance()29 AAudioLoader* AAudioLoader::getInstance() {
30     static AAudioLoader instance;
31     return &instance;
32 }
33 
open()34 int AAudioLoader::open() {
35     if (mLibHandle != nullptr) {
36         return 0;
37     }
38     mLibHandle = dlopen(LIB_AAUDIO_NAME, 0);
39     if (mLibHandle == nullptr) {
40         ALOGI("AAudioLoader::open() could not find " LIB_AAUDIO_NAME);
41         return -1; // TODO review return code
42     } else {
43         ALOGD("AAudioLoader():  dlopen(%s) returned %p", LIB_AAUDIO_NAME, mLibHandle);
44     }
45 
46     // Load all the function pointers.
47     createStreamBuilder = (aaudio_result_t (*)(AAudioStreamBuilder **builder))
48             dlsym(mLibHandle, "AAudio_createStreamBuilder");
49 
50     builder_openStream = (aaudio_result_t (*)(AAudioStreamBuilder *builder,
51                                               AAudioStream **stream))
52             dlsym(mLibHandle, "AAudioStreamBuilder_openStream");
53 
54     builder_setChannelCount    = load_V_PBI("AAudioStreamBuilder_setChannelCount");
55     if (builder_setChannelCount == nullptr) {
56         // Use old alias if needed.
57         builder_setChannelCount    = load_V_PBI("AAudioStreamBuilder_setSamplesPerFrame");
58     }
59 
60     builder_setBufferCapacityInFrames = load_V_PBI("AAudioStreamBuilder_setBufferCapacityInFrames");
61     builder_setDeviceId        = load_V_PBI("AAudioStreamBuilder_setDeviceId");
62     builder_setDirection       = load_V_PBI("AAudioStreamBuilder_setDirection");
63     builder_setFormat          = load_V_PBI("AAudioStreamBuilder_setFormat");
64     builder_setFramesPerDataCallback = load_V_PBI("AAudioStreamBuilder_setFramesPerDataCallback");
65     builder_setSharingMode     = load_V_PBI("AAudioStreamBuilder_setSharingMode");
66     builder_setPerformanceMode     = load_V_PBI("AAudioStreamBuilder_setPerformanceMode");
67     builder_setSampleRate      = load_V_PBI("AAudioStreamBuilder_setSampleRate");
68 
69     builder_delete             = load_I_PB("AAudioStreamBuilder_delete");
70 
71     stream_getFormat = (aaudio_format_t (*)(AAudioStream *stream))
72             dlsym(mLibHandle, "AAudioStream_getFormat");
73 
74     builder_setDataCallback = (void (*)(AAudioStreamBuilder *builder,
75                                         AAudioStream_dataCallback callback,
76                                         void *userData))
77             dlsym(mLibHandle, "AAudioStreamBuilder_setDataCallback");
78 
79     builder_setErrorCallback = (void (*)(AAudioStreamBuilder *builder,
80                                         AAudioStream_errorCallback callback,
81                                         void *userData))
82             dlsym(mLibHandle, "AAudioStreamBuilder_setErrorCallback");
83 
84     stream_read = (aaudio_result_t (*)(AAudioStream *stream,
85                                        void *buffer,
86                                        int32_t numFrames,
87                                        int64_t timeoutNanoseconds))
88             dlsym(mLibHandle, "AAudioStream_read");
89 
90     stream_write = (aaudio_result_t (*)(AAudioStream *stream,
91                                         const void *buffer,
92                                         int32_t numFrames,
93                                         int64_t timeoutNanoseconds))
94             dlsym(mLibHandle, "AAudioStream_write");
95 
96 
97     stream_waitForStateChange = (aaudio_result_t (*)(AAudioStream *stream,
98                                                  aaudio_stream_state_t inputState,
99                                                  aaudio_stream_state_t *nextState,
100                                                  int64_t timeoutNanoseconds))
101             dlsym(mLibHandle, "AAudioStream_waitForStateChange");
102 
103 
104     stream_getTimestamp = (aaudio_result_t (*)(AAudioStream *stream,
105                                            clockid_t clockid,
106                                            int64_t *framePosition,
107                                            int64_t *timeNanoseconds))
108             dlsym(mLibHandle, "AAudioStream_getTimestamp");
109 
110     stream_getChannelCount    = load_I_PS("AAudioStream_getChannelCount");
111     if (stream_getChannelCount == nullptr) {
112         // Use old alias if needed.
113         stream_getChannelCount    = load_I_PS("AAudioStream_getSamplesPerFrame");
114     }
115 
116     stream_close              = load_I_PS("AAudioStream_close");
117 
118     stream_getBufferSize      = load_I_PS("AAudioStream_getBufferSizeInFrames");
119     stream_getDeviceId        = load_I_PS("AAudioStream_getDeviceId");
120     stream_getDirection       = load_I_PS("AAudioStream_getDirection");
121     stream_getBufferCapacity  = load_I_PS("AAudioStream_getBufferCapacityInFrames");
122     stream_getFramesPerBurst  = load_I_PS("AAudioStream_getFramesPerBurst");
123     stream_getFramesRead      = load_L_PS("AAudioStream_getFramesRead");
124     stream_getFramesWritten   = load_L_PS("AAudioStream_getFramesWritten");
125     stream_getPerformanceMode = load_I_PS("AAudioStream_getPerformanceMode");
126     stream_getSampleRate      = load_I_PS("AAudioStream_getSampleRate");
127     stream_getSharingMode     = load_I_PS("AAudioStream_getSharingMode");
128     stream_getState           = load_I_PS("AAudioStream_getState");
129     stream_getXRunCount       = load_I_PS("AAudioStream_getXRunCount");
130 
131     stream_requestStart       = load_I_PS("AAudioStream_requestStart");
132     stream_requestPause       = load_I_PS("AAudioStream_requestPause");
133     stream_requestFlush       = load_I_PS("AAudioStream_requestFlush");
134     stream_requestStop        = load_I_PS("AAudioStream_requestStop");
135 
136     stream_setBufferSize      = load_I_PSI("AAudioStream_setBufferSizeInFrames");
137 
138     convertResultToText       = load_PC_I("AAudio_convertResultToText");
139     convertStreamStateToText  = load_PC_I("AAudio_convertStreamStateToText");
140 
141     return 0;
142 }
143 
close()144 int AAudioLoader::close() {
145     if (mLibHandle != nullptr) {
146         dlclose(mLibHandle);
147         mLibHandle = nullptr;
148     }
149     return 0;
150 }
151 
AAudioLoader_check(void * proc,const char * functionName)152 static void AAudioLoader_check(void *proc, const char *functionName) {
153     if (proc == nullptr) {
154         ALOGE("AAudioLoader could not find %s", functionName);
155     } else {
156         ALOGV("AAudioLoader(): dlsym(%s) succeeded.", functionName);
157     }
158 }
159 
load_PC_I(const char * functionName)160 AAudioLoader::signature_PC_I AAudioLoader::load_PC_I(const char *functionName) {
161     signature_PC_I proc = (signature_PC_I) dlsym(mLibHandle, functionName);
162     AAudioLoader_check((void *)proc, functionName);
163     return proc;
164 }
165 
load_V_PBI(const char * functionName)166 AAudioLoader::signature_V_PBI AAudioLoader::load_V_PBI(const char *functionName) {
167     signature_V_PBI proc = (signature_V_PBI) dlsym(mLibHandle, functionName);
168     AAudioLoader_check((void *)proc, functionName);
169     return proc;
170 }
171 
load_I_PSI(const char * functionName)172 AAudioLoader::signature_I_PSI AAudioLoader::load_I_PSI(const char *functionName) {
173     signature_I_PSI proc = (signature_I_PSI) dlsym(mLibHandle, functionName);
174     AAudioLoader_check((void *)proc, functionName);
175     return proc;
176 }
177 
load_I_PS(const char * functionName)178 AAudioLoader::signature_I_PS AAudioLoader::load_I_PS(const char *functionName) {
179     signature_I_PS proc = (signature_I_PS) dlsym(mLibHandle, functionName);
180     AAudioLoader_check((void *)proc, functionName);
181     return proc;
182 }
183 
load_L_PS(const char * functionName)184 AAudioLoader::signature_L_PS AAudioLoader::load_L_PS(const char *functionName) {
185     signature_L_PS proc = (signature_L_PS) dlsym(mLibHandle, functionName);
186     AAudioLoader_check((void *)proc, functionName);
187     return proc;
188 }
189 
load_I_PB(const char * functionName)190 AAudioLoader::signature_I_PB AAudioLoader::load_I_PB(const char *functionName) {
191     signature_I_PB proc = (signature_I_PB) dlsym(mLibHandle, functionName);
192     AAudioLoader_check((void *)proc, functionName);
193     return proc;
194 }
195