1 /*
2  * Copyright (C) 2014 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 #define LOG_TAG "AudioPolicyEffects"
18 //#define LOG_NDEBUG 0
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <memory>
24 #include <cutils/misc.h>
25 #include <media/AudioEffect.h>
26 #include <media/EffectsConfig.h>
27 #include <mediautils/ServiceUtilities.h>
28 #include <system/audio.h>
29 #include <system/audio_effects/audio_effects_conf.h>
30 #include <utils/Vector.h>
31 #include <utils/SortedVector.h>
32 #include <cutils/config_utils.h>
33 #include <binder/IPCThreadState.h>
34 #include "AudioPolicyEffects.h"
35 
36 namespace android {
37 
38 // ----------------------------------------------------------------------------
39 // AudioPolicyEffects Implementation
40 // ----------------------------------------------------------------------------
41 
AudioPolicyEffects()42 AudioPolicyEffects::AudioPolicyEffects()
43 {
44     status_t loadResult = loadAudioEffectXmlConfig();
45     if (loadResult == NO_ERROR) {
46         mDefaultDeviceEffectFuture = std::async(
47                     std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
48     } else if (loadResult < 0) {
49         ALOGW("Failed to load XML effect configuration, fallback to .conf");
50         // load automatic audio effect modules
51         if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
52             loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
53         } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
54             loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
55         }
56     } else if (loadResult > 0) {
57         ALOGE("Effect config is partially invalid, skipped %d elements", loadResult);
58     }
59 }
60 
61 
~AudioPolicyEffects()62 AudioPolicyEffects::~AudioPolicyEffects()
63 {
64     size_t i = 0;
65     // release audio input processing resources
66     for (i = 0; i < mInputSources.size(); i++) {
67         delete mInputSources.valueAt(i);
68     }
69     mInputSources.clear();
70 
71     for (i = 0; i < mInputSessions.size(); i++) {
72         mInputSessions.valueAt(i)->mEffects.clear();
73         delete mInputSessions.valueAt(i);
74     }
75     mInputSessions.clear();
76 
77     // release audio output processing resources
78     for (i = 0; i < mOutputStreams.size(); i++) {
79         delete mOutputStreams.valueAt(i);
80     }
81     mOutputStreams.clear();
82 
83     for (i = 0; i < mOutputSessions.size(); i++) {
84         mOutputSessions.valueAt(i)->mEffects.clear();
85         delete mOutputSessions.valueAt(i);
86     }
87     mOutputSessions.clear();
88 }
89 
90 
addInputEffects(audio_io_handle_t input,audio_source_t inputSource,audio_session_t audioSession)91 status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
92                              audio_source_t inputSource,
93                              audio_session_t audioSession)
94 {
95     status_t status = NO_ERROR;
96 
97     // create audio pre processors according to input source
98     audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
99                                     AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
100 
101     Mutex::Autolock _l(mLock);
102     ssize_t index = mInputSources.indexOfKey(aliasSource);
103     if (index < 0) {
104         ALOGV("addInputEffects(): no processing needs to be attached to this source");
105         return status;
106     }
107     ssize_t idx = mInputSessions.indexOfKey(audioSession);
108     EffectVector *sessionDesc;
109     if (idx < 0) {
110         sessionDesc = new EffectVector(audioSession);
111         mInputSessions.add(audioSession, sessionDesc);
112     } else {
113         // EffectVector is existing and we just need to increase ref count
114         sessionDesc = mInputSessions.valueAt(idx);
115     }
116     sessionDesc->mRefCount++;
117 
118     ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
119     if (sessionDesc->mRefCount == 1) {
120         int64_t token = IPCThreadState::self()->clearCallingIdentity();
121         Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
122         for (size_t i = 0; i < effects.size(); i++) {
123             EffectDesc *effect = effects[i];
124             sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0,
125                                                  0, audioSession, input);
126             status_t status = fx->initCheck();
127             if (status != NO_ERROR && status != ALREADY_EXISTS) {
128                 ALOGW("addInputEffects(): failed to create Fx %s on source %d",
129                       effect->mName, (int32_t)aliasSource);
130                 // fx goes out of scope and strong ref on AudioEffect is released
131                 continue;
132             }
133             for (size_t j = 0; j < effect->mParams.size(); j++) {
134                 fx->setParameter(effect->mParams[j]);
135             }
136             ALOGV("addInputEffects(): added Fx %s on source: %d",
137                   effect->mName, (int32_t)aliasSource);
138             sessionDesc->mEffects.add(fx);
139         }
140         sessionDesc->setProcessorEnabled(true);
141         IPCThreadState::self()->restoreCallingIdentity(token);
142     }
143     return status;
144 }
145 
146 
releaseInputEffects(audio_io_handle_t input,audio_session_t audioSession)147 status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
148                                                  audio_session_t audioSession)
149 {
150     status_t status = NO_ERROR;
151 
152     Mutex::Autolock _l(mLock);
153     ssize_t index = mInputSessions.indexOfKey(audioSession);
154     if (index < 0) {
155         return status;
156     }
157     EffectVector *sessionDesc = mInputSessions.valueAt(index);
158     sessionDesc->mRefCount--;
159     ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
160     if (sessionDesc->mRefCount == 0) {
161         sessionDesc->setProcessorEnabled(false);
162         delete sessionDesc;
163         mInputSessions.removeItemsAt(index);
164         ALOGV("releaseInputEffects(): all effects released");
165     }
166     return status;
167 }
168 
queryDefaultInputEffects(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)169 status_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
170                                                       effect_descriptor_t *descriptors,
171                                                       uint32_t *count)
172 {
173     status_t status = NO_ERROR;
174 
175     Mutex::Autolock _l(mLock);
176     size_t index;
177     for (index = 0; index < mInputSessions.size(); index++) {
178         if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
179             break;
180         }
181     }
182     if (index == mInputSessions.size()) {
183         *count = 0;
184         return BAD_VALUE;
185     }
186     Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
187 
188     for (size_t i = 0; i < effects.size(); i++) {
189         effect_descriptor_t desc = effects[i]->descriptor();
190         if (i < *count) {
191             descriptors[i] = desc;
192         }
193     }
194     if (effects.size() > *count) {
195         status = NO_MEMORY;
196     }
197     *count = effects.size();
198     return status;
199 }
200 
201 
queryDefaultOutputSessionEffects(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)202 status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
203                          effect_descriptor_t *descriptors,
204                          uint32_t *count)
205 {
206     status_t status = NO_ERROR;
207 
208     Mutex::Autolock _l(mLock);
209     size_t index;
210     for (index = 0; index < mOutputSessions.size(); index++) {
211         if (mOutputSessions.valueAt(index)->mSessionId == audioSession) {
212             break;
213         }
214     }
215     if (index == mOutputSessions.size()) {
216         *count = 0;
217         return BAD_VALUE;
218     }
219     Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects;
220 
221     for (size_t i = 0; i < effects.size(); i++) {
222         effect_descriptor_t desc = effects[i]->descriptor();
223         if (i < *count) {
224             descriptors[i] = desc;
225         }
226     }
227     if (effects.size() > *count) {
228         status = NO_MEMORY;
229     }
230     *count = effects.size();
231     return status;
232 }
233 
234 
addOutputSessionEffects(audio_io_handle_t output,audio_stream_type_t stream,audio_session_t audioSession)235 status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
236                          audio_stream_type_t stream,
237                          audio_session_t audioSession)
238 {
239     status_t status = NO_ERROR;
240 
241     Mutex::Autolock _l(mLock);
242     // create audio processors according to stream
243     // FIXME: should we have specific post processing settings for internal streams?
244     // default to media for now.
245     if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
246         stream = AUDIO_STREAM_MUSIC;
247     }
248     ssize_t index = mOutputStreams.indexOfKey(stream);
249     if (index < 0) {
250         ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
251         return NO_ERROR;
252     }
253 
254     ssize_t idx = mOutputSessions.indexOfKey(audioSession);
255     EffectVector *procDesc;
256     if (idx < 0) {
257         procDesc = new EffectVector(audioSession);
258         mOutputSessions.add(audioSession, procDesc);
259     } else {
260         // EffectVector is existing and we just need to increase ref count
261         procDesc = mOutputSessions.valueAt(idx);
262     }
263     procDesc->mRefCount++;
264 
265     ALOGV("addOutputSessionEffects(): session: %d, refCount: %d",
266           audioSession, procDesc->mRefCount);
267     if (procDesc->mRefCount == 1) {
268         // make sure effects are associated to audio server even if we are executing a binder call
269         int64_t token = IPCThreadState::self()->clearCallingIdentity();
270         Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
271         for (size_t i = 0; i < effects.size(); i++) {
272             EffectDesc *effect = effects[i];
273             sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,
274                                                  audioSession, output);
275             status_t status = fx->initCheck();
276             if (status != NO_ERROR && status != ALREADY_EXISTS) {
277                 ALOGE("addOutputSessionEffects(): failed to create Fx  %s on session %d",
278                       effect->mName, audioSession);
279                 // fx goes out of scope and strong ref on AudioEffect is released
280                 continue;
281             }
282             ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
283                   effect->mName, audioSession, (int32_t)stream);
284             procDesc->mEffects.add(fx);
285         }
286 
287         procDesc->setProcessorEnabled(true);
288         IPCThreadState::self()->restoreCallingIdentity(token);
289     }
290     return status;
291 }
292 
releaseOutputSessionEffects(audio_io_handle_t output,audio_stream_type_t stream,audio_session_t audioSession)293 status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
294                          audio_stream_type_t stream,
295                          audio_session_t audioSession)
296 {
297     status_t status = NO_ERROR;
298     (void) output; // argument not used for now
299     (void) stream; // argument not used for now
300 
301     Mutex::Autolock _l(mLock);
302     ssize_t index = mOutputSessions.indexOfKey(audioSession);
303     if (index < 0) {
304         ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
305         return NO_ERROR;
306     }
307 
308     EffectVector *procDesc = mOutputSessions.valueAt(index);
309     procDesc->mRefCount--;
310     ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
311           audioSession, procDesc->mRefCount);
312     if (procDesc->mRefCount == 0) {
313         procDesc->setProcessorEnabled(false);
314         procDesc->mEffects.clear();
315         delete procDesc;
316         mOutputSessions.removeItemsAt(index);
317         ALOGV("releaseOutputSessionEffects(): output processing released from session: %d",
318               audioSession);
319     }
320     return status;
321 }
322 
addSourceDefaultEffect(const effect_uuid_t * type,const String16 & opPackageName,const effect_uuid_t * uuid,int32_t priority,audio_source_t source,audio_unique_id_t * id)323 status_t AudioPolicyEffects::addSourceDefaultEffect(const effect_uuid_t *type,
324                                                     const String16& opPackageName,
325                                                     const effect_uuid_t *uuid,
326                                                     int32_t priority,
327                                                     audio_source_t source,
328                                                     audio_unique_id_t* id)
329 {
330     if (uuid == NULL || type == NULL) {
331         ALOGE("addSourceDefaultEffect(): Null uuid or type uuid pointer");
332         return BAD_VALUE;
333     }
334 
335     // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
336     if (source < AUDIO_SOURCE_DEFAULT ||
337             (source > AUDIO_SOURCE_MAX &&
338              source != AUDIO_SOURCE_HOTWORD &&
339              source != AUDIO_SOURCE_FM_TUNER &&
340              source != AUDIO_SOURCE_ECHO_REFERENCE)) {
341         ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
342         return BAD_VALUE;
343     }
344 
345     // Check that |uuid| or |type| corresponds to an effect on the system.
346     effect_descriptor_t descriptor = {};
347     status_t res = AudioEffect::getEffectDescriptor(
348             uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
349     if (res != OK) {
350         ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
351         return res;
352     }
353 
354     // Only pre-processing effects can be added dynamically as source defaults.
355     if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
356         ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
357               "as a source default effect.");
358         return BAD_VALUE;
359     }
360 
361     Mutex::Autolock _l(mLock);
362 
363     // Find the EffectDescVector for the given source type, or create a new one if necessary.
364     ssize_t index = mInputSources.indexOfKey(source);
365     EffectDescVector *desc = NULL;
366     if (index < 0) {
367         // No effects for this source type yet.
368         desc = new EffectDescVector();
369         mInputSources.add(source, desc);
370     } else {
371         desc = mInputSources.valueAt(index);
372     }
373 
374     // Create a new effect and add it to the vector.
375     res = AudioEffect::newEffectUniqueId(id);
376     if (res != OK) {
377         ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
378         return res;
379     }
380     EffectDesc *effect = new EffectDesc(
381             descriptor.name, *type, opPackageName, *uuid, priority, *id);
382     desc->mEffects.add(effect);
383     // TODO(b/71813697): Support setting params as well.
384 
385     // TODO(b/71814300): Retroactively attach to any existing sources of the given type.
386     // This requires tracking the source type of each session id in addition to what is
387     // already being tracked.
388 
389     return NO_ERROR;
390 }
391 
addStreamDefaultEffect(const effect_uuid_t * type,const String16 & opPackageName,const effect_uuid_t * uuid,int32_t priority,audio_usage_t usage,audio_unique_id_t * id)392 status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
393                                                     const String16& opPackageName,
394                                                     const effect_uuid_t *uuid,
395                                                     int32_t priority,
396                                                     audio_usage_t usage,
397                                                     audio_unique_id_t* id)
398 {
399     if (uuid == NULL || type == NULL) {
400         ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
401         return BAD_VALUE;
402     }
403     audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
404 
405     if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
406         ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
407         return BAD_VALUE;
408     }
409 
410     // Check that |uuid| or |type| corresponds to an effect on the system.
411     effect_descriptor_t descriptor = {};
412     status_t res = AudioEffect::getEffectDescriptor(
413             uuid, type, EFFECT_FLAG_TYPE_INSERT, &descriptor);
414     if (res != OK) {
415         ALOGE("addStreamDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
416         return res;
417     }
418 
419     // Only insert effects can be added dynamically as stream defaults.
420     if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_INSERT) {
421         ALOGE("addStreamDefaultEffect(): Desired effect cannot be attached "
422               "as a stream default effect.");
423         return BAD_VALUE;
424     }
425 
426     Mutex::Autolock _l(mLock);
427 
428     // Find the EffectDescVector for the given stream type, or create a new one if necessary.
429     ssize_t index = mOutputStreams.indexOfKey(stream);
430     EffectDescVector *desc = NULL;
431     if (index < 0) {
432         // No effects for this stream type yet.
433         desc = new EffectDescVector();
434         mOutputStreams.add(stream, desc);
435     } else {
436         desc = mOutputStreams.valueAt(index);
437     }
438 
439     // Create a new effect and add it to the vector.
440     res = AudioEffect::newEffectUniqueId(id);
441     if (res != OK) {
442         ALOGE("addStreamDefaultEffect(): failed to get new unique id.");
443         return res;
444     }
445     EffectDesc *effect = new EffectDesc(
446             descriptor.name, *type, opPackageName, *uuid, priority, *id);
447     desc->mEffects.add(effect);
448     // TODO(b/71813697): Support setting params as well.
449 
450     // TODO(b/71814300): Retroactively attach to any existing streams of the given type.
451     // This requires tracking the stream type of each session id in addition to what is
452     // already being tracked.
453 
454     return NO_ERROR;
455 }
456 
removeSourceDefaultEffect(audio_unique_id_t id)457 status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
458 {
459     if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
460         // ALLOCATE is not a unique identifier, but rather a reserved value indicating
461         // a real id has not been assigned. For default effects, this value is only used
462         // by system-owned defaults from the loaded config, which cannot be removed.
463         return BAD_VALUE;
464     }
465 
466     Mutex::Autolock _l(mLock);
467 
468     // Check each source type.
469     size_t numSources = mInputSources.size();
470     for (size_t i = 0; i < numSources; ++i) {
471         // Check each effect for each source.
472         EffectDescVector* descVector = mInputSources[i];
473         for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
474             if ((*desc)->mId == id) {
475                 // Found it!
476                 // TODO(b/71814300): Remove from any sources the effect was attached to.
477                 descVector->mEffects.erase(desc);
478                 // Handles are unique; there can only be one match, so return early.
479                 return NO_ERROR;
480             }
481         }
482     }
483 
484     // Effect wasn't found, so it's been trivially removed successfully.
485     return NO_ERROR;
486 }
487 
removeStreamDefaultEffect(audio_unique_id_t id)488 status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
489 {
490     if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
491         // ALLOCATE is not a unique identifier, but rather a reserved value indicating
492         // a real id has not been assigned. For default effects, this value is only used
493         // by system-owned defaults from the loaded config, which cannot be removed.
494         return BAD_VALUE;
495     }
496 
497     Mutex::Autolock _l(mLock);
498 
499     // Check each stream type.
500     size_t numStreams = mOutputStreams.size();
501     for (size_t i = 0; i < numStreams; ++i) {
502         // Check each effect for each stream.
503         EffectDescVector* descVector = mOutputStreams[i];
504         for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
505             if ((*desc)->mId == id) {
506                 // Found it!
507                 // TODO(b/71814300): Remove from any streams the effect was attached to.
508                 descVector->mEffects.erase(desc);
509                 // Handles are unique; there can only be one match, so return early.
510                 return NO_ERROR;
511             }
512         }
513     }
514 
515     // Effect wasn't found, so it's been trivially removed successfully.
516     return NO_ERROR;
517 }
518 
setProcessorEnabled(bool enabled)519 void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
520 {
521     for (size_t i = 0; i < mEffects.size(); i++) {
522         mEffects.itemAt(i)->setEnabled(enabled);
523     }
524 }
525 
526 
527 // ----------------------------------------------------------------------------
528 // Audio processing configuration
529 // ----------------------------------------------------------------------------
530 
531 /*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
532     MIC_SRC_TAG,
533     VOICE_UL_SRC_TAG,
534     VOICE_DL_SRC_TAG,
535     VOICE_CALL_SRC_TAG,
536     CAMCORDER_SRC_TAG,
537     VOICE_REC_SRC_TAG,
538     VOICE_COMM_SRC_TAG,
539     UNPROCESSED_SRC_TAG,
540     VOICE_PERFORMANCE_SRC_TAG
541 };
542 
543 // returns the audio_source_t enum corresponding to the input source name or
544 // AUDIO_SOURCE_CNT is no match found
inputSourceNameToEnum(const char * name)545 /*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name)
546 {
547     int i;
548     for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
549         if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
550             ALOGV("inputSourceNameToEnum found source %s %d", name, i);
551             break;
552         }
553     }
554     return (audio_source_t)i;
555 }
556 
557 const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
558     AUDIO_STREAM_DEFAULT_TAG,
559     AUDIO_STREAM_VOICE_CALL_TAG,
560     AUDIO_STREAM_SYSTEM_TAG,
561     AUDIO_STREAM_RING_TAG,
562     AUDIO_STREAM_MUSIC_TAG,
563     AUDIO_STREAM_ALARM_TAG,
564     AUDIO_STREAM_NOTIFICATION_TAG,
565     AUDIO_STREAM_BLUETOOTH_SCO_TAG,
566     AUDIO_STREAM_ENFORCED_AUDIBLE_TAG,
567     AUDIO_STREAM_DTMF_TAG,
568     AUDIO_STREAM_TTS_TAG,
569     AUDIO_STREAM_ASSISTANT_TAG
570 };
571 
572 // returns the audio_stream_t enum corresponding to the output stream name or
573 // AUDIO_STREAM_PUBLIC_CNT is no match found
streamNameToEnum(const char * name)574 audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
575 {
576     int i;
577     for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
578         if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
579             ALOGV("streamNameToEnum found stream %s %d", name, i);
580             break;
581         }
582     }
583     return (audio_stream_type_t)i;
584 }
585 
586 // ----------------------------------------------------------------------------
587 // Audio Effect Config parser
588 // ----------------------------------------------------------------------------
589 
growParamSize(char ** param,size_t size,size_t * curSize,size_t * totSize)590 size_t AudioPolicyEffects::growParamSize(char **param,
591                                          size_t size,
592                                          size_t *curSize,
593                                          size_t *totSize)
594 {
595     // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
596     size_t pos = ((*curSize - 1 ) / size + 1) * size;
597 
598     if (pos + size > *totSize) {
599         while (pos + size > *totSize) {
600             *totSize += ((*totSize + 7) / 8) * 4;
601         }
602         char *newParam = (char *)realloc(*param, *totSize);
603         if (newParam == NULL) {
604             ALOGE("%s realloc error for size %zu", __func__, *totSize);
605             return 0;
606         }
607         *param = newParam;
608     }
609     *curSize = pos + size;
610     return pos;
611 }
612 
613 
readParamValue(cnode * node,char ** param,size_t * curSize,size_t * totSize)614 size_t AudioPolicyEffects::readParamValue(cnode *node,
615                                           char **param,
616                                           size_t *curSize,
617                                           size_t *totSize)
618 {
619     size_t len = 0;
620     size_t pos;
621 
622     if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
623         pos = growParamSize(param, sizeof(short), curSize, totSize);
624         if (pos == 0) {
625             goto exit;
626         }
627         *(short *)(*param + pos) = (short)atoi(node->value);
628         ALOGV("readParamValue() reading short %d", *(short *)(*param + pos));
629         len = sizeof(short);
630     } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
631         pos = growParamSize(param, sizeof(int), curSize, totSize);
632         if (pos == 0) {
633             goto exit;
634         }
635         *(int *)(*param + pos) = atoi(node->value);
636         ALOGV("readParamValue() reading int %d", *(int *)(*param + pos));
637         len = sizeof(int);
638     } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
639         pos = growParamSize(param, sizeof(float), curSize, totSize);
640         if (pos == 0) {
641             goto exit;
642         }
643         *(float *)(*param + pos) = (float)atof(node->value);
644         ALOGV("readParamValue() reading float %f",*(float *)(*param + pos));
645         len = sizeof(float);
646     } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
647         pos = growParamSize(param, sizeof(bool), curSize, totSize);
648         if (pos == 0) {
649             goto exit;
650         }
651         if (strncmp(node->value, "true", strlen("true") + 1) == 0) {
652             *(bool *)(*param + pos) = true;
653         } else {
654             *(bool *)(*param + pos) = false;
655         }
656         ALOGV("readParamValue() reading bool %s",
657               *(bool *)(*param + pos) ? "true" : "false");
658         len = sizeof(bool);
659     } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
660         len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
661         if (*curSize + len + 1 > *totSize) {
662             *totSize = *curSize + len + 1;
663             char *newParam = (char *)realloc(*param, *totSize);
664             if (newParam == NULL) {
665                 len = 0;
666                 ALOGE("%s realloc error for string len %zu", __func__, *totSize);
667                 goto exit;
668             }
669             *param = newParam;
670         }
671         strncpy(*param + *curSize, node->value, len);
672         *curSize += len;
673         (*param)[*curSize] = '\0';
674         ALOGV("readParamValue() reading string %s", *param + *curSize - len);
675     } else {
676         ALOGW("readParamValue() unknown param type %s", node->name);
677     }
678 exit:
679     return len;
680 }
681 
loadEffectParameter(cnode * root)682 effect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root)
683 {
684     cnode *param;
685     cnode *value;
686     size_t curSize = sizeof(effect_param_t);
687     size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
688     effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
689 
690     if (fx_param == NULL) {
691         ALOGE("%s malloc error for effect structure of size %zu",
692               __func__, totSize);
693         return NULL;
694     }
695 
696     param = config_find(root, PARAM_TAG);
697     value = config_find(root, VALUE_TAG);
698     if (param == NULL && value == NULL) {
699         // try to parse simple parameter form {int int}
700         param = root->first_child;
701         if (param != NULL) {
702             // Note: that a pair of random strings is read as 0 0
703             int *ptr = (int *)fx_param->data;
704 #if LOG_NDEBUG == 0
705             int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
706             ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
707 #endif
708             *ptr++ = atoi(param->name);
709             *ptr = atoi(param->value);
710             fx_param->psize = sizeof(int);
711             fx_param->vsize = sizeof(int);
712             return fx_param;
713         }
714     }
715     if (param == NULL || value == NULL) {
716         ALOGW("loadEffectParameter() invalid parameter description %s",
717               root->name);
718         goto error;
719     }
720 
721     fx_param->psize = 0;
722     param = param->first_child;
723     while (param) {
724         ALOGV("loadEffectParameter() reading param of type %s", param->name);
725         size_t size =
726                 readParamValue(param, (char **)&fx_param, &curSize, &totSize);
727         if (size == 0) {
728             goto error;
729         }
730         fx_param->psize += size;
731         param = param->next;
732     }
733 
734     // align start of value field on 32 bit boundary
735     curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
736 
737     fx_param->vsize = 0;
738     value = value->first_child;
739     while (value) {
740         ALOGV("loadEffectParameter() reading value of type %s", value->name);
741         size_t size =
742                 readParamValue(value, (char **)&fx_param, &curSize, &totSize);
743         if (size == 0) {
744             goto error;
745         }
746         fx_param->vsize += size;
747         value = value->next;
748     }
749 
750     return fx_param;
751 
752 error:
753     free(fx_param);
754     return NULL;
755 }
756 
loadEffectParameters(cnode * root,Vector<effect_param_t * > & params)757 void AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
758 {
759     cnode *node = root->first_child;
760     while (node) {
761         ALOGV("loadEffectParameters() loading param %s", node->name);
762         effect_param_t *param = loadEffectParameter(node);
763         if (param != NULL) {
764             params.add(param);
765         }
766         node = node->next;
767     }
768 }
769 
770 
loadEffectConfig(cnode * root,const Vector<EffectDesc * > & effects)771 AudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig(
772                                                             cnode *root,
773                                                             const Vector <EffectDesc *>& effects)
774 {
775     cnode *node = root->first_child;
776     if (node == NULL) {
777         ALOGW("loadInputSource() empty element %s", root->name);
778         return NULL;
779     }
780     EffectDescVector *desc = new EffectDescVector();
781     while (node) {
782         size_t i;
783 
784         for (i = 0; i < effects.size(); i++) {
785             if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
786                 ALOGV("loadEffectConfig() found effect %s in list", node->name);
787                 break;
788             }
789         }
790         if (i == effects.size()) {
791             ALOGV("loadEffectConfig() effect %s not in list", node->name);
792             node = node->next;
793             continue;
794         }
795         EffectDesc *effect = new EffectDesc(*effects[i]);   // deep copy
796         loadEffectParameters(node, effect->mParams);
797         ALOGV("loadEffectConfig() adding effect %s uuid %08x",
798               effect->mName, effect->mUuid.timeLow);
799         desc->mEffects.add(effect);
800         node = node->next;
801     }
802     if (desc->mEffects.size() == 0) {
803         ALOGW("loadEffectConfig() no valid effects found in config %s", root->name);
804         delete desc;
805         return NULL;
806     }
807     return desc;
808 }
809 
loadInputEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)810 status_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root,
811                                                            const Vector <EffectDesc *>& effects)
812 {
813     cnode *node = config_find(root, PREPROCESSING_TAG);
814     if (node == NULL) {
815         return -ENOENT;
816     }
817     node = node->first_child;
818     while (node) {
819         audio_source_t source = inputSourceNameToEnum(node->name);
820         if (source == AUDIO_SOURCE_CNT) {
821             ALOGW("loadInputSources() invalid input source %s", node->name);
822             node = node->next;
823             continue;
824         }
825         ALOGV("loadInputSources() loading input source %s", node->name);
826         EffectDescVector *desc = loadEffectConfig(node, effects);
827         if (desc == NULL) {
828             node = node->next;
829             continue;
830         }
831         mInputSources.add(source, desc);
832         node = node->next;
833     }
834     return NO_ERROR;
835 }
836 
loadStreamEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)837 status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
838                                                             const Vector <EffectDesc *>& effects)
839 {
840     cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG);
841     if (node == NULL) {
842         return -ENOENT;
843     }
844     node = node->first_child;
845     while (node) {
846         audio_stream_type_t stream = streamNameToEnum(node->name);
847         if (stream == AUDIO_STREAM_PUBLIC_CNT) {
848             ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
849             node = node->next;
850             continue;
851         }
852         ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name);
853         EffectDescVector *desc = loadEffectConfig(node, effects);
854         if (desc == NULL) {
855             node = node->next;
856             continue;
857         }
858         mOutputStreams.add(stream, desc);
859         node = node->next;
860     }
861     return NO_ERROR;
862 }
863 
loadEffect(cnode * root)864 AudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root)
865 {
866     cnode *node = config_find(root, UUID_TAG);
867     if (node == NULL) {
868         return NULL;
869     }
870     effect_uuid_t uuid;
871     if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
872         ALOGW("loadEffect() invalid uuid %s", node->value);
873         return NULL;
874     }
875     return new EffectDesc(root->name, uuid);
876 }
877 
loadEffects(cnode * root,Vector<EffectDesc * > & effects)878 status_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
879 {
880     cnode *node = config_find(root, EFFECTS_TAG);
881     if (node == NULL) {
882         return -ENOENT;
883     }
884     node = node->first_child;
885     while (node) {
886         ALOGV("loadEffects() loading effect %s", node->name);
887         EffectDesc *effect = loadEffect(node);
888         if (effect == NULL) {
889             node = node->next;
890             continue;
891         }
892         effects.add(effect);
893         node = node->next;
894     }
895     return NO_ERROR;
896 }
897 
loadAudioEffectXmlConfig()898 status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
899     auto result = effectsConfig::parse();
900     if (result.parsedConfig == nullptr) {
901         return -ENOENT;
902     }
903 
904     auto loadProcessingChain = [](auto& processingChain, auto& streams) {
905         for (auto& stream : processingChain) {
906             auto effectDescs = std::make_unique<EffectDescVector>();
907             for (auto& effect : stream.effects) {
908                 effectDescs->mEffects.add(
909                         new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
910             }
911             streams.add(stream.type, effectDescs.release());
912         }
913     };
914 
915     auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
916         for (auto& deviceProcess : processingChain) {
917 
918             auto effectDescs = std::make_unique<EffectDescVector>();
919             for (auto& effect : deviceProcess.effects) {
920                 effectDescs->mEffects.add(
921                         new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
922             }
923             auto deviceEffects = std::make_unique<DeviceEffects>(
924                         std::move(effectDescs), deviceProcess.type, deviceProcess.address);
925             devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
926         }
927     };
928 
929     loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
930     loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
931     {
932         Mutex::Autolock _l(mLock);
933         loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
934     }
935     // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
936     return result.nbSkippedElement;
937 }
938 
loadAudioEffectConfig(const char * path)939 status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
940 {
941     cnode *root;
942     char *data;
943 
944     data = (char *)load_file(path, NULL);
945     if (data == NULL) {
946         return -ENODEV;
947     }
948     root = config_node("", "");
949     config_load(root, data);
950 
951     Vector <EffectDesc *> effects;
952     loadEffects(root, effects);
953     loadInputEffectConfigurations(root, effects);
954     loadStreamEffectConfigurations(root, effects);
955 
956     for (size_t i = 0; i < effects.size(); i++) {
957         delete effects[i];
958     }
959 
960     config_free(root);
961     free(root);
962     free(data);
963 
964     return NO_ERROR;
965 }
966 
initDefaultDeviceEffects()967 void AudioPolicyEffects::initDefaultDeviceEffects()
968 {
969     Mutex::Autolock _l(mLock);
970     for (const auto& deviceEffectsIter : mDeviceEffects) {
971         const auto& deviceEffects =  deviceEffectsIter.second;
972         for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
973             auto fx = std::make_unique<AudioEffect>(
974                         EFFECT_UUID_NULL, String16("android"), &effectDesc->mUuid, 0, nullptr,
975                         nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
976                         AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
977                                             deviceEffects->getDeviceAddress()});
978             status_t status = fx->initCheck();
979             if (status != NO_ERROR && status != ALREADY_EXISTS) {
980                 ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
981                       effectDesc->mName, deviceEffects->getDeviceType(),
982                       deviceEffects->getDeviceAddress().c_str());
983                 // fx goes out of scope and strong ref on AudioEffect is released
984                 continue;
985             }
986             fx->setEnabled(true);
987             ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
988                   effectDesc->mName, deviceEffects->getDeviceType(),
989                   deviceEffects->getDeviceAddress().c_str());
990             deviceEffects->mEffects.push_back(std::move(fx));
991         }
992     }
993 }
994 
995 } // namespace android
996