Git init
[framework/appfw/aul-1.git] / src / mime.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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
23 #include "aul.h"
24 #include "aul_api.h"
25 #include "mida.h"
26 #include "miregex.h"
27 #include <stdio.h>
28 #include <string.h>
29 #include <xdgmime.h>
30 #include <bundle.h>
31
32 #include "menu_db_util.h"
33 #include "simple_util.h"
34
35 #define MIME_APP_SELECTOR "org.tizen.app-selector"
36
37 static int __match_content_with_regex(const char *content, regex_t *regex_preg);
38 static int get_defapp_from_desktop(const char *mimetype, char *defapp, int len);
39 static int _aul_get_defapp_from_mime(const char *mimetype, char *unaliased,
40                                      char *defapp, int len_unaliased,
41                                      int len_defapp);
42 static int __launch_with_defapp(const char *mime_type, 
43                                         const char *mime_content);
44
45
46
47 static int __match_content_with_regex(const char *content, regex_t *regex_preg)
48 {
49         if (regexec(regex_preg, content, 0, NULL, 0) == 0)
50                 return 1;
51         else
52                 return 0;
53 }
54
55 SLPAPI int aul_get_mime_from_content(const char *content, char *mimetype,
56                                      int len)
57 {
58         char *founded = NULL;
59         regex_tbl *miregex_tbl = NULL;
60
61         if (content == NULL)
62                 return AUL_R_EINVAL;
63
64         if ((miregex_tbl = miregex_get_regex_table()) == NULL) {
65                 _E("load miregex_table fail\n");
66                 return AUL_R_ERROR;
67         }
68
69         while (miregex_tbl) {
70                 if (__match_content_with_regex(content,
71                         &(miregex_tbl->regex_preg))) {
72                         founded = miregex_tbl->mimetype;
73                         _D("content %s => mimetype %s\n", content, founded);
74                         break;
75                 }
76                 miregex_tbl = miregex_tbl->next;
77         }
78
79         if (founded != NULL)
80                 snprintf(mimetype, len, "%s", founded);
81         else {
82                 /* TODO : should to try to extract from share mime info's data*/
83                 return AUL_R_ERROR;
84         }
85
86         return AUL_R_OK;
87 }
88
89 SLPAPI int aul_get_mime_description(const char *mimetype, char *desc, int len)
90 {
91         regex_tbl *miregex_tbl = NULL;
92         char *founded = NULL;
93
94         if (mimetype == NULL)
95                 return AUL_R_EINVAL;
96
97         if ((miregex_tbl = miregex_get_regex_table()) == NULL) {
98                 _E("load miregex_table fail\n");
99                 return AUL_R_ERROR;
100         }
101
102         while (miregex_tbl) {
103                 if (strcmp(miregex_tbl->mimetype, mimetype) == 0) {
104                         founded = miregex_tbl->desc;
105                         _D("mimetype %s => desc %s\n", mimetype, founded);
106                         break;
107                 }
108                 miregex_tbl = miregex_tbl->next;
109         }
110
111         if (founded != NULL)
112                 snprintf(desc, len, "%s", founded);
113         else {
114                 /* TODO : should to try to extract from 
115                    share mime info's comment */
116                 return AUL_R_ERROR;
117         }
118
119         return AUL_R_OK;
120 }
121
122 SLPAPI int aul_get_mime_extension(const char *mimetype, char *ext, int len)
123 {
124         const char **extlist;
125         int totlen = 0;
126         const char *unaliased_mimetype;
127
128         if (mimetype == NULL || ext == NULL || len <= 0)
129                 return AUL_R_EINVAL;
130
131         unaliased_mimetype = xdg_mime_unalias_mime_type(mimetype);
132         if (unaliased_mimetype == NULL)
133                 return AUL_R_ERROR;
134
135         extlist = xdg_mime_get_file_names_from_mime_type(unaliased_mimetype);
136         if (extlist == NULL)
137                 return AUL_R_ERROR;
138
139         if (extlist[0] == NULL)
140                 return AUL_R_ERROR;
141
142         ext[0] = 0;
143         while (*extlist != NULL) {
144                 if (*(extlist + 1) == NULL) {
145                         snprintf(&ext[totlen], len - totlen, "%s", *extlist);
146                         break;
147                 } else {
148                         snprintf(&ext[totlen], len - totlen, "%s,", *extlist);
149                         if (strlen(*extlist) > len - totlen - 1)
150                                 break;
151                         totlen += strlen(*extlist) + 1;
152                         extlist++;
153                 }
154         }
155
156         return AUL_R_OK;
157 }
158
159 SLPAPI int aul_get_mime_icon(const char *mimetype, char *iconname, int len)
160 {
161         const char *icon;
162         const char *unaliased_mimetype;
163
164         if (mimetype == NULL || iconname == NULL || len <= 0)
165                 return AUL_R_EINVAL;
166
167         unaliased_mimetype = xdg_mime_unalias_mime_type(mimetype);
168         if (unaliased_mimetype == NULL)
169                 return AUL_R_ERROR;
170
171         icon = xdg_mime_get_icon(unaliased_mimetype);
172         if (icon == NULL)
173                 icon = xdg_mime_get_generic_icon(unaliased_mimetype);
174
175         if (icon != NULL) {
176                 snprintf(iconname, len, "%s", icon);
177                 return AUL_R_OK;
178         } else
179                 return AUL_R_ERROR;
180 }
181
182 SLPAPI int aul_get_mime_from_file(const char *filename, char *mimetype, int len)
183 {
184         const char *mime;
185         if (filename == NULL)
186                 return AUL_R_EINVAL;
187
188         if (access(filename, F_OK) != 0)
189                 return AUL_R_EINVAL;
190
191         mime = xdg_mime_get_mime_type_for_file(filename, 0);
192         if (strcmp(mime, "application/octet-stream") == 0) {
193                 mime = xdg_mime_get_mime_type_from_file_name(filename);
194         }
195
196         snprintf(mimetype, len, "%s", mime);
197         return AUL_R_OK;
198 }
199
200 SLPAPI int aul_set_defapp_with_mime(const char *mimetype, const char *defapp)
201 {
202         const char *unaliased_mimetype;
203
204         if (mimetype == NULL || defapp == NULL) {
205                 _E("invalid arg");
206                 return AUL_R_EINVAL;
207         }
208
209         unaliased_mimetype = xdg_mime_unalias_mime_type(mimetype);
210         if (unaliased_mimetype == NULL)
211                 return AUL_R_ERROR;
212
213         if (mida_add_app(unaliased_mimetype, defapp) < 0) {
214                 _E("fail to add: mimtype-%s and defapp-%s", unaliased_mimetype,
215                    defapp);
216                 return AUL_R_ERROR;
217         }
218
219         return AUL_R_OK;
220 }
221
222 static ail_cb_ret_e __defapp_with_mime_func(
223                         const ail_appinfo_h appinfo, void *user_data)
224 {
225         char **package = (char **)user_data;
226         char *str;
227
228         ail_appinfo_get_str(appinfo, AIL_PROP_PACKAGE_STR, &str);
229
230         _D("defapp from desktop = %s", str);
231
232         *package = strdup(str);
233         
234         return AIL_CB_RET_CANCEL;       /*return AIL_CB_RET_CONTINUE;*/ 
235 }
236
237 static int get_defapp_from_desktop(const char *mimetype, char *defapp, int len)
238 {
239         ail_filter_h filter;
240         ail_error_e ret;
241         int pkg_count = 0;
242         char *tmp = NULL;
243
244         ret = ail_filter_new(&filter);
245         if (ret != AIL_ERROR_OK) 
246                 return -1;
247         
248         ret = ail_filter_add_str(filter, AIL_PROP_MIMETYPE_STR, mimetype);
249         if (ret != AIL_ERROR_OK) {
250                 ret = -1;
251                 goto out;
252         }
253         
254         ail_filter_count_appinfo(filter, &pkg_count);
255
256         if (pkg_count == 1) {
257                 ail_filter_list_appinfo_foreach(filter, 
258                         __defapp_with_mime_func, (void *)&tmp);
259
260                 if(tmp) {
261                         strncpy(defapp,tmp,len);
262                         _D("defapp from desktop = %s", defapp);
263                         aul_set_defapp_with_mime(mimetype, defapp);
264                         ret = 0;
265                         free(tmp);
266                 }
267         } else 
268                 ret = -1;
269         
270 out:
271        ail_filter_destroy(filter);
272        return ret;      
273 }
274
275 SLPAPI int aul_get_defapp_from_mime(const char *mimetype, char *defapp, int len)
276 {
277         char *res;
278         const char *unaliased_mimetype;
279
280         if (mimetype == NULL || defapp == NULL || len <= 0)
281                 return AUL_R_EINVAL;
282
283         unaliased_mimetype = xdg_mime_unalias_mime_type(mimetype);
284         if (unaliased_mimetype == NULL)
285                 return AUL_R_ERROR;
286
287         /* search mida db*/
288         if ((res = mida_get_app(unaliased_mimetype)) != NULL) {
289                 snprintf(defapp, len, "%s", res);
290                 free(res);
291                 _D("Found %s for %s from mime db", defapp, unaliased_mimetype);
292                 return AUL_R_OK;
293         }
294
295         if (get_defapp_from_desktop(unaliased_mimetype, defapp, len) != 0)
296                 return AUL_R_ERROR;
297         else
298                 return AUL_R_OK;
299 }
300
301 static int _aul_get_defapp_from_mime(const char *mimetype, char *unaliased,
302                                      char *defapp, int len_unaliased,
303                                      int len_defapp)
304 {
305         char *res;
306         const char *unaliased_mimetype;
307
308         if (mimetype == NULL || unaliased == NULL || len_unaliased <= 0
309             || defapp == NULL || len_defapp <= 0)
310                 return AUL_R_EINVAL;
311
312         unaliased_mimetype = xdg_mime_unalias_mime_type(mimetype);
313         if (unaliased_mimetype == NULL)
314                 return AUL_R_ERROR;
315
316         snprintf(unaliased, len_unaliased, "%s", unaliased_mimetype);
317
318         /* search mida db*/
319         if ((res = mida_get_app(unaliased_mimetype)) != NULL) {
320                 snprintf(defapp, len_defapp, "%s", res);
321                 free(res);
322                 _D("Found %s for %s from mime db", defapp, unaliased_mimetype);
323                 return AUL_R_OK;
324         }
325
326         if (get_defapp_from_desktop(unaliased_mimetype, defapp, len_defapp) < 0)
327                 return AUL_R_ERROR;
328         else
329                 return AUL_R_OK;
330 }
331
332 static int __launch_with_defapp(const char *mime_type, const char *mime_content)
333 {
334         ail_appinfo_h handle;
335         ail_error_e ail_ret;
336         char defapp[MAX_LOCAL_BUFSZ];
337         char unaliased_mime_type[MAX_LOCAL_BUFSZ];
338         bundle *kb = NULL;
339         int ret = AUL_R_ERROR;
340
341         kb = bundle_create();
342         if (NULL == kb) {
343                 _E("bundle creation fail");
344                 return ret;
345         }
346         bundle_add(kb, AUL_K_MIME_TYPE, mime_type);
347         bundle_add(kb, AUL_K_MIME_CONTENT, mime_content);
348
349  retry:
350         if (_aul_get_defapp_from_mime
351             (mime_type, unaliased_mime_type, defapp,
352              sizeof(unaliased_mime_type), sizeof(defapp)) < 0) {
353                 _D("mimetype : %s, unaliased mimetype : %s, mime_content : %s,"
354                         " no default app", mime_type, 
355                                 unaliased_mime_type, mime_content);
356                 bundle_add(kb, AUL_K_UNALIASED_MIME_TYPE, unaliased_mime_type);
357                 ret = aul_launch_app(MIME_APP_SELECTOR, kb);
358                 /* TODO: When launching MIME APP SELECTOR, what should 
359                 be the return value? */
360                 /* Currently, it returns 0 if the app selector is launched */
361                 if (ret > 0)
362                         ret = 0;
363         } else {
364                 ail_ret = ail_package_get_appinfo(defapp, &handle);
365
366                 if (ail_ret == AIL_ERROR_OK) {
367                         ail_package_destroy_appinfo(handle);
368                         _D("mimetype : %s, unaliased mimetype : %s, "
369                                 "mime_content : %s, defapp : %s", mime_type, 
370                                         unaliased_mime_type, 
371                                                 mime_content, defapp);
372                         bundle_add(kb, AUL_K_UNALIASED_MIME_TYPE,
373                                    unaliased_mime_type);
374                         ret = aul_launch_app(defapp, kb);
375                 } else if (ail_ret == AIL_ERROR_NO_DATA) {
376                         _D("defapp %s for mimetype : %s, mime_content : %s "
377                                 "does NOT exist", defapp, 
378                                         mime_type, mime_content);
379                         mida_delete_with_pkgname(defapp);
380                         ail_package_destroy_appinfo(handle);
381                         goto retry;
382                 } else {
383                         _E("ail_package_get_appinfo with %s failed", defapp);
384                         if (kb) {
385                                 bundle_free(kb);
386                                 kb = NULL;
387                         }
388                         return ret;
389                 }       
390         }
391         bundle_free(kb);
392         return ret;
393 }
394
395 SLPAPI int aul_open_content(const char *content)
396 {
397         int ret;
398         char mime[MAX_LOCAL_BUFSZ];
399         if ((ret = aul_get_mime_from_content(content, mime, sizeof(mime))) < 0)
400                 return ret;
401
402         return __launch_with_defapp(mime, content);
403 }
404
405 SLPAPI int aul_open_file_with_mimetype(const char *filename,
406                                        const char *mimetype)
407 {
408         if (mimetype == NULL)
409                 return AUL_R_EINVAL;
410
411         return __launch_with_defapp(mimetype, filename);
412 }
413
414 SLPAPI int aul_open_file(const char *filename)
415 {
416         int ret;
417         char mime[MAX_LOCAL_BUFSZ];
418         if ((ret = aul_get_mime_from_file(filename, mime, sizeof(mime))) < 0)
419                 return ret;
420
421         return __launch_with_defapp(mime, filename);
422 }
423