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