Remove unused include statement
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_plugin.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <dirent.h>
28 #include <dlfcn.h>
29
30 #include "include/mm_sound_plugin.h"
31 #include <mm_error.h>
32 #include <mm_debug.h>
33
34 static char* __strcatdup(const char *str1, const char *str2);
35 static int _MMSoundPluginGetList(const char *plugdir ,char ***list);
36 static int _MMSoundPluginDestroyList(char **list);
37
38 char* MMSoundPluginGetTypeName(int type)
39 {
40     static char *typename[] = {
41         "ERROR",
42         "SOUND",
43         "RUN",
44     };
45
46     if (type < MM_SOUND_PLUGIN_TYPE_LAST && type > -1)
47         return typename[type];
48     else
49         return "Unknown"; /* error condition */
50 }
51
52 int MMSoundPluginScan(const char *plugindir, const int type, MMSoundPluginType **pluginlist)
53 {
54     char **list = NULL;
55     int err = MM_ERROR_NONE;
56     char *item = NULL;
57     int index = 0;
58     MMSoundPluginType plugin[100];
59     int plugin_index = 0;
60
61     debug_fenter ();
62
63     debug_msg(" Plugin dir :: %s \n", plugindir);
64     err = _MMSoundPluginGetList(plugindir, &list);
65     if (err != MM_ERROR_NONE)
66         return err;
67
68     while((item = list[index++]) != NULL) {
69         if(MMSoundPluginOpen(item, &plugin[plugin_index]) != MM_ERROR_NONE) {
70             debug_warning("%s is not sound plugin\n", item);
71             continue;
72         }
73         if (plugin[plugin_index].type != type)
74             MMSoundPluginClose(&plugin[plugin_index]);
75         else
76             plugin_index++;
77     }
78
79     _MMSoundPluginDestroyList(list);
80
81     *pluginlist = (MMSoundPluginType*) malloc(sizeof(MMSoundPluginType) * (plugin_index+1));
82     if ((*pluginlist) == NULL) {
83         debug_critical("Memory allocation fail\n");
84         /* Occur segmentation fault */
85         *pluginlist = (void*)1;
86     }
87
88     memcpy(*pluginlist, plugin, sizeof(MMSoundPluginType) * (plugin_index+1));
89     /* Marking end of array */
90     (*pluginlist)[plugin_index].type = MM_SOUND_PLUGIN_TYPE_NONE;
91     (*pluginlist)[plugin_index].module = NULL;
92
93     debug_fleave ();
94
95     return MM_ERROR_NONE;
96 }
97
98 int MMSoundPluginRelease(MMSoundPluginType *pluginlist)
99 {
100     int loop = 0;
101
102     debug_fenter ();
103
104     while (pluginlist[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
105         MMSoundPluginClose(&pluginlist[loop++]);
106     }
107
108     free (pluginlist);
109
110     debug_fleave ();
111
112     return MM_ERROR_NONE;
113 }
114
115 int MMSoundPluginOpen(char *file, MMSoundPluginType *plugin)
116 {
117     void *pdll = NULL;
118     int (*func)(void) = NULL;
119     int t = -1;
120
121     debug_fenter ();
122
123     pdll = dlopen(file, RTLD_NOW|RTLD_GLOBAL);
124
125     if (pdll == NULL) {
126         debug_error("%s\n", dlerror());
127         return MM_ERROR_SOUND_INVALID_FILE;
128     }
129
130     func = (int (*)(void))dlsym(pdll, "MMSoundGetPluginType");
131     if (func == NULL) {
132         dlclose(pdll);
133         debug_error("Cannot find symbol : MMSoundGetPluginType\n");
134         return MM_ERROR_SOUND_INVALID_FILE;
135     }
136     t = func();
137
138     debug_msg("%s is %s\n", file,
139                 t == MM_SOUND_PLUGIN_TYPE_CODEC ? "CODEC":
140                 t == MM_SOUND_PLUGIN_TYPE_RUN ? "RUN" : "Unknown");
141     switch(t)
142     {
143         case MM_SOUND_PLUGIN_TYPE_CODEC:
144         case MM_SOUND_PLUGIN_TYPE_RUN:
145             plugin->type = t;
146             plugin->module = pdll;
147             break;
148         default:
149             debug_error("Type is %d\n",t);
150             dlclose(pdll);
151             return MM_ERROR_SOUND_INVALID_FILE;
152     }
153
154     debug_fleave ();
155
156     return MM_ERROR_NONE;
157 }
158
159 int MMSoundPluginClose(MMSoundPluginType *plugin)
160 {
161         debug_fenter ();
162
163     if(plugin->module)
164         dlclose(plugin->module);
165     plugin->type = MM_SOUND_PLUGIN_TYPE_NONE;
166     plugin->module = NULL;
167
168     debug_fleave ();
169     return MM_ERROR_NONE;
170 }
171
172 int MMSoundPluginGetSymbol(MMSoundPluginType *plugin, const char *symbol, void **func)
173 {
174     void *fn = NULL;
175
176     debug_fenter ();
177
178     if (plugin->module == NULL)
179         return MM_ERROR_SOUND_INVALID_FILE;
180     fn = dlsym(plugin->module, symbol);
181     if (fn == NULL)
182         return MM_ERROR_SOUND_INVALID_FILE;
183     *func = fn;
184
185     debug_fleave ();
186     return MM_ERROR_NONE;
187 }
188 #define MAX_PATH_SIZE 256
189 static int _MMSoundPluginGetList(const char *plugdir ,char ***list)
190 {
191         struct dirent **entry = NULL;
192         int items;
193         struct stat finfo;
194         char **temp;
195         int tn = 0;
196         static char curdir[MAX_PATH_SIZE];
197         int item_idx;
198         int ret = MM_ERROR_NONE;
199
200         items = scandir(plugdir, &entry, NULL, alphasort);
201         debug_msg("Items %d\n", items);
202
203         if (items == -1)
204                 return MM_ERROR_INVALID_ARGUMENT;
205
206         temp = (char **)malloc(sizeof(char *) * (items + 1));
207         if(!temp) {
208                 ret = MM_ERROR_OUT_OF_MEMORY;
209                 goto free_entry;
210         }
211         memset(temp, 0, sizeof(char*) * (items + 1));
212         memset(curdir, '\0', sizeof(curdir));
213         if(NULL == getcwd(curdir, sizeof(curdir)-1)) {
214                 if (temp) {
215                         free (temp);
216                         temp = NULL;
217                 }
218                 ret = MM_ERROR_OUT_OF_STORAGE;
219                 goto free_entry;
220         }
221         /* FIXME : need to handle error case */
222         if (chdir(plugdir) != 0) {
223                 debug_error("chdir error\n");
224                 if (temp) {
225                         free (temp);
226                         temp = NULL;
227                 }
228                 ret = MM_ERROR_INVALID_ARGUMENT;
229                 goto free_entry;
230         }
231
232         for(item_idx = items; item_idx--; ) {
233                 if(stat(entry[item_idx]->d_name, &finfo) < 0) {
234                         debug_error("Stat error\n");
235                         if (temp) {
236                                 free(temp);
237                                 temp = NULL;
238                         }
239                         ret = MM_ERROR_INVALID_ARGUMENT;
240                         goto free_entry;
241                 }
242
243                 debug_log("item %d is %s\n", item_idx, entry[item_idx]->d_name);
244
245                 if (S_ISREG(finfo.st_mode)) {
246                         temp[tn++] = __strcatdup(plugdir, entry[item_idx]->d_name);
247                 }
248         }
249         *list =  temp;
250 free_entry:
251         for(item_idx = 0; item_idx < items; item_idx++) {
252                 free(entry[item_idx]);
253         }
254         free(entry);
255         return ret;
256 }
257
258 static int _MMSoundPluginDestroyList(char **list)
259 {
260         int tn = 0;
261         while(list[tn]) {
262                 free(list[tn++]);
263         }
264         free (list);
265         return MM_ERROR_NONE;
266 }
267
268 static char* __strcatdup(const char *str1, const char *str2)
269 {
270     char *dest = NULL;
271     int len = 0;
272     len = strlen(str1) + strlen(str2) + 1;
273     dest = (char*) malloc(len*sizeof(char));
274     if (!dest)
275         return NULL;
276     strncpy(dest, str1, len-1);
277     strncat(dest, str2, len-1);
278     return dest;
279 }