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