1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/*
2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * you may not use this file except in compliance with the License.
6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * You may obtain a copy of the License at
7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Unless required by applicable law or agreed to in writing, software
11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * See the License for the specific language governing permissions and
14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * limitations under the License.
15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent */
16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define LOG_TAG "EffectsFactory"
18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//#define LOG_NDEBUG 0
19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "EffectsFactory.h"
2160d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn
22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <dlfcn.h>
2360d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <stdlib.h>
2460d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <string.h>
2560d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <unistd.h>
26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
27e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/config_utils.h>
2860d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <cutils/misc.h>
2920569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi#include <cutils/properties.h>
30eb16561336e6445f7edae047998f2459e046cdfeMark Salyzyn#include <log/log.h>
3160d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn
32c2f710f89ec1a3ea8e448bfafcc02b03529cc681Mikhail Naganov#include <system/audio_effects/audio_effects_conf.h>
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
36d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid
372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// list of effect_descriptor and list of sub effects : all currently loaded
382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// It does not contain effects without sub effects.
392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic list_sub_elem_t *gSubEffectList;
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
41ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects;         // total number number of effects
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib;    // current library in enumeration process
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process
44ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx;       // current effect index in enumeration process
45e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed
48ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
49ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                          // was not modified since last call to EffectQueryNumberEffects()
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
51090eb09be1600b101b6d6e4e092f30763776bc80ragostatic list_elem_t *gLibraryFailedList;  //list of lib_failed_entry_t: libraries failed to load
52e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions prototypes
55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init();
58e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path);
59e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root);
60e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name);
61e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root);
62e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node);
632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To get and add the effect pointed by the passed node to the gSubEffectList
642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic int addSubEffect(cnode *root);
65e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path);
66ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration();
67ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects();
685e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatic int findEffect(const effect_uuid_t *type,
695e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
70e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
71e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc);
722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList
73d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic int findSubEffect(const effect_uuid_t *uuid,
742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc);
76d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
77e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid);
78e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Control Interface functions
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
84e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer);
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
104e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self,
10525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdCode,
10625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdSize,
10725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pCmdData,
10825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t *replySize,
10925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pReplyData)
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self,
130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                         effect_descriptor_t *desc)
131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int ret = init();
133e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (ret < 0) {
134e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return ret;
135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
137e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
138e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (fx->lib == NULL) {
139e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        pthread_mutex_unlock(&gLibLock);
140e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EPIPE;
141e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
142e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
143e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&gLibLock);
144e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
145e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
146e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
147e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return ret;
148e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
149e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{
152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    int ret = init();
153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (ret < 0) {
154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return ret;
155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
156ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
157ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&gLibLock);
158ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (fx->lib == NULL) {
159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        pthread_mutex_unlock(&gLibLock);
160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return -EPIPE;
161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&fx->lib->lock);
163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&gLibLock);
164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*fx->subItfe)->process_reverse != NULL) {
166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer);
167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    } else {
168ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = -ENOSYS;
169ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
170ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&fx->lib->lock);
171ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    return ret;
172ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}
173ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
174ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = {
176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Effect_Process,
177e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_Command,
178ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
179ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        NULL
180ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent};
181ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
182ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = {
183ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Process,
184ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Command,
185ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
186ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_ProcessReverse
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
188135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Factory Interface functions
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
193be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects)
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
199135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pNumEffects == NULL) {
200135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
202135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
204ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    *pNumEffects = gNumEffects;
205ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 1;
206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
2073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects);
208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
211ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
213135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
216135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
217ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (pDescriptor == NULL ||
218ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        index >= gNumEffects) {
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
221ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCanQueryEffect == 0) {
222ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -ENOSYS;
223ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = -ENOENT;
227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index < gCurEffectIdx) {
228ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        resetEffectEnumeration();
229ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
230135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (gCurLib) {
231135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (gCurEffect) {
232ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            if (index == gCurEffectIdx) {
233a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                *pDescriptor = *(effect_descriptor_t *)gCurEffect->object;
234ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                ret = 0;
235ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                break;
236ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            } else {
237ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffect = gCurEffect->next;
238ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffectIdx++;
239ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            }
240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } else {
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurLib = gCurLib->next;
242135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
245ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
246ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0)
247d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char str[512];
248d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(pDescriptor, str, sizeof(str), 0 /* indent */);
2493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryEffect() desc:%s", str);
250ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif
251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2555e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL || uuid == NULL) {
265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
268e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret == 0) {
270a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDescriptor = *d;
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2765e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
281e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_handle_t itfe;
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
286e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (uuid == NULL || pHandle == NULL) {
287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->node[3],uuid->node[4],uuid->node[5]);
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = init();
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
2985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() init error: %d", ret);
299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
302135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
304e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0){
3062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // Sub effects are not associated with the library->effects,
3072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // so, findEffect will fail. Search for the effect in gSubEffectList.
3082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = findSubEffect(uuid, &l, &d);
3092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (ret < 0 ) {
3102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            goto exit;
3112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // create effect in library
315342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent    ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
316ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (ret != 0) {
3175ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
319135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
320135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
321135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry to effect list
322135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
323135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->subItfe = itfe;
324ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*itfe)->process_reverse != NULL) {
325ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse;
3263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterfaceWithReverse");
327ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }   else {
328ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterface;
3293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterface");
330ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->lib = l;
332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
333135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = (list_elem_t *)malloc(sizeof(list_elem_t));
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = fx;
335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->next = gEffectList;
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gEffectList = e;
337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
338e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)fx;
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
347e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle)
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e1;
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e2;
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // remove effect from effect list
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e1 = gEffectList;
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e2 = NULL;
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e1) {
363e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (e1->object == handle) {
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            if (e2) {
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                e2->next = e1->next;
366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            } else {
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                gEffectList = e1->next;
368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            fx = (effect_entry_t *)e1->object;
370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            free(e1);
371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e2 = e1;
374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e1 = e1->next;
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (e1 == NULL) {
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // release effect in library
382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
3835ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectRelease() fx %p library already unloaded", handle);
384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
385135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_lock(&fx->lib->lock);
386e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        fx->lib->desc->release_effect(fx->subItfe);
387135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&fx->lib->lock);
388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
389135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    free(fx);
390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
391135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
392f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana    pthread_mutex_unlock(&gLibLock);
393135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3965e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid)
397135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
398135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
399135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
400135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
401135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 1;
402135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
403135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
4042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid
4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the
4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors
4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param
408f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube,
409f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana                        size_t size)
4102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X"
4122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->node[3],uuid->node[4],uuid->node[5]);
4152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   // Check if the size of the desc buffer is large enough for 2 subeffects
417f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana   if ((uuid == NULL) || (pSube == NULL) || (size < 2)) {
4182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       ALOGW("NULL pointer or insufficient memory. Cannot query subeffects");
4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       return -EINVAL;
4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int ret = init();
4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   if (ret < 0)
4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana      return ret;
4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   list_sub_elem_t *e = gSubEffectList;
4252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   sub_effect_entry_t *subeffect;
4262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   effect_descriptor_t *d;
4272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int count = 0;
4282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   while (e != NULL) {
4292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       d = (effect_descriptor_t*)e->object;
4302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) {
4312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGV("EffectGetSubEffects: effect found in the list");
4322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           list_elem_t *subefx = e->sub_elem;
4332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           while (subefx != NULL) {
4342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subeffect = (sub_effect_entry_t*)subefx->object;
435f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana               pSube[count++] = subeffect;
4362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subefx = subefx->next;
4372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           }
438f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana           ALOGV("EffectGetSubEffects end - copied the sub effect structures");
4392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return count;
4402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
4412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       e = e->next;
4422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   return -ENOENT;
4442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
445135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions
447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() {
450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int hdl;
451135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
452135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (gInitDone) {
453135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
454135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
45620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    // ignore effects or not?
45720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    const bool ignoreFxConfFiles = property_get_bool(PROPERTY_IGNORE_EFFECTS, false);
45820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi
459135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&gLibLock, NULL);
460135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
46120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    if (ignoreFxConfFiles) {
46220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        ALOGI("Audio effects in configuration files will be ignored");
46320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    } else {
46420569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
46520569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi            loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
46620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
46720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi            loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
46820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        }
469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
470e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
471ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    updateNumEffects();
472135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gInitDone = 1;
4733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init() done");
474135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
475135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
477e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path)
478135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
479e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *root;
480e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char *data;
481135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
482e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    data = load_file(path, NULL);
483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (data == NULL) {
484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENODEV;
485135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
486e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    root = config_node("", "");
487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_load(root, data);
488e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadLibraries(root);
489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadEffects(root);
490e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_free(root);
491e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(root);
492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(data);
493135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
495e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
496135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root)
498e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
499e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
500135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
501e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARIES_TAG);
502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
504135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
505e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadLibrary(node, node->name);
508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
509135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
510e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
511e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
512e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
5130556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#ifdef __LP64__
5140556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
5150556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const char *kLibraryPathRoot[] =
5160556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
5170556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#else
5180556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const char *kLibraryPathRoot[] =
5190556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
5200556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#endif
5210556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5220556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const int kLibraryPathRootSize =
5230556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0]));
5240556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5250556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// Checks if the library path passed as lib_path_in can be opened and if not
5260556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// tries in standard effect library directories with just the library name and returns correct path
5270556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// in lib_path_out
5280556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentint checkLibraryPath(const char *lib_path_in, char *lib_path_out) {
5290556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    char *str;
5300556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    const char *lib_name;
5310556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    size_t len;
5320556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5330556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    if (lib_path_in == NULL || lib_path_out == NULL) {
5340556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        return -EINVAL;
5350556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    }
5360556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5370556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    strlcpy(lib_path_out, lib_path_in, PATH_MAX);
5380556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5390556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    // Try exact path first
5400556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    str = strstr(lib_path_out, "/lib/soundfx/");
5410556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    if (str == NULL) {
5420556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        return -EINVAL;
5430556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    }
5440556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5450556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    // Extract library name from input path
5460556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    len = str - lib_path_out;
5470556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    lib_name = lib_path_in + len + strlen("/lib/soundfx/");
5480556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5490556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    // Then try with library name and standard path names in order of preference
5500556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    for (int i = 0; i < kLibraryPathRootSize; i++) {
5510556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        char path[PATH_MAX];
5520556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5530556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        snprintf(path,
5540556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent                 PATH_MAX,
5550556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent                 "%s/%s",
5560556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent                 kLibraryPathRoot[i],
5570556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent                 lib_name);
5580556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        if (F_OK == access(path, 0)) {
5590556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent            strcpy(lib_path_out, path);
5600556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent            ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0,
5610556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent                "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out);
5620556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent            return 0;
5630556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        }
5640556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    }
5650556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    return -EINVAL;
5660556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent}
5670556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5680556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5690556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
570e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name)
571e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
572e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
5730556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    void *hdl = NULL;
574e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    audio_effect_library_t *desc;
575e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
576e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    lib_entry_t *l;
577a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    char path[PATH_MAX];
578e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
579e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, PATH_TAG);
580e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
581e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
582135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
5830556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent
5840556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    if (checkLibraryPath((const char *)node->value, path) != 0) {
5850556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        ALOGW("loadLibrary() could not find library %s", path);
5860556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent        goto error;
5870556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent    }
588e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
589a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    hdl = dlopen(path, RTLD_NOW);
590e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl == NULL) {
591a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent        ALOGW("loadLibrary() failed to open %s", path);
592135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
593135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
594135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
595e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
596e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (desc == NULL) {
5975ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
598135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
599135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
600135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
601e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
6025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
603e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
604135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
605ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
606e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
607e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
6085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() bad lib version %08x", desc->version);
609e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
610e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
611ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
612135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry for library in gLibraryList
613135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l = malloc(sizeof(lib_entry_t));
614e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->name = strndup(name, PATH_MAX);
615a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    l->path = strndup(path, PATH_MAX);
616135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l->handle = hdl;
617e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->desc = desc;
618e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = NULL;
619135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&l->lock, NULL);
620135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
621135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = malloc(sizeof(list_elem_t));
622135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = l;
623e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
624e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = gLibraryList;
625135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gLibraryList = e;
626135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
627a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    ALOGV("getLibrary() linked library %p for path %s", l, path);
628135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
629135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
630135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
631135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror:
632e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl != NULL) {
633e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        dlclose(hdl);
634e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
635090eb09be1600b101b6d6e4e092f30763776bc80rago    //add entry for library errors in gLibraryFailedList
636090eb09be1600b101b6d6e4e092f30763776bc80rago    lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t));
637090eb09be1600b101b6d6e4e092f30763776bc80rago    fl->name = strndup(name, PATH_MAX);
638090eb09be1600b101b6d6e4e092f30763776bc80rago    fl->path = strndup(path, PATH_MAX);
639090eb09be1600b101b6d6e4e092f30763776bc80rago
640090eb09be1600b101b6d6e4e092f30763776bc80rago    list_elem_t *fe = malloc(sizeof(list_elem_t));
641090eb09be1600b101b6d6e4e092f30763776bc80rago    fe->object = fl;
642090eb09be1600b101b6d6e4e092f30763776bc80rago    fe->next = gLibraryFailedList;
643090eb09be1600b101b6d6e4e092f30763776bc80rago    gLibraryFailedList = fe;
644090eb09be1600b101b6d6e4e092f30763776bc80rago    ALOGV("getLibrary() linked error in library %p for path %s", fl, path);
645090eb09be1600b101b6d6e4e092f30763776bc80rago
646e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -EINVAL;
647135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
648135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
6492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// This will find the library and UUID tags of the sub effect pointed by the
6502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
6512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// sub_entry_t to the gSubEffectList
6522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint addSubEffect(cnode *root)
6532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
6542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect");
6552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    cnode *node;
6562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_uuid_t uuid;
6572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d;
6582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l;
6592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *e;
6602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, LIBRARY_TAG);
6612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
6622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    l = getLibrary(node->value);
6652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l == NULL) {
6662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() could not get library %s", node->value);
6672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, UUID_TAG);
6702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
6712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (stringToUuid(node->value, &uuid) != 0) {
6742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() invalid uuid %s", node->value);
6752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    d = malloc(sizeof(effect_descriptor_t));
6782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l->desc->get_descriptor(&uuid, d) != 0) {
6792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        char s[40];
6802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        uuidToString(&uuid, s, 40);
6812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Error querying effect %s on lib %s", s, l->name);
6822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
6832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#if (LOG_NDEBUG==0)
686d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
687d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
6882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
6892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#endif
6902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
6912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
6922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
6932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
6942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
6972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->object = d;
6982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // lib_entry_t is stored since the sub effects are not linked to the library
6992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->lib = l;
7002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e = malloc(sizeof(list_elem_t));
7012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->object = sub_effect;
7022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->next = gSubEffectList->sub_elem;
7032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    gSubEffectList->sub_elem = e;
7042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect end");
7052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return 0;
7062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
7072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
708e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root)
709135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
710e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
711e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
712e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, EFFECTS_TAG);
713e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
714e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
715e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
716e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
717e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
718e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffect(node);
719e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
720e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
721e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
722e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
723e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
724e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root)
725e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
726e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
727e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_uuid_t uuid;
728135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l;
729e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_descriptor_t *d;
730e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
731135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
732e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARY_TAG);
733e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
734e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
735135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
736e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
737e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l = getLibrary(node->value);
738e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l == NULL) {
7395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() could not get library %s", node->value);
740e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
741135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
742135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
743e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, UUID_TAG);
744e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
745e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
746e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
747e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (stringToUuid(node->value, &uuid) != 0) {
7485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() invalid uuid %s", node->value);
749e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
750e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
751d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    lib_entry_t *tmp;
752d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    bool skip = false;
753d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
754d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        ALOGW("skipping duplicate uuid %s %s", node->value,
755d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen                node->next ? "and its sub-effects" : "");
756d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        skip = true;
757d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
758e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
759e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    d = malloc(sizeof(effect_descriptor_t));
760e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l->desc->get_descriptor(&uuid, d) != 0) {
761e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        char s[40];
762e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        uuidToString(&uuid, s, 40);
7635ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Error querying effect %s on lib %s", s, l->name);
764e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
765e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
766e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
767e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0)
768d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
769d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
7703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("loadEffect() read descriptor %p:%s",d, s);
771e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif
772e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
773e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
775e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
776e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
777135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
778e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = malloc(sizeof(list_elem_t));
779e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->object = d;
780d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (skip) {
781d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e->next = gSkippedEffects;
782d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        gSkippedEffects = e;
783d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        return -EINVAL;
784d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    } else {
785d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e->next = l->effects;
786d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        l->effects = e;
787d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
788e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
7892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // After the UUID node in the config_tree, if node->next is valid,
7902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // that would be sub effect node.
7912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // Find the sub effects and add them to the gSubEffectList
7922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = node->next;
7932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int count = 2;
7942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    bool hwSubefx = false, swSubefx = false;
7952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *sube = NULL;
7962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node != NULL) {
7972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
7982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube = malloc(sizeof(list_sub_elem_t));
7992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->object = d;
8002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->sub_elem = NULL;
8012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->next = gSubEffectList;
8022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        gSubEffectList = sube;
8032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (node != NULL && count) {
8052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (addSubEffect(node)) {
8062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGW("loadEffect() could not add subEffect %s", node->value);
8072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           // Change the gSubEffectList to point to older list;
8082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           gSubEffectList = sube->next;
8092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube->sub_elem);// Free an already added sub effect
8102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           sube->sub_elem = NULL;
8112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube);
8122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return -ENOENT;
8132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
8142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
8152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
8162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // Since we return a dummy descriptor for the proxy during
8172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // get_descriptor call,we replace it with the correspoding
8182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // sw effect descriptor, but with Proxy UUID
8192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // check for Sw desc
8202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
8212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
8222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             swSubefx = true;
8232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             *d = *subEffectDesc;
8242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             d->uuid = uuid;
8252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             ALOGV("loadEffect() Changed the Proxy desc");
8262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       } else
8272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           hwSubefx = true;
8282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       count--;
8292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       node = node->next;
8302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
8322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (hwSubefx && swSubefx) {
8332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
8342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
835e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
836e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
837135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
8382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid
8392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for
8402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects
8412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid,
8422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
8432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc)
8442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
8452eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *e = gSubEffectList;
8462eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *subefx;
8472eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *effect;
8482eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l = NULL;
8492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d = NULL;
8502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int found = 0;
8512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int ret = 0;
8522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
8532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (uuid == NULL)
8542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
8552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
8562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (e != NULL && !found) {
8572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        subefx = (list_elem_t*)(e->sub_elem);
8582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        while (subefx != NULL) {
8592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            effect = (sub_effect_entry_t*)subefx->object;
8602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            l = (lib_entry_t *)effect->lib;
8612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            d = (effect_descriptor_t *)effect->object;
8622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
8632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                ALOGV("uuid matched");
8642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                found = 1;
8652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                break;
8662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            }
8672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            subefx = subefx->next;
8682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
8692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        e = e->next;
8702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (!found) {
8722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() effect not found");
8732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = -ENOENT;
8742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    } else {
8752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name);
8762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        *lib = l;
8772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (desc != NULL) {
8782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            *desc = d;
8792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
8802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return ret;
8822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
8832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
884e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name)
885e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
886e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
887ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
888e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (gCachedLibrary &&
889e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
890e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return gCachedLibrary;
891e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
892e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
893e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = gLibraryList;
894e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (e) {
895e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
896e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (!strcmp(l->name, name)) {
897e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            gCachedLibrary = l;
898e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            return l;
899135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
900e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        e = e->next;
901135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
902135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
903e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return NULL;
904135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
905135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
906e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
907ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration()
908ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{
909ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurLib = gLibraryList;
910ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffect = NULL;
911ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCurLib) {
912ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
913ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
914ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffectIdx = 0;
915ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent}
916135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
917ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() {
918ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    list_elem_t *e;
919be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    uint32_t cnt = 0;
920135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
921ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    resetEffectEnumeration();
922ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
923ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    e = gLibraryList;
924135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e) {
925135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
926135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
927135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
928135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            cnt++;
929135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
930135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
931135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
932135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
933ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gNumEffects = cnt;
934ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 0;
935135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return cnt;
936135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
937135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
9385e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint findEffect(const effect_uuid_t *type,
9395e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
940e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
941e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc)
942135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
943135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
944135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
945135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
946135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
947135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = 0;
948135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
949135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e && !found) {
950135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        l = (lib_entry_t *)e->object;
951135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
952135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
953135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            d = (effect_descriptor_t *)efx->object;
954e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
955e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                found = 1;
956e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                break;
957e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            }
958e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
959135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                found = 1;
960135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                break;
961135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
962135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
963135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
964135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
965135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
966135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (!found) {
9673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() effect not found");
968135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
969135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
9703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
971135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *lib = l;
972e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (desc) {
973e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            *desc = d;
974e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        }
975135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
976135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
977135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
978135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
979135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
980d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
981135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char s[256];
982d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char ss[256];
983d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char idt[indent + 1];
984d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
985d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    memset(idt, ' ', indent);
986d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    idt[indent] = 0;
987d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
988d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    str[0] = 0;
989135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
990d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
991d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, s, len);
992d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
993d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    uuidToString(&desc->uuid, s, sizeof(s));
994d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(ss, sizeof(ss), "%s  UUID: %s\n", idt, s);
995d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, ss, len);
996d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
997d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    uuidToString(&desc->type, s, sizeof(s));
998d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(ss, sizeof(ss), "%s  TYPE: %s\n", idt, s);
999d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, ss, len);
1000d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1001d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    sprintf(s, "%s  apiVersion: %08X\n%s  flags: %08X\n", idt,
1002d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            desc->apiVersion, idt, desc->flags);
1003d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, s, len);
1004135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
1005135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1006e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid)
1007e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
1008e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int tmp[10];
1009e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1010e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
1011e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
1012e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
1013e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
1014e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeLow = (uint32_t)tmp[0];
1015e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeMid = (uint16_t)tmp[1];
1016e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeHiAndVersion = (uint16_t)tmp[2];
1017e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->clockSeq = (uint16_t)tmp[3];
1018e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[0] = (uint8_t)tmp[4];
1019e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[1] = (uint8_t)tmp[5];
1020e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[2] = (uint8_t)tmp[6];
1021e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[3] = (uint8_t)tmp[7];
1022e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[4] = (uint8_t)tmp[8];
1023e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[5] = (uint8_t)tmp[9];
1024e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1025e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
1026e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
1027e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1028e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
1029e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
1030e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1031e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
1032e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeLow,
1033e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeMid,
1034e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeHiAndVersion,
1035e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->clockSeq,
1036e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[0],
1037e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[1],
1038e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[2],
1039e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[3],
1040e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[4],
1041e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[5]);
1042e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1043e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
1044e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
1045e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
1046d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenint EffectDumpEffects(int fd) {
1047d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
1048090eb09be1600b101b6d6e4e092f30763776bc80rago
1049090eb09be1600b101b6d6e4e092f30763776bc80rago    list_elem_t *fe = gLibraryFailedList;
1050090eb09be1600b101b6d6e4e092f30763776bc80rago    lib_failed_entry_t *fl = NULL;
1051090eb09be1600b101b6d6e4e092f30763776bc80rago
1052090eb09be1600b101b6d6e4e092f30763776bc80rago    dprintf(fd, "Libraries NOT loaded:\n");
1053090eb09be1600b101b6d6e4e092f30763776bc80rago
1054090eb09be1600b101b6d6e4e092f30763776bc80rago    while (fe) {
1055090eb09be1600b101b6d6e4e092f30763776bc80rago        fl = (lib_failed_entry_t *)fe->object;
1056090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, " Library %s\n", fl->name);
1057090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, "  path: %s\n", fl->path);
1058090eb09be1600b101b6d6e4e092f30763776bc80rago        fe = fe->next;
1059090eb09be1600b101b6d6e4e092f30763776bc80rago    }
1060090eb09be1600b101b6d6e4e092f30763776bc80rago
1061d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    list_elem_t *e = gLibraryList;
1062d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    lib_entry_t *l = NULL;
1063d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    effect_descriptor_t *d = NULL;
1064d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    int found = 0;
1065d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    int ret = 0;
1066d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1067090eb09be1600b101b6d6e4e092f30763776bc80rago    dprintf(fd, "Libraries loaded:\n");
1068d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    while (e) {
1069d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        l = (lib_entry_t *)e->object;
1070d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        list_elem_t *efx = l->effects;
1071090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, " Library %s\n", l->name);
1072090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, "  path: %s\n", l->path);
1073d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        if (!efx) {
1074d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "  (no effects)\n");
1075d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
1076d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while (efx) {
1077d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)efx->object;
1078d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2);
1079d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
1080d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            efx = efx->next;
1081d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
1082d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e = e->next;
1083d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
1084d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1085d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    e = gSkippedEffects;
1086d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (e) {
1087d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        dprintf(fd, "Skipped effects\n");
1088d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while(e) {
1089d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)e->object;
1090d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2 /* indent */);
1091d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
1092d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            e = e->next;
1093d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
1094d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
1095d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    return ret;
1096d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen}
1097d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1098