• 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         ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
350         return BAD_VALUE;
351     }
352 
353     // Check that |uuid| or |type| corresponds to an effect on the system.
354     effect_descriptor_t descriptor = {};
355     status_t res = AudioEffect::getEffectDescriptor(
356             uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
357     if (res != OK) {
358         ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
359         return res;
360     }
361 
362     // Only pre-processing effects can be added dynamically as source defaults.
363     if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
364         ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
365               "as a source default effect.");
366         return BAD_VALUE;
367     }
368 
369     Mutex::Autolock _l(mLock);
370 
371     // Find the EffectDescVector for the given source type, or create a new one if necessary.
372     ssize_t index = mInputSources.indexOfKey(source);
373     EffectDescVector *desc = NULL;
374     if (index < 0) {
375         // No effects for this source type yet.
376         desc = new EffectDescVector();
377         mInputSources.add(source, desc);
378     } else {
379         desc = mInputSources.valueAt(index);
380     }
381 
382     // Create a new effect and add it to the vector.
383     res = AudioEffect::newEffectUniqueId(id);
384     if (res != OK) {
385         ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
386         return res;
387     }
388     EffectDesc *effect = new EffectDesc(
389             descriptor.name, *type, opPackageName, *uuid, priority, *id);
390     desc->mEffects.add(effect);
391     // TODO(b/71813697): Support setting params as well.
392 
393     // TODO(b/71814300): Retroactively attach to any existing sources of the given type.
394     // This requires tracking the source type of each session id in addition to what is
395     // already being tracked.
396 
397     return NO_ERROR;
398 }
399 
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)400 status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
401                                                     const String16& opPackageName,
402                                                     const effect_uuid_t *uuid,
403                                                     int32_t priority,
404                                                     audio_usage_t usage,
405                                                     audio_unique_id_t* id)
406 {
407     if (uuid == NULL || type == NULL) {
408         ALOGE("addStreamDefaultEffect(): Null uuid or type uuid pointer");
409         return BAD_VALUE;
410     }
411     audio_stream_type_t stream = AudioSystem::attributesToStreamType(attributes_initializer(usage));
412 
413     if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_PUBLIC_CNT) {
414         ALOGE("addStreamDefaultEffect(): Unsupported stream type %d", stream);
415         return BAD_VALUE;
416     }
417 
418     // Check that |uuid| or |type| corresponds to an effect on the system.
419     effect_descriptor_t descriptor = {};
420     status_t res = AudioEffect::getEffectDescriptor(
421             uuid, type, EFFECT_FLAG_TYPE_INSERT, &descriptor);
422     if (res != OK) {
423         ALOGE("addStreamDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
424         return res;
425     }
426 
427     // Only insert effects can be added dynamically as stream defaults.
428     if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_INSERT) {
429         ALOGE("addStreamDefaultEffect(): Desired effect cannot be attached "
430               "as a stream default effect.");
431         return BAD_VALUE;
432     }
433 
434     Mutex::Autolock _l(mLock);
435 
436     // Find the EffectDescVector for the given stream type, or create a new one if necessary.
437     ssize_t index = mOutputStreams.indexOfKey(stream);
438     EffectDescVector *desc = NULL;
439     if (index < 0) {
440         // No effects for this stream type yet.
441         desc = new EffectDescVector();
442         mOutputStreams.add(stream, desc);
443     } else {
444         desc = mOutputStreams.valueAt(index);
445     }
446 
447     // Create a new effect and add it to the vector.
448     res = AudioEffect::newEffectUniqueId(id);
449     if (res != OK) {
450         ALOGE("addStreamDefaultEffect(): failed to get new unique id.");
451         return res;
452     }
453     EffectDesc *effect = new EffectDesc(
454             descriptor.name, *type, opPackageName, *uuid, priority, *id);
455     desc->mEffects.add(effect);
456     // TODO(b/71813697): Support setting params as well.
457 
458     // TODO(b/71814300): Retroactively attach to any existing streams of the given type.
459     // This requires tracking the stream type of each session id in addition to what is
460     // already being tracked.
461 
462     return NO_ERROR;
463 }
464 
removeSourceDefaultEffect(audio_unique_id_t id)465 status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
466 {
467     if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
468         // ALLOCATE is not a unique identifier, but rather a reserved value indicating
469         // a real id has not been assigned. For default effects, this value is only used
470         // by system-owned defaults from the loaded config, which cannot be removed.
471         return BAD_VALUE;
472     }
473 
474     Mutex::Autolock _l(mLock);
475 
476     // Check each source type.
477     size_t numSources = mInputSources.size();
478     for (size_t i = 0; i < numSources; ++i) {
479         // Check each effect for each source.
480         EffectDescVector* descVector = mInputSources[i];
481         for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
482             if ((*desc)->mId == id) {
483                 // Found it!
484                 // TODO(b/71814300): Remove from any sources the effect was attached to.
485                 descVector->mEffects.erase(desc);
486                 // Handles are unique; there can only be one match, so return early.
487                 return NO_ERROR;
488             }
489         }
490     }
491 
492     // Effect wasn't found, so it's been trivially removed successfully.
493     return NO_ERROR;
494 }
495 
removeStreamDefaultEffect(audio_unique_id_t id)496 status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
497 {
498     if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
499         // ALLOCATE is not a unique identifier, but rather a reserved value indicating
500         // a real id has not been assigned. For default effects, this value is only used
501         // by system-owned defaults from the loaded config, which cannot be removed.
502         return BAD_VALUE;
503     }
504 
505     Mutex::Autolock _l(mLock);
506 
507     // Check each stream type.
508     size_t numStreams = mOutputStreams.size();
509     for (size_t i = 0; i < numStreams; ++i) {
510         // Check each effect for each stream.
511         EffectDescVector* descVector = mOutputStreams[i];
512         for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
513             if ((*desc)->mId == id) {
514                 // Found it!
515                 // TODO(b/71814300): Remove from any streams the effect was attached to.
516                 descVector->mEffects.erase(desc);
517                 // Handles are unique; there can only be one match, so return early.
518                 return NO_ERROR;
519             }
520         }
521     }
522 
523     // Effect wasn't found, so it's been trivially removed successfully.
524     return NO_ERROR;
525 }
526 
setProcessorEnabled(bool enabled)527 void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
528 {
529     for (size_t i = 0; i < mEffects.size(); i++) {
530         mEffects.itemAt(i)->setEnabled(enabled);
531     }
532 }
533 
534 
535 // ----------------------------------------------------------------------------
536 // Audio processing configuration
537 // ----------------------------------------------------------------------------
538 
539 /*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
540     MIC_SRC_TAG,
541     VOICE_UL_SRC_TAG,
542     VOICE_DL_SRC_TAG,
543     VOICE_CALL_SRC_TAG,
544     CAMCORDER_SRC_TAG,
545     VOICE_REC_SRC_TAG,
546     VOICE_COMM_SRC_TAG,
547     UNPROCESSED_SRC_TAG,
548     VOICE_PERFORMANCE_SRC_TAG
549 };
550 
551 // returns the audio_source_t enum corresponding to the input source name or
552 // AUDIO_SOURCE_CNT is no match found
inputSourceNameToEnum(const char * name)553 /*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name)
554 {
555     int i;
556     for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
557         if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
558             ALOGV("inputSourceNameToEnum found source %s %d", name, i);
559             break;
560         }
561     }
562     return (audio_source_t)i;
563 }
564 
565 const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
566     AUDIO_STREAM_DEFAULT_TAG,
567     AUDIO_STREAM_VOICE_CALL_TAG,
568     AUDIO_STREAM_SYSTEM_TAG,
569     AUDIO_STREAM_RING_TAG,
570     AUDIO_STREAM_MUSIC_TAG,
571     AUDIO_STREAM_ALARM_TAG,
572     AUDIO_STREAM_NOTIFICATION_TAG,
573     AUDIO_STREAM_BLUETOOTH_SCO_TAG,
574     AUDIO_STREAM_ENFORCED_AUDIBLE_TAG,
575     AUDIO_STREAM_DTMF_TAG,
576     AUDIO_STREAM_TTS_TAG,
577     AUDIO_STREAM_ASSISTANT_TAG
578 };
579 
580 // returns the audio_stream_t enum corresponding to the output stream name or
581 // AUDIO_STREAM_PUBLIC_CNT is no match found
streamNameToEnum(const char * name)582 audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
583 {
584     int i;
585     for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
586         if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
587             ALOGV("streamNameToEnum found stream %s %d", name, i);
588             break;
589         }
590     }
591     return (audio_stream_type_t)i;
592 }
593 
594 // ----------------------------------------------------------------------------
595 // Audio Effect Config parser
596 // ----------------------------------------------------------------------------
597 
growParamSize(char ** param,size_t size,size_t * curSize,size_t * totSize)598 size_t AudioPolicyEffects::growParamSize(char **param,
599                                          size_t size,
600                                          size_t *curSize,
601                                          size_t *totSize)
602 {
603     // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
604     size_t pos = ((*curSize - 1 ) / size + 1) * size;
605 
606     if (pos + size > *totSize) {
607         while (pos + size > *totSize) {
608             *totSize += ((*totSize + 7) / 8) * 4;
609         }
610         char *newParam = (char *)realloc(*param, *totSize);
611         if (newParam == NULL) {
612             ALOGE("%s realloc error for size %zu", __func__, *totSize);
613             return 0;
614         }
615         *param = newParam;
616     }
617     *curSize = pos + size;
618     return pos;
619 }
620 
621 
readParamValue(cnode * node,char ** param,size_t * curSize,size_t * totSize)622 size_t AudioPolicyEffects::readParamValue(cnode *node,
623                                           char **param,
624                                           size_t *curSize,
625                                           size_t *totSize)
626 {
627     size_t len = 0;
628     size_t pos;
629 
630     if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
631         pos = growParamSize(param, sizeof(short), curSize, totSize);
632         if (pos == 0) {
633             goto exit;
634         }
635         *(short *)(*param + pos) = (short)atoi(node->value);
636         ALOGV("readParamValue() reading short %d", *(short *)(*param + pos));
637         len = sizeof(short);
638     } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
639         pos = growParamSize(param, sizeof(int), curSize, totSize);
640         if (pos == 0) {
641             goto exit;
642         }
643         *(int *)(*param + pos) = atoi(node->value);
644         ALOGV("readParamValue() reading int %d", *(int *)(*param + pos));
645         len = sizeof(int);
646     } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
647         pos = growParamSize(param, sizeof(float), curSize, totSize);
648         if (pos == 0) {
649             goto exit;
650         }
651         *(float *)(*param + pos) = (float)atof(node->value);
652         ALOGV("readParamValue() reading float %f",*(float *)(*param + pos));
653         len = sizeof(float);
654     } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
655         pos = growParamSize(param, sizeof(bool), curSize, totSize);
656         if (pos == 0) {
657             goto exit;
658         }
659         if (strncmp(node->value, "true", strlen("true") + 1) == 0) {
660             *(bool *)(*param + pos) = true;
661         } else {
662             *(bool *)(*param + pos) = false;
663         }
664         ALOGV("readParamValue() reading bool %s",
665               *(bool *)(*param + pos) ? "true" : "false");
666         len = sizeof(bool);
667     } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
668         len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
669         if (*curSize + len + 1 > *totSize) {
670             *totSize = *curSize + len + 1;
671             char *newParam = (char *)realloc(*param, *totSize);
672             if (newParam == NULL) {
673                 len = 0;
674                 ALOGE("%s realloc error for string len %zu", __func__, *totSize);
675                 goto exit;
676             }
677             *param = newParam;
678         }
679         strncpy(*param + *curSize, node->value, len);
680         *curSize += len;
681         (*param)[*curSize] = '\0';
682         ALOGV("readParamValue() reading string %s", *param + *curSize - len);
683     } else {
684         ALOGW("readParamValue() unknown param type %s", node->name);
685     }
686 exit:
687     return len;
688 }
689 
loadEffectParameter(cnode * root)690 effect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root)
691 {
692     cnode *param;
693     cnode *value;
694     size_t curSize = sizeof(effect_param_t);
695     size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
696     effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
697 
698     if (fx_param == NULL) {
699         ALOGE("%s malloc error for effect structure of size %zu",
700               __func__, totSize);
701         return NULL;
702     }
703 
704     param = config_find(root, PARAM_TAG);
705     value = config_find(root, VALUE_TAG);
706     if (param == NULL && value == NULL) {
707         // try to parse simple parameter form {int int}
708         param = root->first_child;
709         if (param != NULL) {
710             // Note: that a pair of random strings is read as 0 0
711             int *ptr = (int *)fx_param->data;
712 #if LOG_NDEBUG == 0
713             int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
714             ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
715 #endif
716             *ptr++ = atoi(param->name);
717             *ptr = atoi(param->value);
718             fx_param->psize = sizeof(int);
719             fx_param->vsize = sizeof(int);
720             return fx_param;
721         }
722     }
723     if (param == NULL || value == NULL) {
724         ALOGW("loadEffectParameter() invalid parameter description %s",
725               root->name);
726         goto error;
727     }
728 
729     fx_param->psize = 0;
730     param = param->first_child;
731     while (param) {
732         ALOGV("loadEffectParameter() reading param of type %s", param->name);
733         size_t size =
734                 readParamValue(param, (char **)&fx_param, &curSize, &totSize);
735         if (size == 0) {
736             goto error;
737         }
738         fx_param->psize += size;
739         param = param->next;
740     }
741 
742     // align start of value field on 32 bit boundary
743     curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
744 
745     fx_param->vsize = 0;
746     value = value->first_child;
747     while (value) {
748         ALOGV("loadEffectParameter() reading value of type %s", value->name);
749         size_t size =
750                 readParamValue(value, (char **)&fx_param, &curSize, &totSize);
751         if (size == 0) {
752             goto error;
753         }
754         fx_param->vsize += size;
755         value = value->next;
756     }
757 
758     return fx_param;
759 
760 error:
761     free(fx_param);
762     return NULL;
763 }
764 
loadEffectParameters(cnode * root,Vector<effect_param_t * > & params)765 void AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
766 {
767     cnode *node = root->first_child;
768     while (node) {
769         ALOGV("loadEffectParameters() loading param %s", node->name);
770         effect_param_t *param = loadEffectParameter(node);
771         if (param != NULL) {
772             params.add(param);
773         }
774         node = node->next;
775     }
776 }
777 
778 
loadEffectConfig(cnode * root,const Vector<EffectDesc * > & effects)779 AudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig(
780                                                             cnode *root,
781                                                             const Vector <EffectDesc *>& effects)
782 {
783     cnode *node = root->first_child;
784     if (node == NULL) {
785         ALOGW("loadInputSource() empty element %s", root->name);
786         return NULL;
787     }
788     EffectDescVector *desc = new EffectDescVector();
789     while (node) {
790         size_t i;
791 
792         for (i = 0; i < effects.size(); i++) {
793             if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
794                 ALOGV("loadEffectConfig() found effect %s in list", node->name);
795                 break;
796             }
797         }
798         if (i == effects.size()) {
799             ALOGV("loadEffectConfig() effect %s not in list", node->name);
800             node = node->next;
801             continue;
802         }
803         EffectDesc *effect = new EffectDesc(*effects[i]);   // deep copy
804         loadEffectParameters(node, effect->mParams);
805         ALOGV("loadEffectConfig() adding effect %s uuid %08x",
806               effect->mName, effect->mUuid.timeLow);
807         desc->mEffects.add(effect);
808         node = node->next;
809     }
810     if (desc->mEffects.size() == 0) {
811         ALOGW("loadEffectConfig() no valid effects found in config %s", root->name);
812         delete desc;
813         return NULL;
814     }
815     return desc;
816 }
817 
loadInputEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)818 status_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root,
819                                                            const Vector <EffectDesc *>& effects)
820 {
821     cnode *node = config_find(root, PREPROCESSING_TAG);
822     if (node == NULL) {
823         return -ENOENT;
824     }
825     node = node->first_child;
826     while (node) {
827         audio_source_t source = inputSourceNameToEnum(node->name);
828         if (source == AUDIO_SOURCE_CNT) {
829             ALOGW("loadInputSources() invalid input source %s", node->name);
830             node = node->next;
831             continue;
832         }
833         ALOGV("loadInputSources() loading input source %s", node->name);
834         EffectDescVector *desc = loadEffectConfig(node, effects);
835         if (desc == NULL) {
836             node = node->next;
837             continue;
838         }
839         mInputSources.add(source, desc);
840         node = node->next;
841     }
842     return NO_ERROR;
843 }
844 
loadStreamEffectConfigurations(cnode * root,const Vector<EffectDesc * > & effects)845 status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
846                                                             const Vector <EffectDesc *>& effects)
847 {
848     cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG);
849     if (node == NULL) {
850         return -ENOENT;
851     }
852     node = node->first_child;
853     while (node) {
854         audio_stream_type_t stream = streamNameToEnum(node->name);
855         if (stream == AUDIO_STREAM_PUBLIC_CNT) {
856             ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
857             node = node->next;
858             continue;
859         }
860         ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name);
861         EffectDescVector *desc = loadEffectConfig(node, effects);
862         if (desc == NULL) {
863             node = node->next;
864             continue;
865         }
866         mOutputStreams.add(stream, desc);
867         node = node->next;
868     }
869     return NO_ERROR;
870 }
871 
loadEffect(cnode * root)872 AudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root)
873 {
874     cnode *node = config_find(root, UUID_TAG);
875     if (node == NULL) {
876         return NULL;
877     }
878     effect_uuid_t uuid;
879     if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
880         ALOGW("loadEffect() invalid uuid %s", node->value);
881         return NULL;
882     }
883     return new EffectDesc(root->name, uuid);
884 }
885 
loadEffects(cnode * root,Vector<EffectDesc * > & effects)886 status_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
887 {
888     cnode *node = config_find(root, EFFECTS_TAG);
889     if (node == NULL) {
890         return -ENOENT;
891     }
892     node = node->first_child;
893     while (node) {
894         ALOGV("loadEffects() loading effect %s", node->name);
895         EffectDesc *effect = loadEffect(node);
896         if (effect == NULL) {
897             node = node->next;
898             continue;
899         }
900         effects.add(effect);
901         node = node->next;
902     }
903     return NO_ERROR;
904 }
905 
loadAudioEffectXmlConfig()906 status_t AudioPolicyEffects::loadAudioEffectXmlConfig() {
907     auto result = effectsConfig::parse();
908     if (result.parsedConfig == nullptr) {
909         return -ENOENT;
910     }
911 
912     auto loadProcessingChain = [](auto& processingChain, auto& streams) {
913         for (auto& stream : processingChain) {
914             auto effectDescs = std::make_unique<EffectDescVector>();
915             for (auto& effect : stream.effects) {
916                 effectDescs->mEffects.add(
917                         new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
918             }
919             streams.add(stream.type, effectDescs.release());
920         }
921     };
922 
923     auto loadDeviceProcessingChain = [](auto &processingChain, auto& devicesEffects) {
924         for (auto& deviceProcess : processingChain) {
925 
926             auto effectDescs = std::make_unique<EffectDescVector>();
927             for (auto& effect : deviceProcess.effects) {
928                 effectDescs->mEffects.add(
929                         new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
930             }
931             auto deviceEffects = std::make_unique<DeviceEffects>(
932                         std::move(effectDescs), deviceProcess.type, deviceProcess.address);
933             devicesEffects.emplace(deviceProcess.address, std::move(deviceEffects));
934         }
935     };
936 
937     loadProcessingChain(result.parsedConfig->preprocess, mInputSources);
938     loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams);
939     {
940         Mutex::Autolock _l(mLock);
941         loadDeviceProcessingChain(result.parsedConfig->deviceprocess, mDeviceEffects);
942     }
943     // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors
944     return result.nbSkippedElement;
945 }
946 
loadAudioEffectConfig(const char * path)947 status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
948 {
949     cnode *root;
950     char *data;
951 
952     data = (char *)load_file(path, NULL);
953     if (data == NULL) {
954         return -ENODEV;
955     }
956     root = config_node("", "");
957     config_load(root, data);
958 
959     Vector <EffectDesc *> effects;
960     loadEffects(root, effects);
961     loadInputEffectConfigurations(root, effects);
962     loadStreamEffectConfigurations(root, effects);
963 
964     for (size_t i = 0; i < effects.size(); i++) {
965         delete effects[i];
966     }
967 
968     config_free(root);
969     free(root);
970     free(data);
971 
972     return NO_ERROR;
973 }
974 
initDefaultDeviceEffects()975 void AudioPolicyEffects::initDefaultDeviceEffects()
976 {
977     Mutex::Autolock _l(mLock);
978     for (const auto& deviceEffectsIter : mDeviceEffects) {
979         const auto& deviceEffects =  deviceEffectsIter.second;
980         for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
981             AttributionSourceState attributionSource;
982             attributionSource.packageName = "android";
983             attributionSource.token = sp<BBinder>::make();
984             sp<AudioEffect> fx = new AudioEffect(attributionSource);
985             fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0, nullptr,
986                     nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
987                     AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
988                                         deviceEffects->getDeviceAddress()});
989             status_t status = fx->initCheck();
990             if (status != NO_ERROR && status != ALREADY_EXISTS) {
991                 ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
992                       effectDesc->mName, deviceEffects->getDeviceType(),
993                       deviceEffects->getDeviceAddress().c_str());
994                 // fx goes out of scope and strong ref on AudioEffect is released
995                 continue;
996             }
997             fx->setEnabled(true);
998             ALOGV("%s(): create Fx %s added on port type=%d address=%s", __func__,
999                   effectDesc->mName, deviceEffects->getDeviceType(),
1000                   deviceEffects->getDeviceAddress().c_str());
1001             deviceEffects->mEffects.push_back(fx);
1002         }
1003     }
1004 }
1005 
1006 } // namespace android
1007