Support launch reqeust async API
[platform/core/appfw/aul-1.git] / src / service.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <bundle.h>
24 #include <bundle_internal.h>
25 #include <glib.h>
26 #include <string.h>
27 #include <pthread.h>
28 #include <dlfcn.h>
29 #include <iniparser.h>
30 #include <pkgmgr-info.h>
31
32 #include "aul.h"
33 #include "aul_api.h"
34 #include "aul_svc.h"
35 #include "aul_sock.h"
36 #include "aul_svc_db.h"
37 #include "aul_util.h"
38 #include "aul_svc_priv_key.h"
39 #include "launch.h"
40
41 #define MAX_CHECKSUM_BUF        2048
42
43 /* callback handling */
44 typedef struct _aul_svc_cb_info_t {
45         int request_code;
46         aul_svc_res_fn cb_func;
47         aul_svc_err_cb err_cb;
48         void *data;
49 } aul_svc_cb_info_t;
50
51 typedef struct _aul_svc_resolve_info_t {
52         char *pkgname;
53         char *op;
54         char *uri;
55         char *scheme;
56         char *host;
57         char *uri_r_info;
58         char *origin_mime;
59         char *mime;
60         char *m_type;
61         char *s_type;
62         char *category;
63         char *win_id;
64         int mime_set;
65 } aul_svc_resolve_info_t;
66
67 typedef struct _aul_svc_transient_cb_info_t {
68         aul_svc_host_res_fn cb_func;
69         void *data;
70 } aul_svc_transient_cb_info_t;
71
72 pthread_mutex_t iniparser_lock = PTHREAD_MUTEX_INITIALIZER;
73 GSList *tmp_list;
74
75 static aul_svc_cb_info_t *__create_rescb(int request_code,
76                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb, void *data);
77 static void __remove_rescb(aul_svc_cb_info_t *info);
78 static int __set_bundle(bundle *b, const char *key, const char *value);
79 static void __aul_cb(bundle *b, int is_cancel, void *data);
80 static int __run_svc_with_pkgname(char *pkgname, bundle *b, int request_code,
81                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb, void *data,
82                 uid_t uid, bool sync);
83 static int __get_resolve_info(bundle *b, aul_svc_resolve_info_t *info);
84 static int __free_resolve_info_data(aul_svc_resolve_info_t *info);
85
86 static char *white_list[] = {
87         APP_SELECTOR,
88         SHARE_PANEL,
89         NULL
90 };
91
92 static bool __is_special_app(const char *appid)
93 {
94         const char *id;
95         int i = 0;
96
97         if (appid == NULL)
98                 return false;
99
100         while ((id = white_list[i]) != NULL) {
101                 if (strcmp(id, appid) == 0)
102                         return true;
103                 i++;
104         }
105         return false;
106 }
107
108 static bool __is_special_operation(bundle *b)
109 {
110         const char *operation;
111         const char *white_operations[] = {
112                 "http://tizen.org/appcontrol/operation/guide_privacy_setting",
113                 NULL
114         };
115         int i;
116
117         operation = aul_svc_get_operation(b);
118         if (!operation)
119                 return false;
120
121         for (i = 0; white_operations[i]; ++i) {
122                 if (!strcmp(operation, white_operations[i]))
123                         return true;
124         }
125
126         return false;
127 }
128
129 static aul_svc_cb_info_t *__create_rescb(int request_code,
130                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb, void *data)
131 {
132         aul_svc_cb_info_t* info;
133
134         info = calloc(1, sizeof(aul_svc_cb_info_t));
135         if (info == NULL) {
136                 _E("Out of memory");
137                 return NULL;
138         }
139
140         info->request_code = request_code;
141         info->cb_func = cbfunc;
142         info->err_cb = err_cb;
143         info->data = data;
144
145         return info;
146 }
147
148 static void __remove_rescb(aul_svc_cb_info_t *info)
149 {
150         if (info)
151                 free(info);
152 }
153
154 static int __set_bundle(bundle *b, const char *key, const char *value)
155 {
156         const char *val = NULL;
157
158         val = bundle_get_val(b, key);
159         if (val) {
160                 if (bundle_del(b, key) != 0)
161                         return AUL_SVC_RET_ERROR;
162         }
163
164         if (!value)
165                 return AUL_SVC_RET_EINVAL;
166
167         if (bundle_add(b, key, value) != 0)
168                 return AUL_SVC_RET_ERROR;
169
170         _D("__set_bundle");
171
172         return AUL_SVC_RET_OK;
173 }
174
175 static int __set_bundle_array(bundle *b, const char *key,
176                                 const char **value, int len)
177 {
178
179         int type;
180         type = aul_svc_data_is_array(b, key);
181
182         if (type == 1) {
183                 if (bundle_del(b, key) != 0)
184                         return AUL_SVC_RET_ERROR;
185         }
186
187         if (!value)
188                 return AUL_SVC_RET_EINVAL;
189
190         if (bundle_add_str_array(b, key, value, len) != 0)
191                 return AUL_SVC_RET_ERROR;
192
193         _D("__set_bundle_array");
194
195         return AUL_SVC_RET_OK;
196 }
197
198 static void __aul_cb(bundle *b, int is_cancel, void *data)
199 {
200         const char *val = NULL;
201         aul_svc_cb_info_t*  cb_info;
202         int res;
203
204         if (is_cancel)
205                 res = AUL_SVC_RES_CANCEL;
206         else {
207                 /* get result_code from bundle */
208                 val = bundle_get_val(b, AUL_SVC_K_RES_VAL);
209                 res = (val == NULL) ? AUL_SVC_RES_NOT_OK : atoi(val);
210         }
211
212         /* remove result_code from bundle */
213         bundle_del(b, AUL_SVC_K_RES_VAL);
214
215         /* find corresponding callback */
216         cb_info = (aul_svc_cb_info_t*)data;
217
218         cb_info->cb_func(b, cb_info->request_code,
219                         (aul_svc_result_val)res, cb_info->data);
220         __remove_rescb(cb_info);
221
222         return;
223 }
224
225 static int __error_convert(int res)
226 {
227         switch (res) {
228         case AUL_R_EILLACC:
229                 return AUL_SVC_RET_EILLACC;
230         case AUL_R_EINVAL:
231                 return AUL_SVC_RET_EINVAL;
232         case AUL_R_ETERMINATING:
233                 return AUL_SVC_RET_ETERMINATING;
234         case AUL_R_EREJECTED:
235                 return AUL_SVC_RET_EREJECTED;
236         case AUL_R_ENOAPP:
237                 return AUL_SVC_RET_ENOMATCH;
238         default:
239                 return AUL_SVC_RET_ELAUNCH;
240         }
241 }
242
243 static void __aul_error_cb(int err, void *data)
244 {
245         aul_svc_cb_info_t *cb_info = (aul_svc_cb_info_t *)data;
246
247         if (!cb_info) {
248                 _E("Critical error!");
249                 return;
250         }
251
252         if (err < 0)
253                 err = __error_convert(err);
254
255         if (cb_info->err_cb) {
256                 cb_info->err_cb(cb_info->request_code, err, cb_info->data);
257                 cb_info->err_cb = NULL;
258         }
259 }
260
261 static int __run_svc_with_pkgname(char *pkgname, bundle *b, int request_code,
262                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
263                 void *data, uid_t uid, bool sync)
264 {
265         aul_svc_cb_info_t *cb_info = NULL;
266         int ret = -1;
267
268         if (bundle_get_type(b, AUL_SVC_K_SELECTOR_EXTRA_LIST) != BUNDLE_TYPE_NONE) {
269                 if (!aul_svc_get_pkgname(b))
270                         pkgname = APP_SELECTOR;
271         }
272
273         if (bundle_get_val(b, AUL_K_FORCE_LAUNCH_APP_SELECTOR))
274                 pkgname = APP_SELECTOR;
275
276         if (__is_special_app(pkgname) || __is_special_operation(b)) {
277                 bundle_del(b, AUL_SVC_K_CAN_BE_LEADER);
278                 bundle_add_str(b, AUL_SVC_K_CAN_BE_LEADER, "true");
279                 bundle_del(b, AUL_SVC_K_REROUTE);
280                 bundle_add_str(b, AUL_SVC_K_REROUTE, "true");
281                 bundle_del(b, AUL_SVC_K_RECYCLE);
282                 bundle_add_str(b, AUL_SVC_K_RECYCLE, "true");
283         }
284
285         if (cbfunc) {
286                 SECURE_LOGD("pkg_name : %s - with result", pkgname);
287
288                 cb_info = __create_rescb(request_code, cbfunc, err_cb, data);
289                 if (sync) {
290                         ret = aul_launch_app_with_result_for_uid(pkgname, b,
291                                         __aul_cb, cb_info, uid);
292                 } else {
293                         if (err_cb) {
294                                 ret = aul_send_launch_request_for_uid(pkgname,
295                                                 b, uid, __aul_cb,
296                                                 __aul_error_cb, cb_info);
297                         } else {
298                                 ret = aul_launch_app_with_result_async_for_uid(
299                                                 pkgname, b, __aul_cb,
300                                                 cb_info, uid);
301                         }
302                 }
303         } else {
304                 SECURE_LOGD("pkg_name : %s - no result", pkgname);
305
306 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
307                 const char* data = bundle_get_val(b, AUL_SVC_K_MULTI_INSTANCE);
308                 if (data)
309                         SECURE_LOGD("multi_instance value = %s", data);
310
311                 if (data && strncmp(data, "TRUE", strlen("TRUE")) == 0) {
312                         if (sync) {
313                                 ret = aul_launch_app_for_multi_instance(pkgname,
314                                                 b);
315                         } else {
316                                 ret = aul_launch_app_for_multi_instance_async(
317                                                 pkgname, b);
318                         }
319                 } else {
320                         if (sync)
321                                 ret = aul_launch_app(pkgname, b);
322                         else
323                                 ret = aul_launch_app_async(pkgname, b, uid);
324                 }
325 #else
326                 if (sync)
327                         ret = aul_launch_app_for_uid(pkgname, b, uid);
328                 else
329                         ret = aul_launch_app_async_for_uid(pkgname, b, uid);
330 #endif
331         }
332
333         if (ret < 0)
334                 ret = __error_convert(ret);
335
336         return ret;
337 }
338
339 static int __get_resolve_info(bundle *b, aul_svc_resolve_info_t *info)
340 {
341         char *tmp = NULL;
342         char *saveptr = NULL;
343         char *strtok_buf = NULL;
344         int ret = -1;
345
346         info->op = (char *)aul_svc_get_operation(b);
347         info->uri = (char *)aul_svc_get_uri(b);
348
349         if ((info->uri) && (strcmp(info->uri, "") == 0)) {
350                 _E("Uri is empty");
351                 return AUL_SVC_RET_EINVAL;
352         }
353
354         info->origin_mime = info->mime = (char *)aul_svc_get_mime(b);
355         info->pkgname = (char *)aul_svc_get_pkgname(b);
356         info->category = (char *)aul_svc_get_category(b);
357         info->win_id = (char *)bundle_get_val(b, AUL_SVC_K_WIN_ID);
358
359         SECURE_LOGD("getting resolve info for: operation - %s / uri - %s / mime - %s",
360                         info->op, info->uri, info->mime);
361
362         if (info->uri) {
363                 if (strncmp(info->uri, "/", 1) == 0) {
364                         if (!info->mime) {
365                                 info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE);
366                                 if (info->mime == NULL) {
367                                         _E("out of memory");
368                                         return AUL_SVC_RET_ERROR;
369                                 }
370
371                                 ret = aul_get_mime_from_file(info->uri, info->mime, MAX_MIME_STR_SIZE);
372                                 info->mime_set = 1;
373                         }
374                         info->uri = NULL;
375                 } else if (strncmp(info->uri, "file:///", 8) == 0) {
376                         if (!info->mime) {
377                                 info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE);
378                                 if (info->mime == NULL) {
379                                         _E("out of memory");
380                                         return AUL_SVC_RET_ERROR;
381                                 }
382
383                                 ret = aul_get_mime_from_file(&info->uri[7], info->mime, MAX_MIME_STR_SIZE);
384                                 info->mime_set = 1;
385                         }
386                 } else if (strncmp(info->uri, "file:/", 6) == 0) {
387                         if (!info->mime) {
388                                 info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE);
389                                 if (info->mime == NULL) {
390                                         _E("out of memory");
391                                         return AUL_SVC_RET_ERROR;
392                                 }
393
394                                 ret = aul_get_mime_from_file(&info->uri[5], info->mime, MAX_MIME_STR_SIZE);
395                                 info->mime_set = 1;
396                         }
397                 }
398
399                 if (info->mime_set == 1 && ret < 0) {
400                         _E("aul_get_mime_from_file : %d", ret);
401                         free(info->mime);
402                         info->origin_mime = info->mime = NULL;
403                         info->mime_set = 0;
404                 }
405         }
406
407         if (info->uri) {
408                 GRegex *regex;
409                 GMatchInfo *match_info;
410                 GError *error = NULL;
411
412                 regex = g_regex_new("^(([^:/?#]+):)?(//([^/?#]*))?", 0, 0, &error);
413                 if (g_regex_match(regex, info->uri, 0, &match_info) == FALSE) {
414                         g_regex_unref(regex);
415                         return AUL_SVC_RET_EINVAL;
416                 }
417
418                 info->scheme = g_match_info_fetch(match_info, 2);
419                 info->host = g_match_info_fetch(match_info, 4);
420
421                 if (info->scheme && info->host) {
422                         info->uri_r_info = malloc(MAX_SCHEME_STR_SIZE + MAX_HOST_STR_SIZE + 2);
423                         if (info->uri_r_info == NULL) {
424                                 _E("out of memory");
425                                 g_match_info_free(match_info);
426                                 g_regex_unref(regex);
427                                 return AUL_SVC_RET_ERROR;
428                         }
429
430                         snprintf(info->uri_r_info, MAX_SCHEME_STR_SIZE + MAX_HOST_STR_SIZE + 1,
431                                                 "%s://%s", info->scheme, info->host);
432                 }
433
434                 g_match_info_free(match_info);
435                 g_regex_unref(regex);
436
437         } else {
438                 info->scheme = strdup("NULL");
439         }
440
441         if (!info->mime) {
442                 info->mime = strdup("NULL");
443                 return 0;
444         }
445
446         info->m_type = calloc(1, MAX_LOCAL_BUFSZ);
447         if (info->m_type == NULL) {
448                 _E("ouf of memory");
449                 return AUL_SVC_RET_ERROR;
450         }
451
452         info->s_type = calloc(1, MAX_LOCAL_BUFSZ);
453         if (info->s_type == NULL) {
454                 _E("out of memory");
455                 free(info->m_type);
456                 return AUL_SVC_RET_ERROR;
457         }
458
459         tmp = strdup(info->mime);
460         if (tmp == NULL) {
461                 _E("out of memory");
462                 free(info->s_type);
463                 free(info->m_type);
464                 return AUL_SVC_RET_ERROR;
465         }
466
467         strtok_buf = strtok_r(tmp, "/", &saveptr);
468         if (strtok_buf)
469                 strncpy(info->m_type, strtok_buf, MAX_LOCAL_BUFSZ - 1);
470         strtok_buf = strtok_r(NULL, "/", &saveptr);
471         if (strtok_buf)
472                 strncpy(info->s_type, strtok_buf, MAX_LOCAL_BUFSZ - 1);
473         free(tmp);
474
475         if (strncmp(info->m_type, "*", 1) == 0)
476                 strncpy(info->m_type, "%", MAX_LOCAL_BUFSZ - 1);
477         if (strncmp(info->s_type, "*", 1) == 0)
478                 strncpy(info->s_type, "%", MAX_LOCAL_BUFSZ - 1);
479
480         info->mime = malloc(MAX_MIME_STR_SIZE);
481         if (info->mime == NULL) {
482                 _E("out of memory");
483                 free(info->s_type);
484                 free(info->m_type);
485                 return AUL_SVC_RET_ERROR;
486         }
487
488         snprintf(info->mime, MAX_MIME_STR_SIZE - 1,
489                         "%s/%s", info->m_type, info->s_type);
490
491         return 0;
492 }
493
494 static int __free_resolve_info_data(aul_svc_resolve_info_t *info)
495 {
496         if (info->mime)
497                 free(info->mime);
498         if (info->scheme)
499                 free(info->scheme);
500         if (info->host)
501                 free(info->host);
502         if (info->m_type)
503                 free(info->m_type);
504         if (info->s_type)
505                 free(info->s_type);
506         if (info->uri_r_info)
507                 free(info->uri_r_info);
508         if (info->mime_set)
509                 free(info->origin_mime);
510
511         return 0;
512 }
513
514 static char* __get_alias_appid(char *appid)
515 {
516         char *alias_id = NULL;
517         char *val = NULL;
518         char key_string[MAX_PACKAGE_STR_SIZE + 5];
519         dictionary *dic;
520
521         dic = iniparser_load("/usr/share/appsvc/alias.ini");
522
523         if (dic == NULL)
524                 return NULL;
525
526         snprintf(key_string, sizeof(key_string), "Alias:%s", appid);
527         pthread_mutex_lock(&iniparser_lock);
528         val = iniparser_getstring(dic, key_string, NULL);
529         pthread_mutex_unlock(&iniparser_lock);
530
531         SECURE_LOGD("alias_id : %s", val);
532
533         if (val != NULL) {
534                 alias_id = malloc(MAX_PACKAGE_STR_SIZE);
535                 if (alias_id == NULL) {
536                         _E("out of memory");
537                         iniparser_freedict(dic);
538                         return NULL;
539                 }
540
541                 strncpy(alias_id, val, MAX_PACKAGE_STR_SIZE - 1);
542         }
543
544         iniparser_freedict(dic);
545
546         return alias_id;
547 }
548
549 static char* __make_query(char *query, char *op, char *uri,
550                         char *mime, char *m_type, char *s_type)
551 {
552         char tmp[MAX_MIME_STR_SIZE] = { 0, };
553
554         query = _svc_db_query_builder_add(query, op, uri, mime, false);
555         if ((mime && strncmp(mime, "NULL", 4) != 0) &&
556                         (s_type && strncmp(s_type, "%", 1) != 0)) {
557                 snprintf(tmp, MAX_MIME_STR_SIZE - 1, "%s/*", m_type);
558                 query = _svc_db_query_builder_add(query, op, uri, tmp, false);
559         }
560
561         if ((mime && strncmp(mime, "NULL", 4) != 0) &&
562                         (m_type && strncmp(m_type, "%", 1) != 0)) {
563                 snprintf(tmp, MAX_MIME_STR_SIZE - 1, "*/*");
564                 query = _svc_db_query_builder_add(query, op, uri, tmp, false);
565         }
566
567         return query;
568 }
569
570 static char* __make_query_with_collation(char *op, char *uri, char *mime, char *m_type, char *s_type)
571 {
572         char tmp[MAX_MIME_STR_SIZE];
573         char *query = NULL;
574
575         query = _svc_db_query_builder_add(query, op, uri, mime, true);
576
577         if (mime && (strncmp(mime, "NULL", 4) != 0) &&
578                         s_type && (strncmp(s_type, "%", 1) != 0)) {
579                 snprintf(tmp, MAX_MIME_STR_SIZE - 1, "%s/*", m_type);
580                 query = _svc_db_query_builder_add(query, op, uri, tmp, true);
581         }
582         if (mime && (strncmp(mime, "NULL", 4) != 0) &&
583                         m_type && (strncmp(m_type, "%", 1) != 0)) {
584                 snprintf(tmp, MAX_MIME_STR_SIZE - 1, "*/*");
585                 query = _svc_db_query_builder_add(query, op, uri, tmp, true);
586         }
587
588         query = _svc_db_query_builder_in("ac.app_control collate appsvc_collation ", query);
589
590         return query;
591 }
592
593
594 static int __app_list_cb(pkgmgrinfo_appinfo_h handle, void *user_data)
595 {
596         char *appid = NULL;
597         GSList **app_list = (GSList **)user_data;
598         char *str = NULL;
599         GSList *iter = NULL;
600
601         pkgmgrinfo_appinfo_get_appid(handle, &str);
602         _D("Matching application is %s", str);
603
604         for (iter = tmp_list; iter != NULL; iter = g_slist_next(iter)) {
605                 if (strncmp(str, (char *)iter->data, MAX_PACKAGE_STR_SIZE - 1) == 0) {
606                         appid = strdup(str);
607                         *app_list = g_slist_append(*app_list, (void *)appid);
608                         _D("%s is added", appid);
609                 }
610         }
611
612         return 0;
613 }
614
615 static int __get_list_with_category(char *category, GSList **pkg_list, uid_t uid)
616 {
617         int ret;
618         pkgmgrinfo_appinfo_filter_h handle;
619         GSList *app_list = NULL;
620         GSList *iter = NULL;
621         char *list_item = NULL;
622
623         ret = pkgmgrinfo_appinfo_filter_create(&handle);
624         ret = pkgmgrinfo_appinfo_filter_add_string(handle,
625                                 PMINFO_APPINFO_PROP_APP_CATEGORY, category);
626
627         tmp_list = *pkg_list;
628         ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
629                                 __app_list_cb, &app_list, uid);
630         if (ret != PMINFO_R_OK) {
631                 pkgmgrinfo_appinfo_filter_destroy(handle);
632                 return -1;
633         }
634         pkgmgrinfo_appinfo_filter_destroy(handle);
635
636         for (iter = *pkg_list; iter != NULL; iter = g_slist_next(iter)) {
637                 list_item = (char *)iter->data;
638                 g_free(list_item);
639         }
640         g_slist_free(*pkg_list);
641
642         *pkg_list = app_list;
643
644         return 0;
645 }
646
647 static int __check_mainapp_mode(char *operation)
648 {
649         return 0;
650 }
651
652 static int __get_list_with_submode(char *operation, char *win_id,
653                                 GSList **pkg_list, uid_t uid)
654 {
655         int ret = 0;
656         int mainapp_mode = 0;
657
658         mainapp_mode = __check_mainapp_mode(operation);
659
660         SECURE_LOGD("mainapp_mode : %d", mainapp_mode);
661
662         ret = _svc_db_adjust_list_with_submode(mainapp_mode, win_id, pkg_list, uid);
663
664         if (ret < 0) {
665                 _E("error: %d", ret);
666                 return -1;
667         }
668
669         return 0;
670 }
671
672 static void __free_pkg_list(GSList *list)
673 {
674         char *list_item;
675         GSList *iter = NULL;
676
677         if (list == NULL)
678                 return;
679
680         for (iter = list; iter != NULL; iter = g_slist_next(iter)) {
681                 list_item = (char *)iter->data;
682                 g_free(list_item);
683         }
684         g_slist_free(list);
685 }
686
687 static gchar *__make_checksum(const char *op, const char *uri, const char *mime)
688 {
689         char buf[MAX_CHECKSUM_BUF];
690         gchar *checksum;
691
692         snprintf(buf, sizeof(buf), "%s:%s:%s", op, uri, mime);
693         checksum = g_compute_checksum_for_string(G_CHECKSUM_MD5, buf, -1);
694
695         return checksum;
696 }
697
698 static char *__get_cache(const char *checksum, uid_t uid)
699 {
700         app_pkt_t *pkt = NULL;
701         int fd;
702         int ret;
703         bundle *b;
704         char buf[MAX_PID_STR_BUFSZ];
705         char *appid;
706
707         b = bundle_create();
708         if (b == NULL) {
709                 _E("out of memory");
710                 return NULL;
711         }
712
713         snprintf(buf, sizeof(buf), "%d", uid);
714         bundle_add(b, AUL_K_TARGET_UID, buf);
715         bundle_add(b, AUL_K_CHECKSUM, checksum);
716
717         fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, APP_GET_APPID_FROM_CACHE,
718                         b, AUL_SOCK_ASYNC);
719         bundle_free(b);
720         if (fd <= 0)
721                 return NULL;
722
723         ret = aul_sock_recv_reply_pkt(fd, &pkt);
724         if (ret < 0)
725                 return NULL;
726
727         if (pkt->cmd == APP_GET_APPID_FROM_CACHE) {
728                 if (pkt->data[0] == 0) {
729                         free(pkt);
730                         return NULL;
731                 }
732                 appid = strdup((const char *)(pkt->data));
733                 free(pkt);
734                 return appid;
735         }
736         free(pkt);
737
738         return NULL;
739 }
740
741 static void __put_cache(const char *checksum, const char *appid, uid_t uid)
742 {
743         int ret;
744         bundle *b;
745         char buf[MAX_PID_STR_BUFSZ];
746
747         b = bundle_create();
748         if (!b) {
749                 _E("out of memory");
750                 return;
751         }
752
753         snprintf(buf, sizeof(buf), "%d", uid);
754         bundle_add(b, AUL_K_TARGET_UID, buf);
755         bundle_add(b, AUL_K_CHECKSUM, checksum);
756         bundle_add(b, AUL_K_APPID, appid);
757
758         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_SET_CACHE, b);
759
760         if (ret < 0)
761                 _E("Failed to set cache : %d", ret);
762
763         bundle_free(b);
764 }
765
766 static void __put_cache_with_info(const char *checksum, const char *info, uid_t uid)
767 {
768         char buf[PATH_MAX];
769
770         snprintf(buf, sizeof(buf), "@APP_SELECTOR %s", info);
771         __put_cache(checksum, buf, uid);
772 }
773
774 static void __invalidate_cache(uid_t uid)
775 {
776         int ret;
777         bundle *b;
778         char buf[MAX_PID_STR_BUFSZ];
779
780         b = bundle_create();
781         if (!b) {
782                 _E("out of memory");
783                 return;
784         }
785
786         snprintf(buf, sizeof(buf), "%d", uid);
787         bundle_add(b, AUL_K_TARGET_UID, buf);
788         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_INVALIDATE_CACHE, b);
789
790         if (ret < 0)
791                 _E("Failed to invalidate cache : %d", ret);
792
793         bundle_free(b);
794 }
795
796 API int aul_svc_set_operation(bundle *b, const char *operation)
797 {
798         if (b == NULL) {
799                 _E("bundle is NULL");
800                 return AUL_SVC_RET_EINVAL;
801         }
802
803         return __set_bundle(b, AUL_SVC_K_OPERATION, operation);
804 }
805
806 API int aul_svc_set_uri(bundle *b, const char *uri)
807 {
808         if (b == NULL) {
809                 _E("bundle is NULL");
810                 return AUL_SVC_RET_EINVAL;
811         }
812
813         return __set_bundle(b, AUL_SVC_K_URI, uri);
814 }
815
816 API int aul_svc_set_mime(bundle *b, const char *mime)
817 {
818         if (b == NULL) {
819                 _E("bundle is NULL");
820                 return AUL_SVC_RET_EINVAL;
821         }
822
823         return __set_bundle(b, AUL_SVC_K_MIME, mime);
824 }
825
826 API int aul_svc_add_data(bundle *b, const char *key, const char *val)
827 {
828         if (b == NULL || key == NULL)
829                 return AUL_SVC_RET_EINVAL;
830
831         /* check key for data */
832         /******************/
833
834         return __set_bundle(b, key, val);
835 }
836
837 API int aul_svc_add_data_array(bundle *b, const char *key,
838                                 const char **val_array, int len)
839 {
840         if (b == NULL || key == NULL)
841                 return AUL_SVC_RET_EINVAL;
842
843         /* check key for data */
844         /******************/
845
846         return __set_bundle_array(b, key, val_array, len);
847 }
848
849 API int aul_svc_set_pkgname(bundle *b, const char *pkg_name)
850 {
851         if (b == NULL) {
852                 _E("bundle is NULL");
853                 return AUL_SVC_RET_EINVAL;
854         }
855
856         return __set_bundle(b, AUL_SVC_K_PKG_NAME, pkg_name);
857 }
858
859 API int aul_svc_set_appid(bundle *b, const char *appid)
860 {
861         char *alias_id = NULL;
862         int ret;
863
864         if (b == NULL || appid == NULL) {
865                 _E("bundle is NULL");
866                 return AUL_SVC_RET_EINVAL;
867         }
868
869         alias_id = __get_alias_appid((char *)appid);
870         if (alias_id == NULL) {
871                 ret = __set_bundle(b, AUL_SVC_K_PKG_NAME, appid);
872         } else {
873                 ret = __set_bundle(b, AUL_SVC_K_PKG_NAME, alias_id);
874                 free(alias_id);
875                 alias_id = NULL;
876         }
877
878         return ret;
879 }
880
881 API int aul_svc_set_category(bundle *b, const char *category)
882 {
883         if (b == NULL) {
884                 _E("bundle is NULL");
885                 return AUL_SVC_RET_EINVAL;
886         }
887
888         return __set_bundle(b, AUL_SVC_K_CATEGORY, category);
889 }
890
891 API int aul_svc_set_launch_mode(bundle *b, const char *mode)
892 {
893         if (b == NULL) {
894                 _E("bundle is NULL");
895                 return AUL_SVC_RET_EINVAL;
896         }
897
898         return __set_bundle(b, AUL_SVC_K_LAUNCH_MODE, mode);
899 }
900
901 static int __run_service(bundle *b, int request_code,
902                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
903                 void *data, uid_t uid, bool sync)
904 {
905         aul_svc_resolve_info_t info;
906         char *pkgname;
907         char *operation;
908         int pkg_count = 0;
909         int ret = -1;
910         char *appid;
911         int l;
912         GSList *pkg_list = NULL;
913         char *query = NULL;
914         gchar *checksum;
915
916         if (b == NULL) {
917                 _E("bundle is NULL");
918                 return AUL_SVC_RET_EINVAL;
919         }
920
921         pkgname = (char *)aul_svc_get_pkgname(b);
922         operation = (char *)aul_svc_get_operation(b);
923
924         /* explict*/
925         if (pkgname) {
926                 if (operation == NULL)
927                         aul_svc_set_operation(b, AUL_SVC_OPERATION_DEFAULT);
928                 ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc,
929                                 err_cb, data, uid, sync);
930                 return ret;
931         }
932
933         /* share panel */
934         if (TIZEN_FEATURE_SHARE_PANEL
935                 && (operation && (strcmp(operation, AUL_SVC_OPERATION_SHARE) == 0
936                 || strcmp(operation, AUL_SVC_OPERATION_MULTI_SHARE) == 0
937                 || strcmp(operation, AUL_SVC_OPERATION_SHARE_TEXT) == 0))) {
938                 ret = __run_svc_with_pkgname(SHARE_PANEL, b, request_code,
939                                 cbfunc, err_cb, data, uid, sync);
940                 return ret;
941         }
942
943         memset(&info, 0, sizeof(aul_svc_resolve_info_t));
944         ret = __get_resolve_info(b, &info);
945         if (ret < 0) {
946                 __free_resolve_info_data(&info);
947                 return ret;
948         }
949
950         SECURE_LOGD("op - %s / mime - %s / scheme - %s",
951                                         info.op, info.origin_mime, info.scheme);
952
953         checksum = __make_checksum(info.op, info.uri, info.origin_mime);
954         appid = __get_cache(checksum, uid);
955
956         if (appid) {
957                 _D("Hit! %s / %s", checksum, appid);
958                 l = strlen("@APP_SELECTOR ");
959                 if (!strncmp("@APP_SELECTOR ", appid, l)) {
960                         bundle_add(b, AUL_SVC_K_URI_R_INFO, &appid[l]);
961                         ret = __run_svc_with_pkgname(APP_SELECTOR, b,
962                                         request_code, cbfunc, err_cb,
963                                         data, uid, sync);
964                 } else if (!strcmp(appid, "^")) {
965                         ret = AUL_SVC_RET_ENOMATCH;
966                 } else {
967                         ret = __run_svc_with_pkgname(appid, b, request_code,
968                                 cbfunc, err_cb, data, uid, sync);
969                 }
970                 free(appid);
971                 g_free(checksum);
972                 __free_resolve_info_data(&info);
973                 return ret;
974         }
975
976         ret = _svc_db_check_perm(uid, true);
977         if (ret < 0) {
978                 _E("permission error : %d", ret);
979                 ret = AUL_SVC_RET_EILLACC;
980                 goto end;
981         }
982
983         /*uri*/
984         pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri, uid);
985         if (pkgname != NULL) {
986                 __put_cache(checksum, pkgname, uid);
987                 ret = __run_svc_with_pkgname(pkgname, b, request_code,
988                         cbfunc, err_cb, data, uid, sync);
989                 free(pkgname);
990                 goto end;
991         }
992
993         query = __make_query_with_collation(info.op, info.uri,
994                         info.mime, info.m_type, info.s_type);
995
996         query = _svc_db_query_builder_build(query);
997         _svc_db_exec_query(query, &pkg_list, uid);
998         if (query) {
999                 free(query);
1000                 query = NULL;
1001         }
1002
1003         pkg_count = g_slist_length(pkg_list);
1004         if (pkg_count > 0) {
1005                 __free_pkg_list(pkg_list);
1006                 pkg_list = NULL;
1007                 if (info.uri_r_info) {
1008                         query = __make_query(query, info.op, info.uri_r_info,
1009                                 info.mime, info.m_type, info.s_type);
1010                 }
1011
1012                 query = __make_query(query, info.op, info.scheme,
1013                         info.mime, info.m_type, info.s_type);
1014
1015                 query = __make_query(query, info.op, "*",
1016                         info.mime, info.m_type, info.s_type);
1017
1018                 if (info.scheme && (strcmp(info.scheme, "file") == 0)
1019                         && info.mime && (strcmp(info.mime, "NULL") != 0)) {
1020                         query = __make_query(query, info.op, "NULL",
1021                                 info.mime, info.m_type, info.s_type);
1022                 }
1023
1024                 query = _svc_db_query_builder_build(query);
1025                 _svc_db_exec_query(query, &pkg_list, uid);
1026                 if (query) {
1027                         free(query);
1028                         query = NULL;
1029                 }
1030
1031                 if (info.category)
1032                         __get_list_with_category(info.category, &pkg_list, uid);
1033
1034                 __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
1035
1036                 pkg_count = g_slist_length(pkg_list);
1037                 _D("pkg_count : %d", pkg_count);
1038
1039                 if (pkg_count == 1) {
1040                         pkgname = (char *)pkg_list->data;
1041                         if (pkgname != NULL) {
1042                                 __put_cache(checksum, pkgname, uid);
1043                                 ret = __run_svc_with_pkgname(pkgname, b, request_code,
1044                                                 cbfunc, err_cb, data, uid, sync);
1045                                 goto end;
1046                         }
1047                 } else if (pkg_count > 1) {
1048                         bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri);
1049                         __put_cache_with_info(checksum, info.uri, uid);
1050                         ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
1051                                         cbfunc, err_cb, data, uid, sync);
1052                         goto end;
1053                 }
1054                 __free_pkg_list(pkg_list);
1055                 pkg_list = NULL;
1056         }
1057
1058         /*scheme & host*/
1059         if (info.uri_r_info) {
1060                 pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri_r_info, uid);
1061
1062                 if (pkgname != NULL) {
1063                         __put_cache(checksum, pkgname, uid);
1064                         ret = __run_svc_with_pkgname(pkgname, b, request_code,
1065                                         cbfunc, err_cb, data, uid, sync);
1066                         free(pkgname);
1067                         goto end;
1068                 }
1069
1070                 query = __make_query(query, info.op, info.uri_r_info,
1071                         info.mime, info.m_type, info.s_type);
1072                 query = _svc_db_query_builder_build(query);
1073                 _svc_db_exec_query(query, &pkg_list, uid);
1074                 if (query) {
1075                         free(query);
1076                         query = NULL;
1077                 }
1078
1079                 pkg_count = g_slist_length(pkg_list);
1080                 if (pkg_count > 0) {
1081                         __free_pkg_list(pkg_list);
1082                         pkg_list = NULL;
1083                         query = __make_query(query, info.op, "*",
1084                         info.mime, info.m_type, info.s_type);
1085
1086                         if (info.scheme && (strcmp(info.scheme, "file") == 0)
1087                                 && info.mime && (strcmp(info.mime, "NULL") != 0)) {
1088                                 query = __make_query(query, info.op, "NULL",
1089                                         info.mime, info.m_type, info.s_type);
1090                         }
1091
1092                         query = _svc_db_query_builder_build(query);
1093                         _svc_db_exec_query(query, &pkg_list, uid);
1094                         if (query) {
1095                                 free(query);
1096                                 query = NULL;
1097                         }
1098
1099                         if (info.category)
1100                                 __get_list_with_category(info.category, &pkg_list, uid);
1101
1102                         __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
1103
1104                         pkg_count = g_slist_length(pkg_list);
1105                         _D("pkg_count : %d", pkg_count);
1106
1107                         if (pkg_count == 1) {
1108                                 pkgname = (char *)pkg_list->data;
1109                                 if (pkgname != NULL) {
1110                                         __put_cache(checksum, pkgname, uid);
1111                                         ret = __run_svc_with_pkgname(pkgname, b, request_code,
1112                                                         cbfunc, err_cb, data, uid, sync);
1113                                         goto end;
1114                                 }
1115                         } else if (pkg_count > 1) {
1116                                 bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri_r_info);
1117                                 __put_cache_with_info(checksum, info.uri_r_info, uid);
1118                                 ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
1119                                         cbfunc, err_cb, data, uid, sync);
1120                                 goto end;
1121                         }
1122
1123                         __free_pkg_list(pkg_list);
1124                         pkg_list = NULL;
1125                 }
1126         }
1127
1128         /*scheme*/
1129         pkgname = _svc_db_get_app(info.op, info.origin_mime, info.scheme, uid);
1130
1131         if (pkgname != NULL) {
1132                 __put_cache(checksum, pkgname, uid);
1133                 ret = __run_svc_with_pkgname(pkgname, b, request_code,
1134                         cbfunc, err_cb, data, uid, sync);
1135                 free(pkgname);
1136                 goto end;
1137         }
1138
1139         query = __make_query(query, info.op, info.scheme,
1140                 info.mime, info.m_type, info.s_type);
1141
1142         query = __make_query(query, info.op, "*",
1143                 info.mime, info.m_type, info.s_type);
1144
1145         if (info.scheme && (strcmp(info.scheme, "file") == 0)
1146                         && info.mime && (strcmp(info.mime, "NULL") != 0)) {
1147                 query = __make_query(query, info.op, "NULL",
1148                         info.mime, info.m_type, info.s_type);
1149         }
1150
1151         query = _svc_db_query_builder_build(query);
1152         _svc_db_exec_query(query, &pkg_list, uid);
1153
1154         if (query) {
1155                 free(query);
1156                 query = NULL;
1157         }
1158
1159         if (info.category)
1160                 __get_list_with_category(info.category, &pkg_list, uid);
1161
1162         __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
1163
1164         pkg_count = g_slist_length(pkg_list);
1165         _D("pkg_count : %d", pkg_count);
1166
1167         if (pkg_count == 1) {
1168                 pkgname = (char *)pkg_list->data;
1169                 if (pkgname != NULL) {
1170                         __put_cache(checksum, pkgname, uid);
1171                         ret = __run_svc_with_pkgname(pkgname, b, request_code,
1172                                         cbfunc, err_cb, data, uid, sync);
1173                 }
1174         } else if (pkg_count < 1) {
1175                 __free_resolve_info_data(&info);
1176                 __put_cache(checksum, "^", uid);
1177                 g_free(checksum);
1178                 return AUL_SVC_RET_ENOMATCH;
1179         } else {
1180                 bundle_add(b, AUL_SVC_K_URI_R_INFO, info.scheme);
1181                 __put_cache_with_info(checksum, info.scheme, uid);
1182                 ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code,
1183                                 cbfunc, err_cb, data, uid, sync);
1184         }
1185
1186 end:
1187         __free_pkg_list(pkg_list);
1188         __free_resolve_info_data(&info);
1189         g_free(checksum);
1190
1191         return ret;
1192 }
1193
1194 API int aul_svc_run_service(bundle *b, int request_code,
1195                 aul_svc_res_fn cbfunc, void *data)
1196 {
1197         return __run_service(b, request_code, cbfunc, NULL, data,
1198                         getuid(), true);
1199 }
1200
1201 API int aul_svc_run_service_for_uid(bundle *b, int request_code,
1202                 aul_svc_res_fn cbfunc, void *data, uid_t uid)
1203 {
1204         return __run_service(b, request_code, cbfunc, NULL, data, uid, true);
1205 }
1206
1207 API int aul_svc_get_list(bundle *b, aul_svc_info_iter_fn iter_fn,
1208                 void *data)
1209 {
1210         return aul_svc_get_list_for_uid(b, iter_fn, data, getuid());
1211 }
1212
1213 API int aul_svc_get_list_for_uid(bundle *b, aul_svc_info_iter_fn iter_fn,
1214                 void *data, uid_t uid)
1215 {
1216         aul_svc_resolve_info_t info;
1217         char *pkgname = NULL;
1218         int pkg_count;
1219         int ret = -1;
1220
1221         GSList *pkg_list = NULL;
1222         GSList *iter = NULL;
1223         char *query = NULL;
1224         char *query2 = NULL;
1225
1226         if (b == NULL) {
1227                 _E("bundle is NULL");
1228                 return AUL_SVC_RET_EINVAL;
1229         }
1230
1231         if (iter_fn == NULL) {
1232                 _E("iter_fn is NULL");
1233                 return AUL_SVC_RET_EINVAL;
1234         }
1235
1236
1237         /* parse bundle */
1238         memset(&info, 0, sizeof(aul_svc_resolve_info_t));
1239         ret = __get_resolve_info(b, &info);
1240         if (ret < 0) {
1241                 __free_resolve_info_data(&info);
1242                 return ret;
1243         }
1244
1245         _D("operation - %s / shceme - %s / mime - %s", info.op, info.scheme,
1246            info.mime);
1247
1248         query2 = __make_query_with_collation(info.op, info.uri,
1249                         info.mime, info.m_type, info.s_type);
1250
1251         if (info.uri_r_info) {
1252                 query = __make_query(query, info.op, info.uri_r_info,
1253                         info.mime, info.m_type, info.s_type);
1254         }
1255
1256         query = __make_query(query, info.op, info.scheme,
1257                 info.mime, info.m_type, info.s_type);
1258
1259         query = __make_query(query, info.op, "*",
1260                 info.mime, info.m_type, info.s_type);
1261
1262         if (info.scheme && (strcmp(info.scheme, "file") == 0)
1263                 && info.mime && (strcmp(info.mime, "NULL") != 0)) {
1264                 query = __make_query(query, info.op, "NULL",
1265                         info.mime, info.m_type, info.s_type);
1266         }
1267
1268         query = _svc_db_query_builder_or(query2, query);
1269         query = _svc_db_query_builder_build(query);
1270         _svc_db_exec_query(query, &pkg_list, uid);
1271         if (query) {
1272                 free(query);
1273                 query = NULL;
1274         }
1275
1276         if (info.category)
1277                 __get_list_with_category(info.category, &pkg_list, uid);
1278
1279         __get_list_with_submode(info.op, info.win_id, &pkg_list, uid);
1280
1281         pkg_count = g_slist_length(pkg_list);
1282         if (pkg_count == 0) {
1283                 _E("Cannot find associated application");
1284
1285                 __free_resolve_info_data(&info);
1286                 return AUL_SVC_RET_ENOMATCH;
1287         }
1288
1289         for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) {
1290                 pkgname = iter->data;
1291                 SECURE_LOGD("PKGNAME : %s", pkgname);
1292                 if (iter_fn(pkgname, data) != 0)
1293                         break;
1294                 g_free(pkgname);
1295         }
1296
1297         g_slist_free(pkg_list);
1298         __free_resolve_info_data(&info);
1299
1300         return AUL_SVC_RET_OK;
1301 }
1302
1303 API int aul_svc_get_all_defapps(aul_svc_info_iter_fn iter_fn, void *data)
1304 {
1305         return aul_svc_get_all_defapps_for_uid(iter_fn, data, getuid());
1306 }
1307
1308 API int aul_svc_get_all_defapps_for_uid(aul_svc_info_iter_fn iter_fn,
1309                 void *data, uid_t uid)
1310 {
1311         char *pkgname = NULL;
1312         int ret = -1;
1313
1314         GSList *pkg_list = NULL;
1315         GSList *iter = NULL;
1316
1317
1318         ret = _svc_db_check_perm(uid, true);
1319         if (ret < 0) {
1320                 _E("permission error : %d", ret);
1321                 return AUL_SVC_RET_EILLACC;
1322         }
1323
1324         ret = _svc_db_get_list_with_all_defapps(&pkg_list, uid);
1325         if (ret < 0)
1326                 return ret;
1327
1328         for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) {
1329                 pkgname = iter->data;
1330                 if (iter_fn(pkgname, data) != 0)
1331                         break;
1332                 g_free(pkgname);
1333         }
1334
1335         g_slist_free(pkg_list);
1336
1337         return AUL_SVC_RET_OK;
1338 }
1339
1340 API const char *aul_svc_get_operation(bundle *b)
1341 {
1342         return bundle_get_val(b, AUL_SVC_K_OPERATION);
1343 }
1344
1345 API const char *aul_svc_get_uri(bundle *b)
1346 {
1347         return bundle_get_val(b, AUL_SVC_K_URI);
1348 }
1349
1350 API const char *aul_svc_get_mime(bundle *b)
1351 {
1352         return bundle_get_val(b, AUL_SVC_K_MIME);
1353 }
1354
1355 API const char *aul_svc_get_data(bundle *b, const char *key)
1356 {
1357         return bundle_get_val(b, key);
1358 }
1359
1360 API const char **aul_svc_get_data_array(bundle *b, const char *key, int *len)
1361 {
1362         return bundle_get_str_array(b, key, len);
1363 }
1364
1365 API const char *aul_svc_get_pkgname(bundle *b)
1366 {
1367         return bundle_get_val(b, AUL_SVC_K_PKG_NAME);
1368 }
1369
1370 API const char *aul_svc_get_appid(bundle *b)
1371 {
1372         return bundle_get_val(b, AUL_SVC_K_PKG_NAME);
1373 }
1374
1375 API const char *aul_svc_get_category(bundle *b)
1376 {
1377         return bundle_get_val(b, AUL_SVC_K_CATEGORY);
1378 }
1379
1380 API const char *aul_svc_get_launch_mode(bundle *b)
1381 {
1382         return bundle_get_val(b, AUL_SVC_K_LAUNCH_MODE);
1383 }
1384
1385 API int aul_svc_create_result_bundle(bundle *inb, bundle **outb)
1386 {
1387         int ret = -1;
1388
1389         if (inb == NULL || outb == NULL) {
1390                 _E("bundle is NULL");
1391                 return AUL_SVC_RET_EINVAL;
1392         }
1393
1394         ret = aul_create_result_bundle(inb, outb);
1395
1396         /* add additional bundle */
1397         /*  bundle_add(outb, " ", " ");  */
1398
1399         if (ret == AUL_R_OK)
1400                 ret = AUL_SVC_RET_OK;
1401         else if (ret == AUL_R_EINVAL)
1402                 ret = AUL_SVC_RET_EINVAL;
1403         else if (ret == AUL_R_ECANCELED)
1404                 ret = AUL_SVC_RET_ECANCELED;
1405         else
1406                 ret = AUL_SVC_RET_ERROR;
1407
1408         return ret;
1409 }
1410
1411 API int aul_svc_send_result(bundle *b, aul_svc_result_val result)
1412 {
1413         int ret;
1414         char tmp[MAX_LOCAL_BUFSZ];
1415
1416         if (b == NULL) {
1417                 _E("aul_svc_send_result is NULL");
1418                 return AUL_SVC_RET_EINVAL;
1419         }
1420
1421         /* add result_code to bundle */
1422         snprintf(tmp, MAX_LOCAL_BUFSZ, "%d", (int)result);
1423         ret = __set_bundle(b, AUL_SVC_K_RES_VAL, tmp);
1424         if (ret < 0)
1425                 return AUL_SVC_RET_ERROR;
1426
1427         if (result == AUL_SVC_RES_CANCEL)
1428                 ret = aul_send_result(b, 1);
1429         else
1430                 ret = aul_send_result(b, 0);
1431
1432         /* remove result_code from bundle */
1433         bundle_del(b, AUL_SVC_K_RES_VAL);
1434
1435         return ret;
1436 }
1437
1438 API int aul_svc_set_defapp(const char *op, const char *mime_type,
1439                                 const char *uri, const char *defapp)
1440 {
1441         return aul_svc_set_defapp_for_uid(op, mime_type, uri, defapp, getuid());
1442 }
1443
1444 API int aul_svc_set_defapp_for_uid(const char *op, const char *mime_type,
1445                                 const char *uri, const char *defapp, uid_t uid)
1446 {
1447         int ret;
1448
1449         if (op == NULL || defapp == NULL)
1450                 return AUL_SVC_RET_EINVAL;
1451
1452         ret = _svc_db_check_perm(uid, false);
1453         if (ret < 0) {
1454                 _E("permission error : %d", ret);
1455                 return AUL_SVC_RET_EILLACC;
1456         }
1457
1458         ret = _svc_db_add_app(op, mime_type, uri, defapp, uid);
1459         if (ret < 0)
1460                 return AUL_SVC_RET_ERROR;
1461
1462         return AUL_SVC_RET_OK;
1463 }
1464
1465 API int aul_svc_unset_defapp(const char *defapp)
1466 {
1467         return aul_svc_unset_defapp_for_uid(defapp, getuid());
1468 }
1469
1470 API int aul_svc_unset_defapp_for_uid(const char *defapp, uid_t uid)
1471 {
1472         int ret;
1473
1474         if (defapp == NULL)
1475                 return AUL_SVC_RET_EINVAL;
1476
1477         ret = _svc_db_check_perm(uid, false);
1478         if (ret < 0) {
1479                 _E("permission error : %d", ret);
1480                 return AUL_SVC_RET_EILLACC;
1481         }
1482
1483         ret = _svc_db_delete_with_pkgname(defapp, uid);
1484
1485         if (ret < 0)
1486                 return AUL_SVC_RET_ERROR;
1487
1488         return AUL_SVC_RET_OK;
1489 }
1490
1491 API int aul_svc_unset_all_defapps()
1492 {
1493         return aul_svc_unset_all_defapps_for_uid(getuid());
1494 }
1495
1496 API int aul_svc_unset_all_defapps_for_uid(uid_t uid)
1497 {
1498         int ret;
1499
1500         ret = _svc_db_check_perm(uid, false);
1501         if (ret < 0) {
1502                 _E("permission error : %d", ret);
1503                 return AUL_SVC_RET_EILLACC;
1504         }
1505
1506         ret = _svc_db_delete_all(uid);
1507
1508         if (ret < 0)
1509                 return AUL_SVC_RET_ERROR;
1510
1511         __invalidate_cache(uid);
1512         return AUL_SVC_RET_OK;
1513 }
1514
1515 API int aul_svc_is_defapp(const char *pkg_name)
1516 {
1517         return aul_svc_is_defapp_for_uid(pkg_name, getuid());
1518 }
1519
1520 API int aul_svc_is_defapp_for_uid(const char *pkg_name, uid_t uid)
1521 {
1522         int ret;
1523
1524         ret = _svc_db_check_perm(uid, true);
1525         if (ret < 0) {
1526                 _E("permission error : %d", ret);
1527                 return AUL_SVC_RET_EILLACC;
1528         }
1529
1530         return _svc_db_is_defapp(pkg_name, uid);
1531 }
1532
1533 API int aul_svc_data_is_array(bundle *b, const char *key)
1534 {
1535         int type;
1536         type = bundle_get_type(b, key);
1537
1538         if (type <= 0)
1539                 return 0;
1540
1541         if (type & BUNDLE_TYPE_ARRAY)
1542                 return 1;
1543         return 0;
1544 }
1545
1546 API int aul_svc_allow_transient_app(bundle *b, int wid)
1547 {
1548         char win_id[MAX_LOCAL_BUFSZ];
1549
1550         snprintf(win_id, MAX_LOCAL_BUFSZ, "%d", wid);
1551
1552         if (b == NULL) {
1553                 _E("bundle is NULL");
1554                 return AUL_SVC_RET_EINVAL;
1555         }
1556
1557         return __set_bundle(b, AUL_SVC_K_WIN_ID, win_id);
1558 }
1559
1560 API int aul_svc_request_transient_app(bundle *b, int callee_wid,
1561                                 aul_svc_host_res_fn cbfunc, void *data)
1562 {
1563         return 0;
1564 }
1565
1566 API int aul_svc_subapp_terminate_request_pid(int pid)
1567 {
1568         int cpid = getpid();
1569         int lcnt;
1570         int *lpids = NULL;
1571         int i;
1572
1573         aul_app_group_get_leader_pids(&lcnt, &lpids);
1574         for (i = 0; i < lcnt; i++) {
1575                 if (lpids[i] == cpid) {
1576                         int cnt;
1577                         int *pids = NULL;
1578
1579                         aul_app_group_get_group_pids(cpid, &cnt, &pids);
1580
1581                         if (cnt == 0) {
1582                                 free(lpids);
1583                                 if (pids)
1584                                         free(pids);
1585
1586                                 return aul_subapp_terminate_request_pid(pid);
1587                         }
1588
1589                         if (pids != NULL)
1590                                 free(pids);
1591                         break;
1592                 }
1593         }
1594
1595         if (lpids != NULL)
1596                 free(lpids);
1597
1598         return aul_app_group_clear_top();
1599 }
1600
1601 API int aul_send_service_result(bundle *b)
1602 {
1603         return aul_send_result(b, 0);
1604 }
1605
1606 API int aul_svc_subscribe_launch_result(bundle *b, const char *result)
1607 {
1608         if (b == NULL) {
1609                 _E("bundle is NULL");
1610                 return AUL_SVC_RET_EINVAL;
1611         }
1612
1613         return __set_bundle(b, result, "1");
1614 }
1615
1616 API int aul_svc_set_loader_id(bundle *b, int loader_id)
1617 {
1618         char tmp[MAX_LOCAL_BUFSZ];
1619
1620         if (b == NULL) {
1621                 _E("bundle is NULL");
1622                 return AUL_SVC_RET_EINVAL;
1623         }
1624
1625         if (loader_id <= 0) {
1626                 _E("invalid loader id");
1627                 return AUL_SVC_RET_EINVAL;
1628         }
1629
1630         snprintf(tmp, sizeof(tmp), "%d", loader_id);
1631         return __set_bundle(b, AUL_K_LOADER_ID, tmp);
1632 }
1633
1634 API int aul_svc_set_loader_name(bundle *b, const char *loader_name)
1635 {
1636         if (b == NULL) {
1637                 _E("bundle is NULL");
1638                 return AUL_SVC_RET_EINVAL;
1639         }
1640
1641         if (!loader_name) {
1642                 _E("invalid loader name");
1643                 return AUL_SVC_RET_EINVAL;
1644         }
1645
1646         return __set_bundle(b, AUL_K_LOADER_NAME, loader_name);
1647 }
1648
1649 API int aul_svc_set_background_launch(bundle *b, int enabled)
1650 {
1651         if (b == NULL)
1652                 return AUL_R_EINVAL;
1653
1654         if (bundle_get_type(b, AUL_SVC_K_BG_LAUNCH) != BUNDLE_TYPE_NONE)
1655                 bundle_del(b, AUL_SVC_K_BG_LAUNCH);
1656
1657         if (enabled)
1658                 bundle_add_str(b, AUL_SVC_K_BG_LAUNCH, "enable");
1659
1660         return AUL_R_OK;
1661 }
1662
1663 API int aul_svc_set_alias_appid(const char *alias_appid, const char *appid)
1664 {
1665         return aul_svc_set_alias_appid_for_uid(alias_appid, appid, getuid());
1666 }
1667
1668 API int aul_svc_set_alias_appid_for_uid(const char *alias_appid,
1669                 const char *appid, uid_t uid)
1670 {
1671         int ret;
1672
1673         ret = _svc_db_check_perm(uid, false);
1674         if (ret < 0) {
1675                 _E("Permission error: %d", ret);
1676                 return AUL_SVC_RET_EILLACC;
1677         }
1678
1679         ret = _svc_db_add_alias_appid(alias_appid, appid, uid);
1680         if (ret < 0)
1681                 return AUL_SVC_RET_ERROR;
1682
1683         return AUL_SVC_RET_OK;
1684 }
1685
1686 API int aul_svc_unset_alias_appid(const char *alias_appid)
1687 {
1688         return aul_svc_unset_alias_appid_for_uid(alias_appid, getuid());
1689 }
1690
1691 API int aul_svc_unset_alias_appid_for_uid(const char *alias_appid, uid_t uid)
1692 {
1693         int ret;
1694
1695         ret = _svc_db_check_perm(uid, false);
1696         if (ret < 0) {
1697                 _E("Permission error: %d", ret);
1698                 return AUL_SVC_RET_EILLACC;
1699         }
1700
1701         ret = _svc_db_delete_alias_appid(alias_appid, uid);
1702         if (ret < 0)
1703                 return AUL_SVC_RET_ERROR;
1704
1705         return AUL_SVC_RET_OK;
1706 }
1707
1708 API int aul_svc_foreach_alias_info(void (*callback)(const char *alias_appid,
1709                         const char *appid, void *data), void *user_data)
1710 {
1711         return aul_svc_foreach_alias_info_for_uid(callback, getuid(),
1712                         user_data);
1713 }
1714
1715 API int aul_svc_foreach_alias_info_for_uid(void (*callback)(
1716                         const char *alias_appid, const char *appid,
1717                         void *data), uid_t uid, void *user_data)
1718 {
1719         int ret;
1720
1721         if (callback == NULL) {
1722                 _E("Invalid parameter");
1723                 return AUL_SVC_RET_EINVAL;
1724         }
1725
1726         ret = _svc_db_check_perm(uid, true);
1727         if (ret < 0) {
1728                 _E("Permission error: %d", ret);
1729                 return AUL_SVC_RET_EILLACC;
1730         }
1731
1732         ret = _svc_db_foreach_alias_info(callback, uid, user_data);
1733         if (ret < 0)
1734                 return AUL_SVC_RET_ERROR;
1735
1736         return AUL_SVC_RET_OK;
1737 }
1738
1739 API int aul_svc_enable_alias_info(const char *appid)
1740 {
1741         return aul_svc_enable_alias_info_for_uid(appid, getuid());
1742 }
1743
1744 API int aul_svc_enable_alias_info_for_uid(const char *appid, uid_t uid)
1745 {
1746         int ret;
1747
1748         ret = _svc_db_check_perm(uid, false);
1749         if (ret < 0) {
1750                 _E("Permission error: %d", ret);
1751                 return AUL_SVC_RET_EILLACC;
1752         }
1753
1754         ret = _svc_db_enable_alias_info(appid, uid);
1755         if (ret < 0)
1756                 return AUL_SVC_RET_ERROR;
1757
1758         return AUL_SVC_RET_OK;
1759 }
1760
1761 API int aul_svc_disable_alias_info(const char *appid)
1762 {
1763         return aul_svc_disable_alias_info_for_uid(appid, getuid());
1764 }
1765
1766 API int aul_svc_disable_alias_info_for_uid(const char *appid, uid_t uid)
1767 {
1768         int ret;
1769
1770         ret = _svc_db_check_perm(uid, false);
1771         if (ret < 0) {
1772                 _E("Permission error: %d", ret);
1773                 return AUL_SVC_RET_EILLACC;
1774         }
1775
1776         ret = _svc_db_disable_alias_info(appid, uid);
1777         if (ret < 0)
1778                 return AUL_SVC_RET_ERROR;
1779
1780         return AUL_SVC_RET_OK;
1781 }
1782
1783 API int aul_svc_get_appid_by_alias_appid(const char *alias_appid, char **appid)
1784 {
1785         return aul_svc_get_appid_by_alias_appid_for_uid(alias_appid,
1786                         appid, getuid());
1787 }
1788
1789 API int aul_svc_get_appid_by_alias_appid_for_uid(const char *alias_appid,
1790                 char **appid, uid_t uid)
1791 {
1792         int ret;
1793
1794         ret = _svc_db_check_perm(uid, true);
1795         if (ret < 0) {
1796                 _E("Permission error: %d", ret);
1797                 return AUL_SVC_RET_EILLACC;
1798         }
1799
1800         ret = _svc_db_get_appid_from_alias_info(alias_appid, appid, uid);
1801         if (ret < 0)
1802                 return AUL_SVC_RET_ERROR;
1803
1804         return AUL_SVC_RET_OK;
1805 }
1806
1807 API int aul_svc_foreach_alias_info_by_appid(int (*callback)(
1808                         const char *alias_appid, const char *appid, void *data),
1809                 const char *appid, void *user_data)
1810 {
1811         return aul_svc_foreach_alias_info_by_appid_for_uid(callback, appid,
1812                         getuid(), user_data);
1813 }
1814
1815 API int aul_svc_foreach_alias_info_by_appid_for_uid(int (*callback)(
1816                         const char *alias_appid, const char *appid, void *data),
1817                 const char *appid, uid_t uid, void *user_data)
1818 {
1819         int ret;
1820
1821         if (callback == NULL || appid == NULL) {
1822                 _E("Invalid parameter");
1823                 return AUL_SVC_RET_EINVAL;
1824         }
1825
1826         ret = _svc_db_check_perm(uid, true);
1827         if (ret < 0) {
1828                 _E("Permission error: %d", ret);
1829                 return AUL_SVC_RET_EILLACC;
1830         }
1831
1832         ret = _svc_db_foreach_alias_info_by_appid(callback, appid,
1833                         uid, user_data);
1834         if (ret < 0)
1835                 return AUL_SVC_RET_ERROR;
1836
1837         return AUL_SVC_RET_OK;
1838 }
1839
1840 API int aul_svc_foreach_allowed_info(int (*callback)(const char *appid,
1841                         const char *allowed_appid, void *data), void *user_data)
1842 {
1843         return aul_svc_foreach_allowed_info_for_uid(callback,
1844                         getuid(), user_data);
1845 }
1846
1847 API int aul_svc_foreach_allowed_info_for_uid(int (*callback)(const char *appid,
1848                         const char *allowed_appid, void *data),
1849                 uid_t uid, void *user_data)
1850 {
1851         int ret;
1852
1853         if (callback == NULL) {
1854                 _E("Invalid parameter");
1855                 return AUL_SVC_RET_EINVAL;
1856         }
1857
1858         ret = _svc_db_check_perm(uid, true);
1859         if (ret < 0) {
1860                 _E("Permission error: %d", ret);
1861                 return AUL_SVC_RET_EILLACC;
1862         }
1863
1864         ret = _svc_db_foreach_allowed_info(callback, uid, user_data);
1865         if (ret < 0)
1866                 return AUL_SVC_RET_ERROR;
1867
1868         return AUL_SVC_RET_OK;
1869 }
1870
1871 API int aul_svc_foreach_allowed_info_by_appid(int (*callback)(
1872                         const char *appid, const char *allowed_appid, void *data),
1873                 const char *appid, void *user_data)
1874 {
1875         return aul_svc_foreach_allowed_info_by_appid_for_uid(callback,
1876                         appid, getuid(), user_data);
1877 }
1878
1879 API int aul_svc_foreach_allowed_info_by_appid_for_uid(int (*callback)(
1880                         const char *appid, const char *allowed_appid, void *data),
1881                 const char *appid, uid_t uid, void *user_data)
1882 {
1883         int ret;
1884
1885         if (callback == NULL || appid == NULL) {
1886                 _E("Invalid parameter");
1887                 return AUL_SVC_RET_EINVAL;
1888         }
1889
1890         ret = _svc_db_check_perm(uid, true);
1891         if (ret < 0) {
1892                 _E("Permission error: %d", ret);
1893                 return AUL_SVC_RET_EILLACC;
1894         }
1895
1896         ret = _svc_db_foreach_allowed_info_by_appid(callback, appid,
1897                         uid, user_data);
1898         if (ret < 0)
1899                 return AUL_SVC_RET_ERROR;
1900
1901         return AUL_SVC_RET_OK;
1902 }
1903
1904 API const char *aul_svc_get_instance_id(bundle *b)
1905 {
1906         return bundle_get_val(b, AUL_K_INSTANCE_ID);
1907 }
1908
1909 API int aul_svc_set_instance_id(bundle *b, const char *instance_id)
1910 {
1911         if (b == NULL || instance_id == NULL) {
1912                 _E("Invalid parameter");
1913                 return AUL_SVC_RET_EINVAL;
1914         }
1915
1916         return __set_bundle(b, AUL_K_INSTANCE_ID, instance_id);
1917 }
1918
1919 API int aul_svc_run_service_async(bundle *b, int request_code,
1920                 aul_svc_res_fn cbfunc, void *data)
1921 {
1922         return __run_service(b, request_code, cbfunc, NULL, data,
1923                         getuid(), false);
1924 }
1925
1926 API int aul_svc_run_service_async_for_uid(bundle *b, int request_code,
1927                 aul_svc_res_fn cbfunc, void *data, uid_t uid)
1928 {
1929         return __run_service(b, request_code, cbfunc, NULL, data, uid, false);
1930 }
1931
1932 API int aul_svc_send_launch_request(bundle *b, int request_code,
1933                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
1934                 void *user_data)
1935 {
1936         return aul_svc_send_launch_request_for_uid(b, request_code,
1937                         cbfunc, err_cb, user_data, getuid());
1938 }
1939
1940 API int aul_svc_send_launch_request_for_uid(bundle *b, int request_code,
1941                 aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
1942                 void *user_data, uid_t uid)
1943 {
1944         return __run_service(b, request_code, cbfunc, err_cb, user_data,
1945                         uid, false);
1946 }