1 /*
2  * Copyright (C) 2010 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 "sles_allinclusive.h"
18 #include "android_prompts.h"
19 #include "channels.h"
20 
21 #include <utils/String16.h>
22 
23 #include <system/audio.h>
24 #include <SLES/OpenSLES_Android.h>
25 
26 #include <android_runtime/AndroidRuntime.h>
27 #include <android/AudioRecordCallback.h>
28 
29 #define KEY_RECORDING_SOURCE_PARAMSIZE  sizeof(SLuint32)
30 #define KEY_RECORDING_PRESET_PARAMSIZE  sizeof(SLuint32)
31 #define KEY_PERFORMANCE_MODE_PARAMSIZE  sizeof(SLuint32)
32 
33 using android::content::AttributionSourceState;
34 
35 //-----------------------------------------------------------------------------
36 // Internal utility functions
37 //----------------------------
38 
audioRecorder_setPreset(CAudioRecorder * ar,SLuint32 recordPreset)39 SLresult audioRecorder_setPreset(CAudioRecorder* ar, SLuint32 recordPreset) {
40     SLresult result = SL_RESULT_SUCCESS;
41 
42     audio_source_t newRecordSource = AUDIO_SOURCE_DEFAULT;
43     switch (recordPreset) {
44     case SL_ANDROID_RECORDING_PRESET_GENERIC:
45         newRecordSource = AUDIO_SOURCE_DEFAULT;
46         break;
47     case SL_ANDROID_RECORDING_PRESET_CAMCORDER:
48         newRecordSource = AUDIO_SOURCE_CAMCORDER;
49         break;
50     case SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION:
51         newRecordSource = AUDIO_SOURCE_VOICE_RECOGNITION;
52         break;
53     case SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION:
54         newRecordSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
55         break;
56     case SL_ANDROID_RECORDING_PRESET_UNPROCESSED:
57             newRecordSource = AUDIO_SOURCE_UNPROCESSED;
58             break;
59     case SL_ANDROID_RECORDING_PRESET_NONE:
60         // it is an error to set preset "none"
61     default:
62         SL_LOGE(ERROR_RECORDERPRESET_SET_UNKNOWN_PRESET);
63         result = SL_RESULT_PARAMETER_INVALID;
64     }
65 
66     // recording preset needs to be set before the object is realized
67     // (ap->mAudioRecord is supposed to be 0 until then)
68     if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) {
69         SL_LOGE(ERROR_RECORDERPRESET_REALIZED);
70         result = SL_RESULT_PRECONDITIONS_VIOLATED;
71     } else {
72         ar->mRecordSource = newRecordSource;
73     }
74 
75     return result;
76 }
77 
78 
79 //-----------------------------------------------------------------------------
audioRecorder_setPerformanceMode(CAudioRecorder * ar,SLuint32 mode)80 SLresult audioRecorder_setPerformanceMode(CAudioRecorder* ar, SLuint32 mode) {
81     SLresult result = SL_RESULT_SUCCESS;
82     SL_LOGV("performance mode set to %d", mode);
83 
84     SLuint32 perfMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
85     switch (mode) {
86     case SL_ANDROID_PERFORMANCE_LATENCY:
87         perfMode = ANDROID_PERFORMANCE_MODE_LATENCY;
88         break;
89     case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS:
90         perfMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
91         break;
92     case SL_ANDROID_PERFORMANCE_NONE:
93         perfMode = ANDROID_PERFORMANCE_MODE_NONE;
94         break;
95     case SL_ANDROID_PERFORMANCE_POWER_SAVING:
96         perfMode = ANDROID_PERFORMANCE_MODE_POWER_SAVING;
97         break;
98     default:
99         SL_LOGE(ERROR_CONFIG_PERF_MODE_UNKNOWN);
100         result = SL_RESULT_PARAMETER_INVALID;
101         break;
102     }
103 
104     // performance mode needs to be set before the object is realized
105     // (ar->mAudioRecord is supposed to be NULL until then)
106     if (SL_OBJECT_STATE_UNREALIZED != ar->mObject.mState) {
107         SL_LOGE(ERROR_CONFIG_PERF_MODE_REALIZED);
108         result = SL_RESULT_PRECONDITIONS_VIOLATED;
109     } else {
110         ar->mPerformanceMode = perfMode;
111     }
112 
113     return result;
114 }
115 
116 
audioRecorder_getPreset(CAudioRecorder * ar,SLuint32 * pPreset)117 SLresult audioRecorder_getPreset(CAudioRecorder* ar, SLuint32* pPreset) {
118     SLresult result = SL_RESULT_SUCCESS;
119 
120     switch (ar->mRecordSource) {
121     case AUDIO_SOURCE_DEFAULT:
122     case AUDIO_SOURCE_MIC:
123         *pPreset = SL_ANDROID_RECORDING_PRESET_GENERIC;
124         break;
125     case AUDIO_SOURCE_VOICE_UPLINK:
126     case AUDIO_SOURCE_VOICE_DOWNLINK:
127     case AUDIO_SOURCE_VOICE_CALL:
128         *pPreset = SL_ANDROID_RECORDING_PRESET_NONE;
129         break;
130     case AUDIO_SOURCE_VOICE_RECOGNITION:
131         *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
132         break;
133     case AUDIO_SOURCE_CAMCORDER:
134         *pPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER;
135         break;
136     case AUDIO_SOURCE_VOICE_COMMUNICATION:
137         *pPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION;
138         break;
139     case AUDIO_SOURCE_UNPROCESSED:
140         *pPreset = SL_ANDROID_RECORDING_PRESET_UNPROCESSED;
141         break;
142     default:
143         *pPreset = SL_ANDROID_RECORDING_PRESET_NONE;
144         result = SL_RESULT_INTERNAL_ERROR;
145         break;
146     }
147 
148     return result;
149 }
150 
151 
152 //-----------------------------------------------------------------------------
audioRecorder_getPerformanceMode(CAudioRecorder * ar,SLuint32 * pMode)153 SLresult audioRecorder_getPerformanceMode(CAudioRecorder* ar, SLuint32 *pMode) {
154     SLresult result = SL_RESULT_SUCCESS;
155 
156     switch (ar->mPerformanceMode) {
157     case ANDROID_PERFORMANCE_MODE_LATENCY:
158         *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
159         break;
160     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
161         *pMode = SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS;
162         break;
163     case ANDROID_PERFORMANCE_MODE_NONE:
164         *pMode = SL_ANDROID_PERFORMANCE_NONE;
165         break;
166     case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
167         *pMode = SL_ANDROID_PERFORMANCE_POWER_SAVING;
168         break;
169     default:
170         result = SL_RESULT_INTERNAL_ERROR;
171         *pMode = SL_ANDROID_PERFORMANCE_LATENCY;
172         break;
173     }
174 
175     return result;
176 }
177 
178 
audioRecorder_handleNewPos_lockRecord(CAudioRecorder * ar)179 void audioRecorder_handleNewPos_lockRecord(CAudioRecorder* ar) {
180     //SL_LOGV("received event EVENT_NEW_POS from AudioRecord");
181     slRecordCallback callback = NULL;
182     void* callbackPContext = NULL;
183 
184     interface_lock_shared(&ar->mRecord);
185     callback = ar->mRecord.mCallback;
186     callbackPContext = ar->mRecord.mContext;
187     interface_unlock_shared(&ar->mRecord);
188 
189     if (NULL != callback) {
190         // getting this event implies SL_RECORDEVENT_HEADATNEWPOS was set in the event mask
191         (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATNEWPOS);
192     }
193 }
194 
195 
audioRecorder_handleMarker_lockRecord(CAudioRecorder * ar)196 void audioRecorder_handleMarker_lockRecord(CAudioRecorder* ar) {
197     //SL_LOGV("received event EVENT_MARKER from AudioRecord");
198     slRecordCallback callback = NULL;
199     void* callbackPContext = NULL;
200 
201     interface_lock_shared(&ar->mRecord);
202     callback = ar->mRecord.mCallback;
203     callbackPContext = ar->mRecord.mContext;
204     interface_unlock_shared(&ar->mRecord);
205 
206     if (NULL != callback) {
207         // getting this event implies SL_RECORDEVENT_HEADATMARKER was set in the event mask
208         (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADATMARKER);
209     }
210 }
211 
212 
audioRecorder_handleOverrun_lockRecord(CAudioRecorder * ar)213 void audioRecorder_handleOverrun_lockRecord(CAudioRecorder* ar) {
214     //SL_LOGV("received event EVENT_OVERRUN from AudioRecord");
215     slRecordCallback callback = NULL;
216     void* callbackPContext = NULL;
217 
218     interface_lock_shared(&ar->mRecord);
219     if (ar->mRecord.mCallbackEventsMask & SL_RECORDEVENT_HEADSTALLED) {
220         callback = ar->mRecord.mCallback;
221         callbackPContext = ar->mRecord.mContext;
222     }
223     interface_unlock_shared(&ar->mRecord);
224 
225     if (NULL != callback) {
226         (*callback)(&ar->mRecord.mItf, callbackPContext, SL_RECORDEVENT_HEADSTALLED);
227     }
228 }
229 
230 //-----------------------------------------------------------------------------
android_audioRecorder_checkSourceSink(CAudioRecorder * ar)231 SLresult android_audioRecorder_checkSourceSink(CAudioRecorder* ar) {
232 
233     const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource;
234     const SLDataSink   *pAudioSnk = &ar->mDataSink.u.mSink;
235 
236     const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
237     const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat;
238 
239     // sink must be an Android simple buffer queue with PCM data format
240     switch (sinkLocatorType) {
241     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: {
242         switch (sinkFormatType) {
243         case SL_ANDROID_DATAFORMAT_PCM_EX: {
244             // checkDataFormat() already checked representation
245         } // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
246             FALLTHROUGH_INTENDED;
247         case SL_DATAFORMAT_PCM: {
248             const SLDataFormat_PCM *df_pcm = (const SLDataFormat_PCM *) pAudioSnk->pFormat;
249             // checkDataFormat already checked sample rate, channels, and mask
250             ar->mNumChannels = df_pcm->numChannels;
251 
252             if (df_pcm->endianness != ar->mObject.mEngine->mEngine.mNativeEndianness) {
253                 SL_LOGE("Cannot create audio recorder: unsupported byte order %u",
254                         df_pcm->endianness);
255                 return SL_RESULT_CONTENT_UNSUPPORTED;
256             }
257 
258             ar->mSampleRateMilliHz = df_pcm->samplesPerSec; // Note: bad field name in SL ES
259             SL_LOGV("AudioRecorder requested sample rate = %u mHz, %u channel(s)",
260                     ar->mSampleRateMilliHz, ar->mNumChannels);
261 
262             // we don't support container size != sample depth
263             if (df_pcm->containerSize != df_pcm->bitsPerSample) {
264                 SL_LOGE("Cannot create audio recorder: unsupported container size %u bits for "
265                         "sample depth %u bits",
266                         df_pcm->containerSize, (SLuint32)df_pcm->bitsPerSample);
267                 return SL_RESULT_CONTENT_UNSUPPORTED;
268             }
269 
270             } break;
271         default:
272             SL_LOGE(ERROR_RECORDER_SINK_FORMAT_MUST_BE_PCM);
273             return SL_RESULT_PARAMETER_INVALID;
274         }   // switch (sourceFormatType)
275         } break;    // case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
276     default:
277         SL_LOGE(ERROR_RECORDER_SINK_MUST_BE_ANDROIDSIMPLEBUFFERQUEUE);
278         return SL_RESULT_PARAMETER_INVALID;
279     }   // switch (sourceLocatorType)
280 
281     // Source check:
282     // only input device sources are supported
283     // check it's an IO device
284     if (SL_DATALOCATOR_IODEVICE != *(SLuint32 *)pAudioSrc->pLocator) {
285         SL_LOGE(ERROR_RECORDER_SOURCE_MUST_BE_IODEVICE);
286         return SL_RESULT_PARAMETER_INVALID;
287     } else {
288 
289         // check it's an input device
290         SLDataLocator_IODevice *dl_iod = (SLDataLocator_IODevice *) pAudioSrc->pLocator;
291         if (SL_IODEVICE_AUDIOINPUT != dl_iod->deviceType) {
292             SL_LOGE(ERROR_RECORDER_IODEVICE_MUST_BE_AUDIOINPUT);
293             return SL_RESULT_PARAMETER_INVALID;
294         }
295 
296         // check it's the default input device, others aren't supported here
297         if (SL_DEFAULTDEVICEID_AUDIOINPUT != dl_iod->deviceID) {
298             SL_LOGE(ERROR_RECORDER_INPUT_ID_MUST_BE_DEFAULT);
299             return SL_RESULT_PARAMETER_INVALID;
300         }
301     }
302 
303     return SL_RESULT_SUCCESS;
304 }
305 //-----------------------------------------------------------------------------
audioRecorder_handleMoreData_lockRecord(CAudioRecorder * ar,const android::AudioRecord::Buffer & buffer)306 size_t audioRecorder_handleMoreData_lockRecord(CAudioRecorder* ar,
307                                                const android::AudioRecord::Buffer& buffer) {
308     //SL_LOGV("audioRecorder_callback(%d, %p, %p) entering", event, user, info);
309 
310     void * callbackPContext = NULL;
311     size_t bytesRead = 0;
312     slBufferQueueCallback callback = NULL;
313 
314     // push data to the buffer queue
315     interface_lock_exclusive(&ar->mBufferQueue);
316 
317     if (ar->mBufferQueue.mState.count != 0) {
318         assert(ar->mBufferQueue.mFront != ar->mBufferQueue.mRear);
319 
320         BufferHeader *oldFront = ar->mBufferQueue.mFront;
321         BufferHeader *newFront = &oldFront[1];
322 
323         size_t availSink = oldFront->mSize - ar->mBufferQueue.mSizeConsumed;
324         size_t availSource = buffer.size();
325         size_t bytesToCopy = availSink < availSource ? availSink : availSource;
326         void *pDest = (char *)oldFront->mBuffer + ar->mBufferQueue.mSizeConsumed;
327         memcpy(pDest, buffer.data(), bytesToCopy);
328         bytesRead = bytesToCopy;
329         if (bytesToCopy < availSink) {
330             // can't consume the whole or rest of the buffer in one shot
331             ar->mBufferQueue.mSizeConsumed += availSource;
332         } else {
333             // finish pushing the buffer or push the buffer in one shot
334             ar->mBufferQueue.mSizeConsumed = 0;
335             if (newFront == &ar->mBufferQueue.mArray[ar->mBufferQueue.mNumBuffers + 1]) {
336                 newFront = ar->mBufferQueue.mArray;
337             }
338             ar->mBufferQueue.mFront = newFront;
339 
340             ar->mBufferQueue.mState.count--;
341             ar->mBufferQueue.mState.playIndex++;
342 
343             // data has been copied to the buffer, and the buffer queue state has been updated
344             // we will notify the client if applicable
345             callback = ar->mBufferQueue.mCallback;
346             // save callback data
347             callbackPContext = ar->mBufferQueue.mContext;
348         }
349     }
350 
351     interface_unlock_exclusive(&ar->mBufferQueue);
352 
353     // notify client
354     if (NULL != callback) {
355         (*callback)(&ar->mBufferQueue.mItf, callbackPContext);
356     }
357     return bytesRead;
358 }
359 
360 
361 //-----------------------------------------------------------------------------
android_audioRecorder_create(CAudioRecorder * ar)362 SLresult android_audioRecorder_create(CAudioRecorder* ar) {
363     SL_LOGV("android_audioRecorder_create(%p) entering", ar);
364 
365     const SLDataSource *pAudioSrc = &ar->mDataSource.u.mSource;
366     const SLDataSink *pAudioSnk = &ar->mDataSink.u.mSink;
367     SLresult result = SL_RESULT_SUCCESS;
368 
369     const SLuint32 sourceLocatorType = *(SLuint32 *)pAudioSrc->pLocator;
370     const SLuint32 sinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
371 
372     //  the following platform-independent fields have been initialized in CreateAudioRecorder()
373     //    ar->mNumChannels
374     //    ar->mSampleRateMilliHz
375 
376     if ((SL_DATALOCATOR_IODEVICE == sourceLocatorType) &&
377             (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE == sinkLocatorType)) {
378         // microphone to simple buffer queue
379         ar->mAndroidObjType = AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE;
380         ar->mAudioRecord.clear();
381         ar->mCallbackHandle.clear();
382         ar->mCallbackProtector = new android::CallbackProtector();
383         ar->mRecordSource = AUDIO_SOURCE_DEFAULT;
384         ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_DEFAULT;
385     } else {
386         result = SL_RESULT_CONTENT_UNSUPPORTED;
387     }
388 
389     return result;
390 }
391 
392 
393 //-----------------------------------------------------------------------------
android_audioRecorder_setConfig(CAudioRecorder * ar,const SLchar * configKey,const void * pConfigValue,SLuint32 valueSize)394 SLresult android_audioRecorder_setConfig(CAudioRecorder* ar, const SLchar *configKey,
395         const void *pConfigValue, SLuint32 valueSize) {
396 
397     SLresult result;
398 
399     assert(NULL != ar && NULL != configKey && NULL != pConfigValue);
400     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) {
401 
402         // recording preset
403         if (KEY_RECORDING_PRESET_PARAMSIZE > valueSize) {
404             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
405             result = SL_RESULT_BUFFER_INSUFFICIENT;
406         } else {
407             result = audioRecorder_setPreset(ar, *(SLuint32*)pConfigValue);
408         }
409 
410     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
411 
412         // performance mode
413         if (KEY_PERFORMANCE_MODE_PARAMSIZE > valueSize) {
414             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
415             result = SL_RESULT_BUFFER_INSUFFICIENT;
416         } else {
417             result = audioRecorder_setPerformanceMode(ar, *(SLuint32*)pConfigValue);
418         }
419     } else {
420         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
421         result = SL_RESULT_PARAMETER_INVALID;
422     }
423 
424     return result;
425 }
426 
427 
428 //-----------------------------------------------------------------------------
android_audioRecorder_getConfig(CAudioRecorder * ar,const SLchar * configKey,SLuint32 * pValueSize,void * pConfigValue)429 SLresult android_audioRecorder_getConfig(CAudioRecorder* ar, const SLchar *configKey,
430         SLuint32* pValueSize, void *pConfigValue) {
431 
432     SLresult result;
433 
434     assert(NULL != ar && NULL != configKey && NULL != pValueSize);
435     if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_RECORDING_PRESET) == 0) {
436 
437         // recording preset
438         if (NULL == pConfigValue) {
439             result = SL_RESULT_SUCCESS;
440         } else if (KEY_RECORDING_PRESET_PARAMSIZE > *pValueSize) {
441             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
442             result = SL_RESULT_BUFFER_INSUFFICIENT;
443         } else {
444             result = audioRecorder_getPreset(ar, (SLuint32*)pConfigValue);
445         }
446         *pValueSize = KEY_RECORDING_PRESET_PARAMSIZE;
447 
448     } else if (strcmp((const char*)configKey, (const char*)SL_ANDROID_KEY_PERFORMANCE_MODE) == 0) {
449 
450         // performance mode
451         if (NULL == pConfigValue) {
452             result = SL_RESULT_SUCCESS;
453         } else if (KEY_PERFORMANCE_MODE_PARAMSIZE > *pValueSize) {
454             SL_LOGE(ERROR_CONFIG_VALUESIZE_TOO_LOW);
455             result = SL_RESULT_BUFFER_INSUFFICIENT;
456         } else {
457             result = audioRecorder_getPerformanceMode(ar, (SLuint32*)pConfigValue);
458         }
459         *pValueSize = KEY_PERFORMANCE_MODE_PARAMSIZE;
460 
461     } else {
462         SL_LOGE(ERROR_CONFIG_UNKNOWN_KEY);
463         result = SL_RESULT_PARAMETER_INVALID;
464     }
465 
466     return result;
467 }
468 
469 // Called from android_audioRecorder_realize for a PCM buffer queue recorder before creating the
470 // AudioRecord to determine which performance modes are allowed based on effect interfaces present
checkAndSetPerformanceModePre(CAudioRecorder * ar)471 static void checkAndSetPerformanceModePre(CAudioRecorder* ar)
472 {
473     SLuint32 allowedModes = ANDROID_PERFORMANCE_MODE_ALL;
474     assert(ar->mAndroidObjType == AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE);
475 
476     // no need to check the buffer queue size, application side
477     // double-buffering (and more) is not a requirement for using fast tracks
478 
479     // Check a denylist of interfaces that are incompatible with fast tracks.
480     // The alternative, to check a allowlist of compatible interfaces, is
481     // more maintainable but is too slow.  As a compromise, in a debug build
482     // we use both methods and warn if they produce different results.
483     // In release builds, we only use the denylist method.
484     // If a denylisted interface is added after realization using
485     // DynamicInterfaceManagement::AddInterface,
486     // then this won't be detected but the interface will be ineffective.
487     static const unsigned denylist[] = {
488         MPH_ANDROIDACOUSTICECHOCANCELLATION,
489         MPH_ANDROIDAUTOMATICGAINCONTROL,
490         MPH_ANDROIDNOISESUPPRESSION,
491         MPH_ANDROIDEFFECT,
492         // FIXME The problem with a denylist is remembering to add new interfaces here
493     };
494 
495     for (unsigned i = 0; i < sizeof(denylist)/sizeof(denylist[0]); ++i) {
496         if (IsInterfaceInitialized(&ar->mObject, denylist[i])) {
497             uint32_t flags = 0;
498 
499             allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY;
500 
501             // if generic effect interface is used we don't know which effect will be used and
502             // disable all low latency performance modes
503             if (denylist[i] != MPH_ANDROIDEFFECT) {
504                 switch (denylist[i]) {
505                 case MPH_ANDROIDACOUSTICECHOCANCELLATION:
506                     SL_LOGV("checkAndSetPerformanceModePre found AEC name %s",
507                             ar->mAcousticEchoCancellation.mAECDescriptor.name);
508                     flags = ar->mAcousticEchoCancellation.mAECDescriptor.flags;
509                     break;
510                 case MPH_ANDROIDAUTOMATICGAINCONTROL:
511                     SL_LOGV("checkAndSetPerformanceModePre found AGC name %s",
512                             ar->mAutomaticGainControl.mAGCDescriptor.name);
513                     flags = ar->mAutomaticGainControl.mAGCDescriptor.flags;
514                     break;
515                 case MPH_ANDROIDNOISESUPPRESSION:
516                     SL_LOGV("checkAndSetPerformanceModePre found NS name %s",
517                             ar->mNoiseSuppression.mNSDescriptor.name);
518                     flags = ar->mNoiseSuppression.mNSDescriptor.flags;
519                     break;
520                 default:
521                     break;
522                 }
523             }
524             if ((flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) {
525                 allowedModes &= ~ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
526                 break;
527             }
528         }
529     }
530 #if LOG_NDEBUG == 0
531     bool denylistResult = (
532             (allowedModes &
533                 (ANDROID_PERFORMANCE_MODE_LATENCY|ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS)) != 0);
534     bool allowlistResult = true;
535     static const unsigned allowlist[] = {
536         MPH_BUFFERQUEUE,
537         MPH_DYNAMICINTERFACEMANAGEMENT,
538         MPH_OBJECT,
539         MPH_RECORD,
540         MPH_ANDROIDCONFIGURATION,
541         MPH_ANDROIDSIMPLEBUFFERQUEUE,
542     };
543     for (unsigned mph = MPH_MIN; mph < MPH_MAX; ++mph) {
544         for (unsigned i = 0; i < sizeof(allowlist)/sizeof(allowlist[0]); ++i) {
545             if (mph == allowlist[i]) {
546                 goto compatible;
547             }
548         }
549         if (IsInterfaceInitialized(&ar->mObject, mph)) {
550             allowlistResult = false;
551             break;
552         }
553 compatible: ;
554     }
555     if (allowlistResult != denylistResult) {
556         SL_LOGW("allowlistResult != denylistResult");
557     }
558 #endif
559     if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY) {
560         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY) == 0) {
561             ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
562         }
563     }
564     if (ar->mPerformanceMode == ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) {
565         if ((allowedModes & ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) == 0) {
566             ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
567         }
568     }
569 }
570 
571 // Called from android_audioRecorder_realize for a PCM buffer queue recorder after creating the
572 // AudioRecord to adjust performance mode based on actual input flags
checkAndSetPerformanceModePost(CAudioRecorder * ar)573 static void checkAndSetPerformanceModePost(CAudioRecorder* ar)
574 {
575     audio_input_flags_t flags = ar->mAudioRecord->getFlags();
576     switch (ar->mPerformanceMode) {
577     case ANDROID_PERFORMANCE_MODE_LATENCY:
578         if ((flags & (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) ==
579                 (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)) {
580             break;
581         }
582         ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS;
583         FALLTHROUGH_INTENDED;
584     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
585         if ((flags & AUDIO_INPUT_FLAG_FAST) == 0) {
586             ar->mPerformanceMode = ANDROID_PERFORMANCE_MODE_NONE;
587         }
588         break;
589     case ANDROID_PERFORMANCE_MODE_NONE:
590     default:
591         break;
592     }
593 }
594 //-----------------------------------------------------------------------------
android_audioRecorder_realize(CAudioRecorder * ar,SLboolean async)595 SLresult android_audioRecorder_realize(CAudioRecorder* ar, SLboolean async) {
596     SL_LOGV("android_audioRecorder_realize(%p) entering", ar);
597 
598     SLresult result = SL_RESULT_SUCCESS;
599 
600     // already checked in created and checkSourceSink
601     assert(ar->mDataSink.mLocator.mLocatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE);
602 
603     const SLDataFormat_PCM *df_pcm = &ar->mDataSink.mFormat.mPCM;
604 
605     //  the following platform-independent fields have been initialized in CreateAudioRecorder()
606     //    ar->mNumChannels
607     //    ar->mSampleRateMilliHz
608 
609     uint32_t sampleRate = sles_to_android_sampleRate(df_pcm->samplesPerSec);
610 
611     checkAndSetPerformanceModePre(ar);
612 
613     audio_input_flags_t policy;
614     switch (ar->mPerformanceMode) {
615     case ANDROID_PERFORMANCE_MODE_NONE:
616     case ANDROID_PERFORMANCE_MODE_POWER_SAVING:
617         policy = AUDIO_INPUT_FLAG_NONE;
618         break;
619     case ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS:
620         policy = AUDIO_INPUT_FLAG_FAST;
621         break;
622     case ANDROID_PERFORMANCE_MODE_LATENCY:
623     default:
624         policy = (audio_input_flags_t)(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW);
625         break;
626     }
627 
628     SL_LOGV("Audio Record format: %dch(0x%x), %dbit, %dKHz",
629             df_pcm->numChannels,
630             df_pcm->channelMask,
631             df_pcm->bitsPerSample,
632             df_pcm->samplesPerSec / 1000000);
633 
634     // note that df_pcm->channelMask has already been validated during object creation.
635     audio_channel_mask_t channelMask = sles_to_audio_input_channel_mask(df_pcm->channelMask);
636 
637     // To maintain backward compatibility with previous releases, ignore
638     // channel masks that are not indexed.
639     if (channelMask == AUDIO_CHANNEL_INVALID
640             || audio_channel_mask_get_representation(channelMask)
641                 == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
642         channelMask = audio_channel_in_mask_from_count(df_pcm->numChannels);
643         SL_LOGI("Emulating old channel mask behavior "
644                 "(ignoring positional mask %#x, using default mask %#x based on "
645                 "channel count of %d)", df_pcm->channelMask, channelMask,
646                 df_pcm->numChannels);
647     }
648     SL_LOGV("SLES channel mask %#x converted to Android mask %#x", df_pcm->channelMask,
649             channelMask);
650 
651     // TODO b/182392769: use attribution source util
652     AttributionSourceState attributionSource;
653     attributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
654     attributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
655     attributionSource.token = android::sp<android::BBinder>::make();
656     ar->mCallbackHandle = android::sp<android::AudioRecordCallback>::make(ar);
657     // initialize platform-specific CAudioRecorder fields
658     ar->mAudioRecord = new android::AudioRecord(
659             ar->mRecordSource,     // source
660             sampleRate,            // sample rate in Hertz
661             sles_to_android_sampleFormat(df_pcm),               // format
662             channelMask,           // channel mask
663             attributionSource,
664             0,                     // frameCount
665             ar->mCallbackHandle,
666             0,                     // notificationFrames
667             AUDIO_SESSION_ALLOCATE,
668             android::AudioRecord::TRANSFER_CALLBACK,
669                                    // transfer type
670             policy);               // audio_input_flags_t
671 
672     // Set it here so it can be logged by the destructor if the open failed.
673     ar->mAudioRecord->setCallerName(ANDROID_OPENSLES_CALLER_NAME);
674 
675     android::status_t status = ar->mAudioRecord->initCheck();
676     if (android::NO_ERROR != status) {
677         SL_LOGE("android_audioRecorder_realize(%p) error creating AudioRecord object; status %d",
678                 ar, status);
679         // FIXME should return a more specific result depending on status
680         result = SL_RESULT_CONTENT_UNSUPPORTED;
681         ar->mAudioRecord.clear();
682         ar->mCallbackHandle.clear();
683         return result;
684     }
685 
686     // update performance mode according to actual flags granted to AudioRecord
687     checkAndSetPerformanceModePost(ar);
688 
689     // If there is a JavaAudioRoutingProxy associated with this recorder, hook it up...
690     JNIEnv* j_env = NULL;
691     jclass clsAudioRecord = NULL;
692     jmethodID midRoutingProxy_connect = NULL;
693     if (ar->mAndroidConfiguration.mRoutingProxy != NULL &&
694             (j_env = android::AndroidRuntime::getJNIEnv()) != NULL &&
695             (clsAudioRecord = j_env->FindClass("android/media/AudioRecord")) != NULL &&
696             (midRoutingProxy_connect =
697                 j_env->GetMethodID(clsAudioRecord, "deferred_connect", "(J)V")) != NULL) {
698         j_env->ExceptionClear();
699         j_env->CallVoidMethod(ar->mAndroidConfiguration.mRoutingProxy,
700                               midRoutingProxy_connect,
701                               ar->mAudioRecord.get());
702         if (j_env->ExceptionCheck()) {
703             SL_LOGE("Java exception releasing recorder routing object.");
704             result = SL_RESULT_INTERNAL_ERROR;
705             ar->mAudioRecord.clear();
706             ar->mCallbackHandle.clear();
707             return result;
708         }
709    }
710 
711     if (ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY) {
712         audio_session_t sessionId = ar->mAudioRecord->getSessionId();
713         // initialize AEC
714         effect_descriptor_t *descriptor = &ar->mAcousticEchoCancellation.mAECDescriptor;
715         if (memcmp(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, &descriptor->type,
716                    sizeof(effect_uuid_t)) == 0) {
717             if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) ||
718                     (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) {
719                 SL_LOGV("Need to initialize AEC for AudioRecorder=%p", ar);
720                 android_aec_init(sessionId, &ar->mAcousticEchoCancellation);
721             }
722         }
723 
724         // initialize AGC
725         descriptor = &ar->mAutomaticGainControl.mAGCDescriptor;
726         if (memcmp(SL_IID_ANDROIDAUTOMATICGAINCONTROL, &descriptor->type,
727                    sizeof(effect_uuid_t)) == 0) {
728             if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) ||
729                     (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) {
730                 SL_LOGV("Need to initialize AGC for AudioRecorder=%p", ar);
731                 android_agc_init(sessionId, &ar->mAutomaticGainControl);
732             }
733         }
734 
735         // initialize NS
736         descriptor = &ar->mNoiseSuppression.mNSDescriptor;
737         if (memcmp(SL_IID_ANDROIDNOISESUPPRESSION, &descriptor->type,
738                    sizeof(effect_uuid_t)) == 0) {
739             if ((ar->mPerformanceMode != ANDROID_PERFORMANCE_MODE_LATENCY_EFFECTS) ||
740                     (descriptor->flags & EFFECT_FLAG_HW_ACC_TUNNEL)) {
741                 SL_LOGV("Need to initialize NS for AudioRecorder=%p", ar);
742                 android_ns_init(sessionId, &ar->mNoiseSuppression);
743             }
744         }
745     }
746 
747     return result;
748 }
749 
750 
751 //-----------------------------------------------------------------------------
752 /**
753  * Called with a lock on AudioRecorder, and blocks until safe to destroy
754  */
android_audioRecorder_preDestroy(CAudioRecorder * ar)755 void android_audioRecorder_preDestroy(CAudioRecorder* ar) {
756     object_unlock_exclusive(&ar->mObject);
757     if (ar->mCallbackProtector != 0) {
758         ar->mCallbackProtector->requestCbExitAndWait();
759     }
760     object_lock_exclusive(&ar->mObject);
761 }
762 
763 
764 //-----------------------------------------------------------------------------
android_audioRecorder_destroy(CAudioRecorder * ar)765 void android_audioRecorder_destroy(CAudioRecorder* ar) {
766     SL_LOGV("android_audioRecorder_destroy(%p) entering", ar);
767 
768     if (ar->mAudioRecord != 0) {
769         ar->mAudioRecord->stop();
770         ar->mAudioRecord.clear();
771     }
772     // explicit destructor
773     ar->mCallbackHandle.~sp();
774     ar->mAudioRecord.~sp();
775     ar->mCallbackProtector.~sp();
776 }
777 
778 
779 //-----------------------------------------------------------------------------
android_audioRecorder_setRecordState(CAudioRecorder * ar,SLuint32 state)780 void android_audioRecorder_setRecordState(CAudioRecorder* ar, SLuint32 state) {
781     SL_LOGV("android_audioRecorder_setRecordState(%p, %u) entering", ar, state);
782 
783     if (ar->mAudioRecord == 0) {
784         return;
785     }
786 
787     switch (state) {
788      case SL_RECORDSTATE_STOPPED:
789          ar->mAudioRecord->stop();
790          break;
791      case SL_RECORDSTATE_PAUSED:
792          // Note that pausing is treated like stop as this implementation only records to a buffer
793          //  queue, so there is no notion of destination being "opened" or "closed" (See description
794          //  of SL_RECORDSTATE in specification)
795          ar->mAudioRecord->stop();
796          break;
797      case SL_RECORDSTATE_RECORDING:
798          ar->mAudioRecord->start();
799          break;
800      default:
801          break;
802      }
803 
804 }
805 
806 
807 //-----------------------------------------------------------------------------
android_audioRecorder_useRecordEventMask(CAudioRecorder * ar)808 void android_audioRecorder_useRecordEventMask(CAudioRecorder *ar) {
809     IRecord *pRecordItf = &ar->mRecord;
810     SLuint32 eventFlags = pRecordItf->mCallbackEventsMask;
811 
812     if (ar->mAudioRecord == 0) {
813         return;
814     }
815 
816     if ((eventFlags & SL_RECORDEVENT_HEADATMARKER) && (pRecordItf->mMarkerPosition != 0)) {
817         ar->mAudioRecord->setMarkerPosition((uint32_t)((((int64_t)pRecordItf->mMarkerPosition
818                 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000));
819     } else {
820         // clear marker
821         ar->mAudioRecord->setMarkerPosition(0);
822     }
823 
824     if (eventFlags & SL_RECORDEVENT_HEADATNEWPOS) {
825         SL_LOGV("pos update period %d", pRecordItf->mPositionUpdatePeriod);
826          ar->mAudioRecord->setPositionUpdatePeriod(
827                 (uint32_t)((((int64_t)pRecordItf->mPositionUpdatePeriod
828                 * sles_to_android_sampleRate(ar->mSampleRateMilliHz)))/1000));
829     } else {
830         // clear periodic update
831         ar->mAudioRecord->setPositionUpdatePeriod(0);
832     }
833 
834     if (eventFlags & SL_RECORDEVENT_HEADATLIMIT) {
835         // FIXME support SL_RECORDEVENT_HEADATLIMIT
836         SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADATLIMIT) on an "
837                     "SL_OBJECTID_AUDIORECORDER to be implemented ]");
838     }
839 
840     if (eventFlags & SL_RECORDEVENT_HEADMOVING) {
841         // FIXME support SL_RECORDEVENT_HEADMOVING
842         SL_LOGD("[ FIXME: IRecord_SetCallbackEventsMask(SL_RECORDEVENT_HEADMOVING) on an "
843                 "SL_OBJECTID_AUDIORECORDER to be implemented ]");
844     }
845 
846     if (eventFlags & SL_RECORDEVENT_BUFFER_FULL) {
847         // nothing to do for SL_RECORDEVENT_BUFFER_FULL since this will not be encountered on
848         // recording to buffer queues
849     }
850 
851     if (eventFlags & SL_RECORDEVENT_HEADSTALLED) {
852         // nothing to do for SL_RECORDEVENT_HEADSTALLED, callback event will be checked against mask
853         // when AudioRecord::EVENT_OVERRUN is encountered
854 
855     }
856 
857 }
858 
859 
860 //-----------------------------------------------------------------------------
android_audioRecorder_getPosition(CAudioRecorder * ar,SLmillisecond * pPosMsec)861 void android_audioRecorder_getPosition(CAudioRecorder *ar, SLmillisecond *pPosMsec) {
862     if ((NULL == ar) || (ar->mAudioRecord == 0)) {
863         *pPosMsec = 0;
864     } else {
865         uint32_t positionInFrames;
866         ar->mAudioRecord->getPosition(&positionInFrames);
867         if (ar->mSampleRateMilliHz == UNKNOWN_SAMPLERATE) {
868             *pPosMsec = 0;
869         } else {
870             *pPosMsec = ((int64_t)positionInFrames * 1000) /
871                     sles_to_android_sampleRate(ar->mSampleRateMilliHz);
872         }
873     }
874 }
875