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"
2117217ab46e12fbdaad9e1d7460c48937f76fa0e2Eric Laurent#include <string.h>
2217217ab46e12fbdaad9e1d7460c48937f76fa0e2Eric Laurent#include <stdlib.h>
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <dlfcn.h>
24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
25e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/misc.h>
26e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/config_utils.h>
277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <audio_effects/audio_effects_conf.h>
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// list of effect_descriptor and list of sub effects : all currently loaded
322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// It does not contain effects without sub effects.
332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic list_sub_elem_t *gSubEffectList;
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
35ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects;         // total number number of effects
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib;    // current library in enumeration process
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process
38ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx;       // current effect index in enumeration process
39e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed
42ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
43ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                          // was not modified since last call to EffectQueryNumberEffects()
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
45e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions prototypes
48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init();
51e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path);
52e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root);
53e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name);
54e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root);
55e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node);
562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To get and add the effect pointed by the passed node to the gSubEffectList
572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic int addSubEffect(cnode *root);
58e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path);
59ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration();
60ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects();
615e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatic int findEffect(const effect_uuid_t *type,
625e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
63e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
64e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc);
652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList
662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid,
672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc);
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
70e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid);
71e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Control Interface functions
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
77e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer);
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
97e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self,
9825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdCode,
9925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdSize,
10025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pCmdData,
10125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t *replySize,
10225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pReplyData)
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
122e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self,
123e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                         effect_descriptor_t *desc)
124e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
125e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int ret = init();
126e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (ret < 0) {
127e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return ret;
128e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (fx->lib == NULL) {
132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        pthread_mutex_unlock(&gLibLock);
133e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EPIPE;
134e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&gLibLock);
137e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
138e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
139e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
140e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return ret;
141e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
142e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
143ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
144ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{
145ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    int ret = init();
146ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (ret < 0) {
147ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return ret;
148ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
149ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&gLibLock);
151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (fx->lib == NULL) {
152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        pthread_mutex_unlock(&gLibLock);
153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return -EPIPE;
154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&fx->lib->lock);
156ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&gLibLock);
157ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
158ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*fx->subItfe)->process_reverse != NULL) {
159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer);
160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    } else {
161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = -ENOSYS;
162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&fx->lib->lock);
164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    return ret;
165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}
166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
168135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = {
169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Effect_Process,
170e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_Command,
171ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
172ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        NULL
173ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent};
174ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
175ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = {
176ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Process,
177ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Command,
178ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
179ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_ProcessReverse
180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
181135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
183135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Factory Interface functions
184135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
185135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
186be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects)
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
188135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pNumEffects == NULL) {
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
197ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    *pNumEffects = gNumEffects;
198ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 1;
199135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
2003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects);
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
202135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
204ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
210ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (pDescriptor == NULL ||
211ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        index >= gNumEffects) {
212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
213135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
214ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCanQueryEffect == 0) {
215ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -ENOSYS;
216ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
217135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
218135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = -ENOENT;
220ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index < gCurEffectIdx) {
221ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        resetEffectEnumeration();
222ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
223135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (gCurLib) {
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (gCurEffect) {
225ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            if (index == gCurEffectIdx) {
226a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                *pDescriptor = *(effect_descriptor_t *)gCurEffect->object;
227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                ret = 0;
228ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                break;
229ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            } else {
230ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffect = gCurEffect->next;
231ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffectIdx++;
232ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            }
233135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } else {
234135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurLib = gCurLib->next;
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
236135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
238ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
239ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0)
240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char str[256];
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    dumpEffectDescriptor(pDescriptor, str, 256);
2423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryEffect() desc:%s", str);
243ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
245135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2485e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
250135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL || uuid == NULL) {
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
261e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret == 0) {
263a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDescriptor = *d;
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2695e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
274e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_handle_t itfe;
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
276135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
279e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (uuid == NULL || pHandle == NULL) {
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
281135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
286135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->node[3],uuid->node[4],uuid->node[5]);
287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = init();
289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
290135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
2915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() init error: %d", ret);
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0){
2992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // Sub effects are not associated with the library->effects,
3002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // so, findEffect will fail. Search for the effect in gSubEffectList.
3012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = findSubEffect(uuid, &l, &d);
3022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (ret < 0 ) {
3032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            goto exit;
3042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
306135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // create effect in library
308342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent    ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
309ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (ret != 0) {
3105ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
311135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry to effect list
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->subItfe = itfe;
317ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*itfe)->process_reverse != NULL) {
318ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse;
3193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterfaceWithReverse");
320ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }   else {
321ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterface;
3223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterface");
323ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
324135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->lib = l;
325135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = (list_elem_t *)malloc(sizeof(list_elem_t));
327135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = fx;
328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->next = gEffectList;
329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gEffectList = e;
330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
331e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)fx;
332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
338135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
340e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle)
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e1;
344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e2;
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // remove effect from effect list
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e1 = gEffectList;
354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e2 = NULL;
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e1) {
356e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (e1->object == handle) {
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            if (e2) {
358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                e2->next = e1->next;
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            } else {
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                gEffectList = e1->next;
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            fx = (effect_entry_t *)e1->object;
363135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            free(e1);
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e2 = e1;
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e1 = e1->next;
368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (e1 == NULL) {
370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // release effect in library
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
3765ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectRelease() fx %p library already unloaded", handle);
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_lock(&fx->lib->lock);
379e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        fx->lib->desc->release_effect(fx->subItfe);
380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&fx->lib->lock);
381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    free(fx);
383135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
385f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana    pthread_mutex_unlock(&gLibLock);
386135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
387135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3895e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid)
390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
391135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
392135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
393135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 1;
395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
396135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid
3982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the
3992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors
4002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param
401f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube,
402f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana                        size_t size)
4032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
4042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X"
4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->node[3],uuid->node[4],uuid->node[5]);
4082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
4092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   // Check if the size of the desc buffer is large enough for 2 subeffects
410f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana   if ((uuid == NULL) || (pSube == NULL) || (size < 2)) {
4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       ALOGW("NULL pointer or insufficient memory. Cannot query subeffects");
4122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       return -EINVAL;
4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int ret = init();
4152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   if (ret < 0)
4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana      return ret;
4172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   list_sub_elem_t *e = gSubEffectList;
4182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   sub_effect_entry_t *subeffect;
4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   effect_descriptor_t *d;
4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int count = 0;
4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   while (e != NULL) {
4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       d = (effect_descriptor_t*)e->object;
4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) {
4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGV("EffectGetSubEffects: effect found in the list");
4252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           list_elem_t *subefx = e->sub_elem;
4262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           while (subefx != NULL) {
4272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subeffect = (sub_effect_entry_t*)subefx->object;
428f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana               pSube[count++] = subeffect;
4292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subefx = subefx->next;
4302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           }
431f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana           ALOGV("EffectGetSubEffects end - copied the sub effect structures");
4322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return count;
4332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
4342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       e = e->next;
4352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   return -ENOENT;
4372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
438135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
439135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions
440135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
441135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
442135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() {
443135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int hdl;
444135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
445135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (gInitDone) {
446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&gLibLock, NULL);
450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
451e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
452e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
453e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
454e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
456e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
457ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    updateNumEffects();
458135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gInitDone = 1;
4593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init() done");
460135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
461135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
462135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
463e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path)
464135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
465e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *root;
466e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char *data;
467135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
468e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    data = load_file(path, NULL);
469e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (data == NULL) {
470e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENODEV;
471135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
472e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    root = config_node("", "");
473e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_load(root, data);
474e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadLibraries(root);
475e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadEffects(root);
476e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_free(root);
477e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(root);
478e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(data);
479135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
480e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
481e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
482135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root)
484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
485e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
486135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARIES_TAG);
488e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
490135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
491e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
493e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadLibrary(node, node->name);
494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
495135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
496e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
498e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
499e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name)
500e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
501e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    void *hdl;
503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    audio_effect_library_t *desc;
504e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
505e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    lib_entry_t *l;
506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, PATH_TAG);
508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
509e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
510135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
511e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
512e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    hdl = dlopen(node->value, RTLD_NOW);
513e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl == NULL) {
5145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() failed to open %s", node->value);
515135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
516135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
517135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
518e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
519e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (desc == NULL) {
5205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
521135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
522135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
523135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
524e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
5255ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
526e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
527135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
528ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
529e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
530e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
5315ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() bad lib version %08x", desc->version);
532e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
533e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
534ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
535135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry for library in gLibraryList
536135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l = malloc(sizeof(lib_entry_t));
537e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->name = strndup(name, PATH_MAX);
538e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->path = strndup(node->value, PATH_MAX);
539135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l->handle = hdl;
540e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->desc = desc;
541e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = NULL;
542135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&l->lock, NULL);
543135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
544135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = malloc(sizeof(list_elem_t));
545135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = l;
546e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
547e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = gLibraryList;
548135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gLibraryList = e;
549135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
5503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getLibrary() linked library %p for path %s", l, node->value);
551135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
552135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
553135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
554135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror:
555e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl != NULL) {
556e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        dlclose(hdl);
557e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
558e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -EINVAL;
559135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
560135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
5612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// This will find the library and UUID tags of the sub effect pointed by the
5622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
5632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// sub_entry_t to the gSubEffectList
5642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint addSubEffect(cnode *root)
5652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
5662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect");
5672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    cnode *node;
5682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_uuid_t uuid;
5692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d;
5702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l;
5712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *e;
5722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, LIBRARY_TAG);
5732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
5742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
5752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    l = getLibrary(node->value);
5772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l == NULL) {
5782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() could not get library %s", node->value);
5792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
5802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, UUID_TAG);
5822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
5832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
5842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (stringToUuid(node->value, &uuid) != 0) {
5862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() invalid uuid %s", node->value);
5872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
5882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    d = malloc(sizeof(effect_descriptor_t));
5902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l->desc->get_descriptor(&uuid, d) != 0) {
5912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        char s[40];
5922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        uuidToString(&uuid, s, 40);
5932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Error querying effect %s on lib %s", s, l->name);
5942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
5952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
5962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#if (LOG_NDEBUG==0)
5982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    char s[256];
5992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    dumpEffectDescriptor(d, s, 256);
6002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
6012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#endif
6022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
6032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
6042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
6052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
6062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
6092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->object = d;
6102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // lib_entry_t is stored since the sub effects are not linked to the library
6112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->lib = l;
6122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e = malloc(sizeof(list_elem_t));
6132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->object = sub_effect;
6142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->next = gSubEffectList->sub_elem;
6152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    gSubEffectList->sub_elem = e;
6162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect end");
6172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return 0;
6182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
6192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
620e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root)
621135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
622e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
623e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
624e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, EFFECTS_TAG);
625e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
626e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
627e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
628e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
629e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
630e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffect(node);
631e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
632e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
633e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
634e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
635e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
636e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root)
637e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
638e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
639e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_uuid_t uuid;
640135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l;
641e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_descriptor_t *d;
642e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
643135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
644e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARY_TAG);
645e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
646e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
647135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
648e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
649e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l = getLibrary(node->value);
650e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l == NULL) {
6515ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() could not get library %s", node->value);
652e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
653135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
654135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
655e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, UUID_TAG);
656e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
657e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
658e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
659e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (stringToUuid(node->value, &uuid) != 0) {
6605ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() invalid uuid %s", node->value);
661e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
662e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
663e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
664e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    d = malloc(sizeof(effect_descriptor_t));
665e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l->desc->get_descriptor(&uuid, d) != 0) {
666e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        char s[40];
667e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        uuidToString(&uuid, s, 40);
6685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Error querying effect %s on lib %s", s, l->name);
669e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
670e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
671e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
672e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0)
673e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char s[256];
674e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    dumpEffectDescriptor(d, s, 256);
6753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("loadEffect() read descriptor %p:%s",d, s);
676e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif
677e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
678e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
6795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
680e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
681e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
682135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
683e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = malloc(sizeof(list_elem_t));
684e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->object = d;
685e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = l->effects;
686e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = e;
687e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
6882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // After the UUID node in the config_tree, if node->next is valid,
6892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // that would be sub effect node.
6902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // Find the sub effects and add them to the gSubEffectList
6912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = node->next;
6922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int count = 2;
6932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    bool hwSubefx = false, swSubefx = false;
6942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *sube = NULL;
6952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node != NULL) {
6962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
6972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube = malloc(sizeof(list_sub_elem_t));
6982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->object = d;
6992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->sub_elem = NULL;
7002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->next = gSubEffectList;
7012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        gSubEffectList = sube;
7022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (node != NULL && count) {
7042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (addSubEffect(node)) {
7052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGW("loadEffect() could not add subEffect %s", node->value);
7062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           // Change the gSubEffectList to point to older list;
7072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           gSubEffectList = sube->next;
7082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube->sub_elem);// Free an already added sub effect
7092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           sube->sub_elem = NULL;
7102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube);
7112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return -ENOENT;
7122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
7132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
7142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
7152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // Since we return a dummy descriptor for the proxy during
7162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // get_descriptor call,we replace it with the correspoding
7172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // sw effect descriptor, but with Proxy UUID
7182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // check for Sw desc
7192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
7202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
7212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             swSubefx = true;
7222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             *d = *subEffectDesc;
7232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             d->uuid = uuid;
7242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             ALOGV("loadEffect() Changed the Proxy desc");
7252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       } else
7262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           hwSubefx = true;
7272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       count--;
7282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       node = node->next;
7292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
7312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (hwSubefx && swSubefx) {
7322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
7332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
734e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
735e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
736135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
7372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid
7382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for
7392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects
7402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid,
7412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
7422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc)
7432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
7442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *e = gSubEffectList;
7452eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *subefx;
7462eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *effect;
7472eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l = NULL;
7482eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d = NULL;
7492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int found = 0;
7502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int ret = 0;
7512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
7522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (uuid == NULL)
7532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
7542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
7552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (e != NULL && !found) {
7562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        subefx = (list_elem_t*)(e->sub_elem);
7572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        while (subefx != NULL) {
7582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            effect = (sub_effect_entry_t*)subefx->object;
7592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            l = (lib_entry_t *)effect->lib;
7602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            d = (effect_descriptor_t *)effect->object;
7612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
7622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                ALOGV("uuid matched");
7632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                found = 1;
7642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                break;
7652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            }
7662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            subefx = subefx->next;
7672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
7682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        e = e->next;
7692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (!found) {
7712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() effect not found");
7722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = -ENOENT;
7732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    } else {
7742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name);
7752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        *lib = l;
7762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (desc != NULL) {
7772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            *desc = d;
7782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
7792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return ret;
7812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
7822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
783e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name)
784e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
785e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
786ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
787e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (gCachedLibrary &&
788e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
789e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return gCachedLibrary;
790e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
791e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
792e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = gLibraryList;
793e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (e) {
794e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
795e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (!strcmp(l->name, name)) {
796e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            gCachedLibrary = l;
797e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            return l;
798135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
799e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        e = e->next;
800135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
801135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
802e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return NULL;
803135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
804135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
805e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
806ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration()
807ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{
808ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurLib = gLibraryList;
809ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffect = NULL;
810ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCurLib) {
811ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
812ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
813ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffectIdx = 0;
814ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent}
815135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
816ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() {
817ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    list_elem_t *e;
818be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    uint32_t cnt = 0;
819135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
820ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    resetEffectEnumeration();
821ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
822ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    e = gLibraryList;
823135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e) {
824135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
825135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
826135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
827135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            cnt++;
828135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
829135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
830135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
831135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
832ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gNumEffects = cnt;
833ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 0;
834135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return cnt;
835135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
836135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
8375e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint findEffect(const effect_uuid_t *type,
8385e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
839e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
840e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc)
841135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
842135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
843135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
844135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
845135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
846135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = 0;
847135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
848135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e && !found) {
849135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        l = (lib_entry_t *)e->object;
850135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
851135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
852135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            d = (effect_descriptor_t *)efx->object;
853e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
854e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                found = 1;
855e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                break;
856e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            }
857e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
858135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                found = 1;
859135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                break;
860135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
861135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
862135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
863135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
864135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
865135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (!found) {
8663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() effect not found");
867135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
868135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
8693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
870135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *lib = l;
871e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (desc) {
872e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            *desc = d;
873e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        }
874135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
875135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
876135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
877135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
878135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
879135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len) {
880135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char s[256];
881135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
882135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    snprintf(str, len, "\nEffect Descriptor %p:\n", desc);
883e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    strncat(str, "- TYPE: ", len);
884e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuidToString(&desc->uuid, s, 256);
885e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, len, "- UUID: %s\n", s);
886e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuidToString(&desc->type, s, 256);
887e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, len, "- TYPE: %s\n", s);
888e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    sprintf(s, "- apiVersion: %08X\n- flags: %08X\n",
889135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            desc->apiVersion, desc->flags);
890135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
891135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    sprintf(s, "- name: %s\n", desc->name);
892135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
893135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    sprintf(s, "- implementor: %s\n", desc->implementor);
894135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
895135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
896135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
897e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid)
898e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
899e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int tmp[10];
900e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
901e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
902e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
903e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
904e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
905e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeLow = (uint32_t)tmp[0];
906e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeMid = (uint16_t)tmp[1];
907e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeHiAndVersion = (uint16_t)tmp[2];
908e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->clockSeq = (uint16_t)tmp[3];
909e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[0] = (uint8_t)tmp[4];
910e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[1] = (uint8_t)tmp[5];
911e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[2] = (uint8_t)tmp[6];
912e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[3] = (uint8_t)tmp[7];
913e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[4] = (uint8_t)tmp[8];
914e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[5] = (uint8_t)tmp[9];
915e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
916e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
917e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
918e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
919e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
920e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
921e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
922e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
923e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeLow,
924e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeMid,
925e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeHiAndVersion,
926e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->clockSeq,
927e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[0],
928e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[1],
929e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[2],
930e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[3],
931e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[4],
932e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[5]);
933e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
934e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
935e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
936e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
937