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