EffectsFactory.c revision c2f710f89ec1a3ea8e448bfafcc02b03529cc681
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>
2720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi#include <cutils/properties.h>
28c2f710f89ec1a3ea8e448bfafcc02b03529cc681Mikhail Naganov#include <system/audio_effects/audio_effects_conf.h>
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
32d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid
332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// list of effect_descriptor and list of sub effects : all currently loaded
342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// It does not contain effects without sub effects.
352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic list_sub_elem_t *gSubEffectList;
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
37ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects;         // total number number of effects
38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib;    // current library in enumeration process
39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process
40ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx;       // current effect index in enumeration process
41e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed
44ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
45ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                          // was not modified since last call to EffectQueryNumberEffects()
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
47e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions prototypes
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init();
53e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path);
54e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root);
55e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name);
56e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root);
57e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node);
582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To get and add the effect pointed by the passed node to the gSubEffectList
592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic int addSubEffect(cnode *root);
60e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path);
61ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration();
62ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects();
635e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatic int findEffect(const effect_uuid_t *type,
645e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
65e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
66e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc);
672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList
68d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic int findSubEffect(const effect_uuid_t *uuid,
692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc);
71d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent);
72e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid);
73e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Control Interface functions
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
79e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer);
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
99e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self,
10025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdCode,
10125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdSize,
10225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pCmdData,
10325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t *replySize,
10425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pReplyData)
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
124e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self,
125e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                         effect_descriptor_t *desc)
126e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
127e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int ret = init();
128e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (ret < 0) {
129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return ret;
130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
133e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (fx->lib == NULL) {
134e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        pthread_mutex_unlock(&gLibLock);
135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EPIPE;
136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
137e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
138e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&gLibLock);
139e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
140e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
141e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
142e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return ret;
143e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
144e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
145ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
146ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{
147ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    int ret = init();
148ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (ret < 0) {
149ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return ret;
150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&gLibLock);
153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (fx->lib == NULL) {
154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        pthread_mutex_unlock(&gLibLock);
155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return -EPIPE;
156ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
157ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&fx->lib->lock);
158ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&gLibLock);
159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*fx->subItfe)->process_reverse != NULL) {
161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer);
162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    } else {
163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = -ENOSYS;
164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&fx->lib->lock);
166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    return ret;
167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}
168ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
169ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = {
171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Effect_Process,
172e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_Command,
173ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
174ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        NULL
175ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent};
176ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
177ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = {
178ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Process,
179ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Command,
180ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
181ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_ProcessReverse
182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
183135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
184135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
185135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Factory Interface functions
186135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
188be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects)
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pNumEffects == NULL) {
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
199ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    *pNumEffects = gNumEffects;
200ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 1;
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects);
203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
204135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
206ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
211135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
212ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (pDescriptor == NULL ||
213ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        index >= gNumEffects) {
214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
216ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCanQueryEffect == 0) {
217ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -ENOSYS;
218ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
221135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = -ENOENT;
222ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index < gCurEffectIdx) {
223ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        resetEffectEnumeration();
224ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (gCurLib) {
226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (gCurEffect) {
227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            if (index == gCurEffectIdx) {
228a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                *pDescriptor = *(effect_descriptor_t *)gCurEffect->object;
229ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                ret = 0;
230ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                break;
231ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            } else {
232ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffect = gCurEffect->next;
233ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffectIdx++;
234ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            }
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } else {
236135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurLib = gCurLib->next;
237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
240ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
241ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0)
242d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char str[512];
243d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(pDescriptor, str, sizeof(str), 0 /* indent */);
2443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryEffect() desc:%s", str);
245ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif
246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2505e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL || uuid == NULL) {
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
263e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret == 0) {
265a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDescriptor = *d;
266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2715e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
276e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_handle_t itfe;
277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
281e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (uuid == NULL || pHandle == NULL) {
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
286135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->node[3],uuid->node[4],uuid->node[5]);
289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
290135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = init();
291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
2935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() init error: %d", ret);
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
299e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0){
3012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // Sub effects are not associated with the library->effects,
3022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // so, findEffect will fail. Search for the effect in gSubEffectList.
3032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = findSubEffect(uuid, &l, &d);
3042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (ret < 0 ) {
3052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            goto exit;
3062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
308135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
309135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // create effect in library
310342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent    ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
311ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (ret != 0) {
3125ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry to effect list
317135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->subItfe = itfe;
319ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*itfe)->process_reverse != NULL) {
320ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse;
3213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterfaceWithReverse");
322ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }   else {
323ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterface;
3243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterface");
325ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->lib = l;
327135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = (list_elem_t *)malloc(sizeof(list_elem_t));
329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = fx;
330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->next = gEffectList;
331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gEffectList = e;
332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
333e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)fx;
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
338135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
340135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
342e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle)
343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e1;
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e2;
347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // remove effect from effect list
354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e1 = gEffectList;
356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e2 = NULL;
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e1) {
358e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (e1->object == handle) {
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            if (e2) {
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                e2->next = e1->next;
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            } else {
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                gEffectList = e1->next;
363135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            fx = (effect_entry_t *)e1->object;
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            free(e1);
366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e2 = e1;
369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e1 = e1->next;
370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (e1 == NULL) {
372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // release effect in library
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
3785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectRelease() fx %p library already unloaded", handle);
379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_lock(&fx->lib->lock);
381e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        fx->lib->desc->release_effect(fx->subItfe);
382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&fx->lib->lock);
383135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    free(fx);
385135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
386135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
387f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana    pthread_mutex_unlock(&gLibLock);
388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
389135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3915e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid)
392135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
393135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
396135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 1;
397135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
398135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid
4002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the
4012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors
4022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param
403f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube,
404f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana                        size_t size)
4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X"
4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
4082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
4092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->node[3],uuid->node[4],uuid->node[5]);
4102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   // Check if the size of the desc buffer is large enough for 2 subeffects
412f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana   if ((uuid == NULL) || (pSube == NULL) || (size < 2)) {
4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       ALOGW("NULL pointer or insufficient memory. Cannot query subeffects");
4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       return -EINVAL;
4152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int ret = init();
4172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   if (ret < 0)
4182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana      return ret;
4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   list_sub_elem_t *e = gSubEffectList;
4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   sub_effect_entry_t *subeffect;
4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   effect_descriptor_t *d;
4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int count = 0;
4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   while (e != NULL) {
4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       d = (effect_descriptor_t*)e->object;
4252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) {
4262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGV("EffectGetSubEffects: effect found in the list");
4272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           list_elem_t *subefx = e->sub_elem;
4282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           while (subefx != NULL) {
4292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subeffect = (sub_effect_entry_t*)subefx->object;
430f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana               pSube[count++] = subeffect;
4312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subefx = subefx->next;
4322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           }
433f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana           ALOGV("EffectGetSubEffects end - copied the sub effect structures");
4342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return count;
4352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
4362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       e = e->next;
4372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   return -ENOENT;
4392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
440135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
441135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions
442135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
443135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
444135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() {
445135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int hdl;
446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (gInitDone) {
448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
45120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    // ignore effects or not?
45220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    const bool ignoreFxConfFiles = property_get_bool(PROPERTY_IGNORE_EFFECTS, false);
45320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi
454135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&gLibLock, NULL);
455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
45620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    if (ignoreFxConfFiles) {
45720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        ALOGI("Audio effects in configuration files will be ignored");
45820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    } else {
45920569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
46020569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi            loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
46120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
46220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi            loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
46320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        }
464135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
465e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
466ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    updateNumEffects();
467135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gInitDone = 1;
4683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init() done");
469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
470135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
471135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
472e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path)
473135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
474e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *root;
475e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char *data;
476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
477e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    data = load_file(path, NULL);
478e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (data == NULL) {
479e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENODEV;
480135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
481e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    root = config_node("", "");
482e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_load(root, data);
483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadLibraries(root);
484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadEffects(root);
485e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_free(root);
486e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(root);
487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(data);
488135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
490e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
491135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root)
493e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
495135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
496e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARIES_TAG);
497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
498e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
499135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
500e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
501e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadLibrary(node, node->name);
503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
504135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
505e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name)
509e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
510e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
511e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    void *hdl;
512e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    audio_effect_library_t *desc;
513e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
514e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    lib_entry_t *l;
515a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    char path[PATH_MAX];
516a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    char *str;
517a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    size_t len;
518e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
519e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, PATH_TAG);
520e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
521e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
522135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
523a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    // audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed
524a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    strlcpy(path, node->value, PATH_MAX);
525a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent#ifdef __LP64__
526a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    str = strstr(path, "/lib/");
527a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    if (str == NULL)
528a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent        return -EINVAL;
529a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    len = str - path;
530a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    path[len] = '\0';
531a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    strlcat(path, "/lib64/", PATH_MAX);
532a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    strlcat(path, node->value + len + strlen("/lib/"), PATH_MAX);
533a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent#endif
534a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    if (strlen(path) >= PATH_MAX - 1)
535a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent        return -EINVAL;
536e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
537a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    hdl = dlopen(path, RTLD_NOW);
538e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl == NULL) {
539a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent        ALOGW("loadLibrary() failed to open %s", path);
540135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
541135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
542135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
543e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
544e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (desc == NULL) {
5455ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
546135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
547135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
548135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
549e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
5505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
551e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
552135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
553ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
554e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
555e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
5565ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadLibrary() bad lib version %08x", desc->version);
557e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
558e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
559ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
560135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry for library in gLibraryList
561135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l = malloc(sizeof(lib_entry_t));
562e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->name = strndup(name, PATH_MAX);
563a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    l->path = strndup(path, PATH_MAX);
564135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l->handle = hdl;
565e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->desc = desc;
566e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = NULL;
567135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&l->lock, NULL);
568135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
569135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = malloc(sizeof(list_elem_t));
570135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = l;
571e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
572e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = gLibraryList;
573135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gLibraryList = e;
574135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
575a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent    ALOGV("getLibrary() linked library %p for path %s", l, path);
576135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
577135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
578135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
579135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror:
580e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl != NULL) {
581e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        dlclose(hdl);
582e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
583e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -EINVAL;
584135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
585135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
5862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// This will find the library and UUID tags of the sub effect pointed by the
5872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
5882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// sub_entry_t to the gSubEffectList
5892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint addSubEffect(cnode *root)
5902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
5912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect");
5922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    cnode *node;
5932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_uuid_t uuid;
5942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d;
5952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l;
5962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *e;
5972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, LIBRARY_TAG);
5982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
5992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    l = getLibrary(node->value);
6022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l == NULL) {
6032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() could not get library %s", node->value);
6042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = config_find(root, UUID_TAG);
6072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node == NULL) {
6082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (stringToUuid(node->value, &uuid) != 0) {
6112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("addSubEffect() invalid uuid %s", node->value);
6122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    d = malloc(sizeof(effect_descriptor_t));
6152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (l->desc->get_descriptor(&uuid, d) != 0) {
6162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        char s[40];
6172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        uuidToString(&uuid, s, 40);
6182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Error querying effect %s on lib %s", s, l->name);
6192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
6202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#if (LOG_NDEBUG==0)
623d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
624d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
6252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
6262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#endif
6272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
6282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
6292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
6302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        free(d);
6312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
6322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
6332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
6342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->object = d;
6352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // lib_entry_t is stored since the sub effects are not linked to the library
6362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect->lib = l;
6372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e = malloc(sizeof(list_elem_t));
6382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->object = sub_effect;
6392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    e->next = gSubEffectList->sub_elem;
6402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    gSubEffectList->sub_elem = e;
6412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    ALOGV("addSubEffect end");
6422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return 0;
6432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
6442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
645e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root)
646135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
647e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
648e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
649e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, EFFECTS_TAG);
650e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
651e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
652e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
653e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
654e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
655e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffect(node);
656e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
657e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
658e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
659e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
660e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
661e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root)
662e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
663e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
664e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_uuid_t uuid;
665135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l;
666e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_descriptor_t *d;
667e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
668135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
669e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARY_TAG);
670e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
671e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
672135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
673e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
674e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l = getLibrary(node->value);
675e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l == NULL) {
6765ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() could not get library %s", node->value);
677e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
678135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
679135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
680e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, UUID_TAG);
681e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
682e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
683e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
684e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (stringToUuid(node->value, &uuid) != 0) {
6855ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() invalid uuid %s", node->value);
686e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
687e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
688d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    lib_entry_t *tmp;
689d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    bool skip = false;
690d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (findEffect(NULL, &uuid, &tmp, NULL) == 0) {
691d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        ALOGW("skipping duplicate uuid %s %s", node->value,
692d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen                node->next ? "and its sub-effects" : "");
693d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        skip = true;
694d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
695e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
696e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    d = malloc(sizeof(effect_descriptor_t));
697e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l->desc->get_descriptor(&uuid, d) != 0) {
698e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        char s[40];
699e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        uuidToString(&uuid, s, 40);
7005ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Error querying effect %s on lib %s", s, l->name);
701e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
702e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
703e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
704e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0)
705d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
706d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */);
7073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("loadEffect() read descriptor %p:%s",d, s);
708e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif
709e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
710e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
7115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
712e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
713e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
714135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
715e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = malloc(sizeof(list_elem_t));
716e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->object = d;
717d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (skip) {
718d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e->next = gSkippedEffects;
719d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        gSkippedEffects = e;
720d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        return -EINVAL;
721d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    } else {
722d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e->next = l->effects;
723d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        l->effects = e;
724d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
725e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
7262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // After the UUID node in the config_tree, if node->next is valid,
7272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // that would be sub effect node.
7282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // Find the sub effects and add them to the gSubEffectList
7292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    node = node->next;
7302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int count = 2;
7312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    bool hwSubefx = false, swSubefx = false;
7322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *sube = NULL;
7332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (node != NULL) {
7342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
7352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube = malloc(sizeof(list_sub_elem_t));
7362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->object = d;
7372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->sub_elem = NULL;
7382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        sube->next = gSubEffectList;
7392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        gSubEffectList = sube;
7402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (node != NULL && count) {
7422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (addSubEffect(node)) {
7432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGW("loadEffect() could not add subEffect %s", node->value);
7442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           // Change the gSubEffectList to point to older list;
7452eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           gSubEffectList = sube->next;
7462eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube->sub_elem);// Free an already added sub effect
7472eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           sube->sub_elem = NULL;
7482eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           free(sube);
7492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return -ENOENT;
7502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
7512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
7522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
7532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // Since we return a dummy descriptor for the proxy during
7542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // get_descriptor call,we replace it with the correspoding
7552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // sw effect descriptor, but with Proxy UUID
7562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       // check for Sw desc
7572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
7582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
7592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             swSubefx = true;
7602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             *d = *subEffectDesc;
7612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             d->uuid = uuid;
7622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana             ALOGV("loadEffect() Changed the Proxy desc");
7632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       } else
7642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           hwSubefx = true;
7652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       count--;
7662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       node = node->next;
7672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
7682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
7692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (hwSubefx && swSubefx) {
7702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
7712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
772e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
773e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
774135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
7752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid
7762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for
7772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects
7782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid,
7792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
7802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc)
7812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
7822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *e = gSubEffectList;
7832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *subefx;
7842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *effect;
7852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l = NULL;
7862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d = NULL;
7872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int found = 0;
7882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int ret = 0;
7892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
7902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (uuid == NULL)
7912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
7922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
7932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (e != NULL && !found) {
7942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        subefx = (list_elem_t*)(e->sub_elem);
7952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        while (subefx != NULL) {
7962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            effect = (sub_effect_entry_t*)subefx->object;
7972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            l = (lib_entry_t *)effect->lib;
7982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            d = (effect_descriptor_t *)effect->object;
7992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
8002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                ALOGV("uuid matched");
8012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                found = 1;
8022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                break;
8032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            }
8042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            subefx = subefx->next;
8052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
8062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        e = e->next;
8072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (!found) {
8092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() effect not found");
8102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = -ENOENT;
8112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    } else {
8122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name);
8132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        *lib = l;
8142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (desc != NULL) {
8152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            *desc = d;
8162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
8172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
8182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return ret;
8192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
8202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
821e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name)
822e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
823e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
824ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
825e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (gCachedLibrary &&
826e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
827e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return gCachedLibrary;
828e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
829e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
830e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = gLibraryList;
831e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (e) {
832e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
833e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (!strcmp(l->name, name)) {
834e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            gCachedLibrary = l;
835e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            return l;
836135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
837e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        e = e->next;
838135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
839135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
840e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return NULL;
841135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
842135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
843e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
844ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration()
845ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{
846ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurLib = gLibraryList;
847ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffect = NULL;
848ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCurLib) {
849ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
850ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
851ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffectIdx = 0;
852ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent}
853135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
854ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() {
855ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    list_elem_t *e;
856be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    uint32_t cnt = 0;
857135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
858ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    resetEffectEnumeration();
859ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
860ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    e = gLibraryList;
861135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e) {
862135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
863135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
864135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
865135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            cnt++;
866135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
867135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
868135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
869135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
870ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gNumEffects = cnt;
871ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 0;
872135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return cnt;
873135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
874135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
8755e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint findEffect(const effect_uuid_t *type,
8765e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten               const effect_uuid_t *uuid,
877e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
878e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc)
879135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
880135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
881135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
882135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
883135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
884135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = 0;
885135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
886135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e && !found) {
887135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        l = (lib_entry_t *)e->object;
888135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
889135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
890135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            d = (effect_descriptor_t *)efx->object;
891e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
892e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                found = 1;
893e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                break;
894e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            }
895e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
896135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                found = 1;
897135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                break;
898135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
899135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
900135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
901135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
902135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
903135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (!found) {
9043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() effect not found");
905135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
906135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
9073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
908135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *lib = l;
909e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (desc) {
910e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            *desc = d;
911e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        }
912135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
913135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
914135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
915135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
916135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
917d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) {
918135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char s[256];
919d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char ss[256];
920d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char idt[indent + 1];
921d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
922d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    memset(idt, ' ', indent);
923d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    idt[indent] = 0;
924d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
925d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    str[0] = 0;
926135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
927d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor);
928d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, s, len);
929d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
930d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    uuidToString(&desc->uuid, s, sizeof(s));
931d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(ss, sizeof(ss), "%s  UUID: %s\n", idt, s);
932d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, ss, len);
933d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
934d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    uuidToString(&desc->type, s, sizeof(s));
935d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    snprintf(ss, sizeof(ss), "%s  TYPE: %s\n", idt, s);
936d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, ss, len);
937d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
938d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    sprintf(s, "%s  apiVersion: %08X\n%s  flags: %08X\n", idt,
939d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            desc->apiVersion, idt, desc->flags);
940d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    strlcat(str, s, len);
941135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
942135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
943e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid)
944e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
945e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int tmp[10];
946e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
947e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
948e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
949e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
950e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
951e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeLow = (uint32_t)tmp[0];
952e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeMid = (uint16_t)tmp[1];
953e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeHiAndVersion = (uint16_t)tmp[2];
954e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->clockSeq = (uint16_t)tmp[3];
955e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[0] = (uint8_t)tmp[4];
956e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[1] = (uint8_t)tmp[5];
957e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[2] = (uint8_t)tmp[6];
958e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[3] = (uint8_t)tmp[7];
959e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[4] = (uint8_t)tmp[8];
960e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[5] = (uint8_t)tmp[9];
961e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
962e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
963e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
964e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
965e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
966e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
967e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
968e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
969e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeLow,
970e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeMid,
971e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeHiAndVersion,
972e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->clockSeq,
973e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[0],
974e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[1],
975e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[2],
976e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[3],
977e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[4],
978e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[5]);
979e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
980e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
981e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
982e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
983d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenint EffectDumpEffects(int fd) {
984d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
985d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    list_elem_t *e = gLibraryList;
986d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    lib_entry_t *l = NULL;
987d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    effect_descriptor_t *d = NULL;
988d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    int found = 0;
989d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    int ret = 0;
990d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
991d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    while (e) {
992d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        l = (lib_entry_t *)e->object;
993d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        list_elem_t *efx = l->effects;
994d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        dprintf(fd, "Library %s\n", l->name);
995d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        if (!efx) {
996d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "  (no effects)\n");
997d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
998d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while (efx) {
999d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)efx->object;
1000d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2);
1001d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
1002d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            efx = efx->next;
1003d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
1004d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e = e->next;
1005d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
1006d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1007d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    e = gSkippedEffects;
1008d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (e) {
1009d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        dprintf(fd, "Skipped effects\n");
1010d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while(e) {
1011d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)e->object;
1012d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2 /* indent */);
1013d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
1014d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            e = e->next;
1015d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
1016d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
1017d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    return ret;
1018d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen}
1019d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
1020