tizen 2.4 release
[framework/appfw/aul-1.git] / am_daemon / amd_request.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 #define _GNU_SOURCE
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <dirent.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <dlfcn.h>
31 #include <poll.h>
32 #include <aul.h>
33 #include <glib.h>
34 #include <bundle.h>
35 #include <bundle_internal.h>
36 #include <rua.h>
37 #include <rua_stat.h>
38 #include <proc_stat.h>
39 #include <security-server.h>
40 #include <vconf.h>
41 #include <ttrace.h>
42 #include <Ecore.h>
43 #include <sys/signalfd.h>
44 #include <signal.h>
45 #include <wait.h>
46 #include <pkgmgr-info.h>
47
48 #include "amd_config.h"
49 #include "simple_util.h"
50 #include "app_sock.h"
51 #include "app_signal.h"
52 #include "aul_util.h"
53 #include "amd_request.h"
54 #include "amd_key.h"
55 #include "amd_launch.h"
56 #include "amd_appinfo.h"
57 #include "amd_status.h"
58 #include "amd_app_group.h"
59
60 #define INHOUSE_UID     5000
61
62 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
63 #define METADATA_MULTI_INSTANCE         "http://developer.samsung.com/tizen/metadata/multiinstance"
64 #endif
65
66 struct appinfomgr *_raf;
67 static DBusConnection *bus = NULL;
68 static sigset_t oldmask;
69 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
70 char *home_appid = NULL;
71 #endif
72
73 struct restart_info {
74         char *appid;
75         int count;
76         Ecore_Timer *timer;
77 };
78
79 GHashTable *restart_tbl;
80
81 static int __send_result_to_client(int fd, int res);
82 static gboolean __request_handler(gpointer data);
83
84 // TODO: Replace with pkgmgr-info header
85 int pkgmgrinfo_updateinfo_check_update(const char* pkgid);
86
87 static int __send_result_data(int fd, int cmd, unsigned char *kb_data, int datalen)
88 {
89         int len;
90         int ret;
91         int res = 0;
92         app_pkt_t *pkt = NULL;
93
94         if (datalen > AUL_SOCK_MAXBUFF - 8) {
95                 _E("datalen > AUL_SOCK_MAXBUFF\n");
96                 return -EINVAL;
97         }
98
99         pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
100         if (NULL == pkt) {
101                 _E("Malloc Failed!");
102                 return -ENOMEM;
103         }
104         memset(pkt, 0, AUL_SOCK_MAXBUFF);
105
106         pkt->cmd = cmd;
107         pkt->len = datalen;
108         memcpy(pkt->data, kb_data, datalen);
109
110         if ((len = send(fd, pkt, datalen + 8, MSG_NOSIGNAL)) != datalen + 8) {
111                 _E("sendto() failed - %d %d (errno %d)", len, datalen + 8, errno);
112                 if(len > 0) {
113                         while (len != datalen + 8) {
114                                 ret = send(fd, &pkt->data[len-8], datalen + 8 - len, MSG_NOSIGNAL);
115                                 if (ret < 0) {
116                                         _E("second sendto() failed - %d %d (errno %d)", ret, datalen + 8, errno);
117                                         close(fd);
118                                         if (pkt) {
119                                                 free(pkt);
120                                                 pkt = NULL;
121                                         }
122                                         return -ECOMM;
123                                 }
124                                 len += ret;
125                                 _D("sendto() len - %d %d", len, datalen + 8);
126                         }
127                 } else {
128                         close(fd);
129                         if (pkt) {
130                                 free(pkt);
131                                 pkt = NULL;
132                         }
133                         return -ECOMM;
134                 }
135         }
136         if (pkt) {
137                 free(pkt);
138                 pkt = NULL;
139         }
140
141         close(fd);
142         return res;
143 }
144
145 static int __send_result_to_client(int fd, int res)
146 {
147         if (fd < 0)
148                 return -1;
149
150         _W("__send_result_to_client, pid: %d", res);
151
152         if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
153                 if (errno == EPIPE) {
154                         _E("send failed due to EPIPE.\n");
155                 }
156
157                 _E("send fail to client");
158         }
159         close(fd);
160         return 0;
161 }
162
163 static void __real_send(int clifd, int ret)
164 {
165         if(clifd < 0)
166                 return;
167
168         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
169                 if (errno == EPIPE) {
170                         _E("send failed due to EPIPE.\n");
171                 }
172                 _E("send fail to client");
173         }
174
175         close(clifd);
176 }
177
178 static int __get_caller_pid(bundle *kb)
179 {
180         const char *pid_str;
181         int pid;
182
183         pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
184         if(pid_str)
185                 goto end;
186
187         pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
188         if (pid_str == NULL)
189                 return -1;
190
191 end:
192         pid = atoi(pid_str);
193         if (pid <= 1)
194                 return -1;
195
196         return pid;
197 }
198
199 static int __foward_cmd(int cmd, bundle *kb, int cr_pid)
200 {
201         int pid;
202         int pgid;
203         char tmp_pid[MAX_PID_STR_BUFSZ];
204         int datalen;
205         bundle_raw *kb_data;
206         int res;
207
208         if ((pid = __get_caller_pid(kb)) < 0)
209         {
210                 return AUL_R_ERROR;
211         }
212
213         pgid = getpgid(cr_pid);
214         if(pgid > 0) {
215                 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pgid);
216                 bundle_del(kb, AUL_K_CALLEE_PID);
217                 bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
218         }
219
220         _W("__forward_cmd: %d %d", cr_pid, pgid);
221
222         bundle_encode(kb, &kb_data, &datalen);
223         if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
224                 res = AUL_R_ERROR;
225
226         free(kb_data);
227
228         return res;
229 }
230
231 static int __app_process_by_pid(int cmd,
232         const char *pkg_name, struct ucred *cr, int clifd)
233 {
234         int pid;
235         int ret = -1;
236         int dummy;
237         char *appid = NULL;
238         const char *pkgid = NULL;
239         const char *type = NULL;
240         const struct appinfo *ai = NULL;
241
242         if (pkg_name == NULL)
243                 return -1;
244
245         pid = atoi(pkg_name);
246         if (pid <= 1) {
247                 _E("invalid pid");
248                 return -1;
249         }
250
251         /* check whether app process is dead or not */
252         char buf[1024];
253         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
254         if (access(buf, F_OK) != 0) {
255                 _E("pid(%d) is dead. cmd(%d) is canceled", pid, cmd);
256                 __real_send(clifd, -ECOMM);
257                 return -ECOMM;
258         }
259
260         if (_status_get_app_info_status(pid) == -1) {
261                 char buf[512];
262                 if (_status_get_pkgname_bypid(pid, buf, 512) == -1) {
263                         _E("request for unknown pid. It might not be a pid of app: %d", pid);
264                         __real_send(clifd, -1);
265                         return -1;
266                 }
267         }
268
269         appid = _status_app_get_appid_bypid(pid);
270         ai = appinfo_find(_raf, appid);
271         pkgid = appinfo_get_value(ai, AIT_PKGID);
272         type = appinfo_get_value(ai, AIT_COMPTYPE);
273
274         if (cmd == APP_RESUME_BY_PID)
275                 aul_send_app_resume_request_signal(pid, appid, pkgid, type);
276         else
277                 aul_send_app_terminate_request_signal(pid, appid, pkgid, type);
278
279         SECURE_LOGD("__app_process_by_pid, pid: %d, ", pid);
280         switch (cmd) {
281         case APP_RESUME_BY_PID:
282                 ret = _resume_app(pid, clifd);
283                 break;
284         case APP_TERM_BY_PID:
285         case APP_TERM_BY_PID_WITHOUT_RESTART:
286                 ret = _term_app(pid, clifd);
287                 break;
288         case APP_TERM_BGAPP_BY_PID:
289                 ret = _term_bgapp(pid, clifd);
290                 break;
291         case APP_KILL_BY_PID:
292                 if ((ret = _send_to_sigkill(pid)) < 0)
293                         _E("fail to killing - %d\n", pid);
294                 __real_send(clifd, ret);
295                 break;
296         case APP_TERM_REQ_BY_PID:
297                 ret = _term_req_app(pid, clifd);
298                 break;
299         case APP_TERM_BY_PID_ASYNC:
300                 if ((ret = __app_send_raw_with_noreply(pid, cmd, (unsigned char *)&dummy, sizeof(int))) < 0) {
301                         _D("terminate req packet send error");
302                 }
303                 __real_send(clifd, ret);
304                 break;
305         case APP_PAUSE_BY_PID:
306                 ret = _pause_app(pid, clifd);
307                 break;
308         default:
309                 break;
310         }
311
312         return ret;
313 }
314
315 #ifdef _APPFW_FEATURE_EFFECTIVE_APPID
316 static void __set_effective_appid(bundle *kb)
317 {
318         const struct appinfo *ai;
319         const struct appinfo *effective_ai;
320         char *appid;
321         const char *effective_appid;
322
323         appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
324         if (appid) {
325                 ai = appinfo_find(_raf, appid);
326                 if (ai == NULL)
327                         return;
328
329                 effective_appid = appinfo_get_value(ai, AIT_EFFECTIVE_APPID);
330                 if (effective_appid) {
331                         const char *pkgid;
332                         const char *effective_pkgid;
333                         effective_ai = appinfo_find(_raf, effective_appid);
334                         if (effective_ai == NULL)
335                                 return;
336
337                         pkgid = appinfo_get_value(ai, AIT_PKGID);
338                         effective_pkgid = appinfo_get_value(effective_ai, AIT_PKGID);
339                         if (pkgid && effective_pkgid && strcmp(pkgid, effective_pkgid) == 0) {
340                                 _D("use effective appid instead of the real appid");
341                                 bundle_del(kb, AUL_K_PKG_NAME);
342                                 bundle_add(kb, AUL_K_PKG_NAME, effective_appid);
343                         }
344                 }
345         }
346 }
347 #endif
348
349 static gboolean __add_history_handler(gpointer user_data)
350 {
351         struct rua_rec rec;
352         int ret;
353         bundle *kb = NULL;
354         char *appid = NULL;
355         char *app_path = NULL;
356         char *stat_caller = NULL;
357         char *stat_tag = NULL;
358         struct appinfo *ai;
359
360         app_pkt_t *pkt = (app_pkt_t *)user_data;
361
362         if (!pkt)
363                 return FALSE;
364         kb = bundle_decode(pkt->data, pkt->len);
365
366         if (!app_group_is_group_app(kb)) {
367
368 #ifdef _APPFW_FEATURE_EFFECTIVE_APPID
369                 __set_effective_appid(kb);
370 #endif
371                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
372
373                 ai = (struct appinfo *)appinfo_find(_raf, appid);
374                 app_path = (char *)appinfo_get_value(ai, AIT_EXEC);
375
376                 memset((void *)&rec, 0, sizeof(rec));
377
378                 rec.pkg_name = appid;
379                 rec.app_path = app_path;
380
381                 if(pkt->len > 0) {
382                         rec.arg = (char *)pkt->data;
383                 }
384
385                 SECURE_LOGD("add rua history %s %s", rec.pkg_name, rec.app_path);
386
387                 ret = rua_add_history(&rec);
388                 if (ret == -1)
389                         _D("rua add history error");
390         }
391
392         stat_caller = (char *)bundle_get_val(kb, AUL_SVC_K_RUA_STAT_CALLER);
393         stat_tag = (char *)bundle_get_val(kb, AUL_SVC_K_RUA_STAT_TAG);
394
395         if (stat_caller != NULL && stat_tag != NULL) {
396                 SECURE_LOGD("rua_stat_caller: %s, rua_stat_tag: %s", stat_caller, stat_tag);
397                 rua_stat_update(stat_caller, stat_tag);
398         }
399
400         if (kb != NULL)
401                 bundle_free(kb);
402         free(pkt);
403
404         return FALSE;
405 }
406
407 static int __get_pid_cb(void *user_data, const char *group, pid_t pid)
408 {
409         int *sz = user_data;
410
411         _D("%s: %d : %d", *sz, pid);
412         *sz = 1; /* 1 is enough */
413
414         return -1; /* stop the iteration */
415 }
416
417 int _release_srv(const char *appid)
418 {
419         int r;
420         const struct appinfo *ai;
421
422         ai = (struct appinfo *)appinfo_find(_raf, appid);
423         if (!ai) {
424                 _E("appid not found");
425                 SECURE_LOGE("release service: '%s' not found", appid);
426                 return -1;
427         }
428
429         r = appinfo_get_boolean(ai, AIT_RESTART);
430         if (r == 1) {
431                 _W("Auto restart");
432                 SECURE_LOGD("Auto restart set: '%s'", appid);
433                 return _start_srv(ai);
434         }
435
436         return 0;
437 }
438
439 static Eina_Bool __restart_timeout_handler(void *data)
440 {
441         struct restart_info *ri = (struct restart_info *)data;
442
443         _D("ri (%x)", ri);
444         SECURE_LOGD("appid (%s)", ri->appid);
445
446         g_hash_table_remove(restart_tbl, ri->appid);
447         free(ri->appid);
448         free(ri);
449
450         return ECORE_CALLBACK_CANCEL;
451 }
452
453 static bool __check_restart(const char *appid)
454 {
455         struct restart_info *ri = NULL;
456         //struct appinfo *ai = NULL;
457
458         ri = g_hash_table_lookup(restart_tbl, appid);
459
460         if(!ri) {
461                 ri = calloc(1, sizeof(*ri));
462                 if (!ri) {
463                         _E("create restart info: %s", strerror(errno));
464                         return true;
465                 }
466                 memset(ri, 0, sizeof(struct restart_info));
467                 ri->appid = strdup(appid);
468                 ri->count = 1;
469                 g_hash_table_insert(restart_tbl, ri->appid, ri);
470
471                 _D("ri (%x)", ri);
472                 SECURE_LOGD("appid (%s)", appid);
473
474                 ri->timer = ecore_timer_add(10, __restart_timeout_handler, ri);
475         } else {
476                 ri->count++;
477                 _D("count (%d)", ri->count);
478                 if(ri->count > 5) {
479                         /*ai = appinfo_find(_raf, appid);
480                         if(ai) {
481                                 appinfo_set_value(ai, AIT_STATUS, "norestart");
482                         }*/
483                         ecore_timer_del(ri->timer);
484                         return false;
485                 }
486         }
487         return true;
488 }
489
490 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
491 static inline int __send_home_launch_signal(int pid)
492 {
493         DBusMessage *message;
494
495         if (bus == NULL)
496                 return -1;
497
498         message = dbus_message_new_signal(AUL_DBUS_PATH,
499                                           AUL_DBUS_SIGNAL_INTERFACE,
500                                           AUL_DBUS_HOMELAUNCH_SIGNAL);
501
502         if (dbus_message_append_args(message,
503                                      DBUS_TYPE_UINT32, &pid,
504                                      DBUS_TYPE_INVALID) == FALSE) {
505                 _E("Failed to load data error");
506                 return -1;
507         }
508
509         if (dbus_connection_send(bus, message, NULL) == FALSE) {
510                 _E("dbus send error");
511                 return -1;
512         }
513
514         dbus_connection_flush(bus);
515         dbus_message_unref(message);
516
517         _W("send a home launch signal");
518
519         return 0;
520 }
521 #endif
522
523 static inline int __send_app_termination_signal(int dead_pid)
524 {
525         DBusMessage *message;
526
527         if (bus == NULL)
528                 return -1;
529
530         message = dbus_message_new_signal(AUL_DBUS_PATH,
531                                           AUL_DBUS_SIGNAL_INTERFACE,
532                                           AUL_DBUS_APPDEAD_SIGNAL);
533
534         if (dbus_message_append_args(message,
535                                      DBUS_TYPE_UINT32, &dead_pid,
536                                      DBUS_TYPE_INVALID) == FALSE) {
537                 _E("Failed to load data error");
538                 return -1;
539         }
540
541         if (dbus_connection_send(bus, message, NULL) == FALSE) {
542                 _E("dbus send error");
543                 return -1;
544         }
545
546         dbus_connection_flush(bus);
547         dbus_message_unref(message);
548
549         _W("send dead signal done");
550
551         return 0;
552 }
553
554 int _send_set_process_group_signal_signal(int owner_pid, int child_pid)
555 {
556         DBusMessage *message;
557
558         if (bus == NULL)
559                 return -1;
560
561         message = dbus_message_new_signal(RESOURCED_PROC_OBJECT,
562                                           RESOURCED_PROC_INTERFACE,
563                                           RESOURCED_PROC_GROUP_SIGNAL);
564
565         if (dbus_message_append_args(message,
566                                          DBUS_TYPE_INT32, &owner_pid,
567                                          DBUS_TYPE_INT32, &child_pid,
568                                          DBUS_TYPE_INVALID) == FALSE) {
569                 _E("Failed to load data error");
570                 return -1;
571         }
572
573         if (dbus_connection_send(bus, message, NULL) == FALSE) {
574                 _E("dbus send error");
575                 return -1;
576         }
577
578         dbus_connection_flush(bus);
579         dbus_message_unref(message);
580
581         _W("send set_process_group signal done");
582
583         return 0;
584 }
585
586 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
587 static char* __get_metadata_value(const char *appid, const char *metadata_key)
588 {
589         int ret = 0;
590         pkgmgrinfo_appinfo_h handle;
591         char *metadata_value = NULL;
592         char *multi_appid = NULL;
593
594         ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
595         if (ret != PMINFO_R_OK)
596                 return NULL;
597
598         ret = pkgmgrinfo_appinfo_get_metadata_value(handle, metadata_key, &metadata_value);
599         if (ret != PMINFO_R_OK) {
600                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
601                 return NULL;
602         }
603
604         multi_appid = strdup(metadata_value);
605
606         pkgmgrinfo_appinfo_destroy_appinfo(handle);
607
608         return multi_appid;
609 }
610
611 static const char* __check_target_appid(const struct appinfo* ai, const char *appid, const char *multi_appid)
612 {
613         const char* target = NULL;
614
615         // Both apps are running
616         if (_status_app_is_running(appid) != -1 && _status_app_is_running(multi_appid) != -1) {
617                 const char* toggle = appinfo_get_value(ai, AIT_TOGGLE_ORDER);
618                 int order = atoi(toggle);
619
620                 _D("launch a multi-instance app with toggle mode: %d", order);
621                 switch (order) {
622                         case 0:
623                                 target = multi_appid;
624                                 appinfo_set_value((struct appinfo *)ai,
625                                         AIT_TOGGLE_ORDER, "1");
626                                 break;
627
628                         case 1:
629                                 target = appid;
630                                 appinfo_set_value((struct appinfo *)ai,
631                                         AIT_TOGGLE_ORDER, "0");
632                                 break;
633
634                         default:
635                                 break;
636                 }
637         } else {
638                 // Main app is running
639                 if (_status_app_is_running(appid) != -1) {
640                         SECURE_LOGD("Send a request to the running main appid: %s", appid);
641                         target = appid;
642                         // Sub app is running
643                 } else if (_status_app_is_running(multi_appid) != -1) {
644                         SECURE_LOGD("Send a request to the running sub appid: %s", multi_appid);
645                         target = multi_appid;
646                 } else {
647                         SECURE_LOGD("Both apps are not running, launch a main app - %s", appid);
648                         target = appid;
649                 }
650         }
651
652         return target;
653 }
654 #endif
655
656 static void __dispatch_app_group_get_window(int clifd, const app_pkt_t *pkt)
657 {
658         bundle *b;
659         char *buf;
660         int pid;
661         int wid;
662
663         b = bundle_decode(pkt->data, pkt->len);
664         bundle_get_str(b, AUL_K_PID, &buf);
665         pid = atoi(buf);
666         bundle_free(b);
667         wid = app_group_get_window(pid);
668         __real_send(clifd, wid);
669 }
670
671 static void __dispatch_app_group_set_window(int clifd, const app_pkt_t *pkt, int pid)
672 {
673         bundle *b;
674         char *buf;
675         int wid;
676         int ret;
677
678         b = bundle_decode(pkt->data, pkt->len);
679         bundle_get_str(b, AUL_K_WID, &buf);
680         wid = atoi(buf);
681         bundle_free(b);
682         ret = app_group_set_window(pid, wid);
683         __real_send(clifd, ret);
684 }
685
686 static void __dispatch_app_group_get_fg_flag(int clifd, const app_pkt_t *pkt)
687 {
688         bundle *b;
689         char *buf;
690         int pid;
691         int fg;
692
693         b = bundle_decode(pkt->data, pkt->len);
694         bundle_get_str(b, AUL_K_PID, &buf);
695         pid = atoi(buf);
696         bundle_free(b);
697         fg = app_group_get_fg_flag(pid);
698         __real_send(clifd, fg);
699 }
700
701 static void __dispatch_app_group_clear_top(int clifd, int pid)
702 {
703         app_group_clear_top(pid);
704         __real_send(clifd, 0);
705 }
706
707 static void __dispatch_app_group_get_leader_pid(int clifd,
708                 const app_pkt_t *pkt)
709 {
710         bundle *b;
711         char *buf;
712         int pid;
713         int lpid;
714
715         b = bundle_decode(pkt->data, pkt->len);
716         bundle_get_str(b, AUL_K_PID, &buf);
717         pid = atoi(buf);
718         bundle_free(b);
719         lpid = app_group_get_leader_pid(pid);
720         __real_send(clifd, lpid);
721 }
722
723 static void __dispatch_app_group_get_leader_pids(int clifd,
724                 const app_pkt_t *pkt)
725 {
726         int cnt;
727         int *pids;
728         unsigned char empty[1] = { 0 };
729
730         app_group_get_leader_pids(&cnt, &pids);
731
732         if (pids == NULL || cnt == 0) {
733                 __send_result_data(clifd, APP_GROUP_GET_LEADER_PIDS, empty, 0);
734         } else {
735                 __send_result_data(clifd, APP_GROUP_GET_LEADER_PIDS,
736                         (unsigned char *)pids, cnt * sizeof(int));
737         }
738         if (pids != NULL)
739                 free(pids);
740 }
741
742 static void __dispatch_app_group_get_idle_pids(int clifd,
743                 const app_pkt_t *pkt)
744 {
745         int cnt;
746         int *pids;
747         unsigned char empty[1] = { 0 };
748
749         app_group_get_idle_pids(&cnt, &pids);
750
751         if (pids == NULL || cnt == 0) {
752                 __send_result_data(clifd, APP_GROUP_GET_IDLE_PIDS, empty, 0);
753         } else {
754                 __send_result_data(clifd, APP_GROUP_GET_IDLE_PIDS,
755                         (unsigned char *)pids, cnt * sizeof(int));
756         }
757         if (pids != NULL)
758                 free(pids);
759 }
760
761 static void __dispatch_app_group_get_group_pids(int clifd, const app_pkt_t *pkt)
762 {
763         bundle *b;
764         char *buf;
765         int leader_pid;
766         int cnt;
767         int *pids;
768         unsigned char empty[1] = { 0 };
769
770         b = bundle_decode(pkt->data, pkt->len);
771         bundle_get_str(b, AUL_K_LEADER_PID, &buf);
772         leader_pid = atoi(buf);
773         bundle_free(b);
774
775         app_group_get_group_pids(leader_pid, &cnt, &pids);
776         if (pids == NULL || cnt == 0) {
777                 __send_result_data(clifd, APP_GROUP_GET_GROUP_PIDS, empty, 0);
778         } else {
779                 __send_result_data(clifd, APP_GROUP_GET_GROUP_PIDS,
780                         (unsigned char *)pids, cnt * sizeof(int));
781         }
782         if (pids != NULL)
783                 free(pids);
784 }
785
786 static void __dispatch_app_group_lower(int clifd, int pid)
787 {
788         int ret = 0;
789
790         app_group_lower(pid, &ret);
791         __real_send(clifd, ret);
792 }
793
794 static void  __check_host_pid(bundle *kb, struct ucred *cr)
795 {
796         if (cr->pid == 0) {
797                 SECURE_LOGD("check host pid");
798
799                 char *spid = NULL;
800
801                 bundle_get_str(kb, AUL_K_HOST_PID, &spid);
802                 if (spid != NULL) {
803                         cr->pid = atoi(spid);
804                         SECURE_LOGD("caller pid was changed by host pid %s", spid);
805                 }
806         }
807 }
808
809 static gboolean __request_handler(gpointer data)
810 {
811         GPollFD *gpollfd = (GPollFD *) data;
812         int fd = gpollfd->fd;
813         app_pkt_t *pkt;
814         int clifd;
815         struct ucred cr;
816         int *status;
817         int ret = -1;
818         int free_pkt = 1;
819         char *appid = NULL;
820         char *term_pid = NULL;
821         int pid;
822         bundle *kb = NULL;
823         const struct appinfo *ai;
824         int owner_pid;
825         int child_pid;
826
827         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:AMD:REQ_HANDLER");
828         if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
829                 _E("recv error");
830                 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
831                 return FALSE;
832         }
833
834         kb = bundle_decode(pkt->data, pkt->len);
835 #ifdef _APPFW_FEATURE_EFFECTIVE_APPID
836         __set_effective_appid(kb);
837 #endif
838         _D("__request_handler: %d", pkt->cmd);
839
840         switch (pkt->cmd) {
841                 case APP_OPEN:
842                 case APP_RESUME:
843                 case APP_START:
844                 case APP_START_RES:
845                 case APP_START_ASYNC:
846                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::launch", "x");
847                         if (cr.pid != 0 && ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
848                                 _E("launch request has been denied by smack");
849                                 ret = -EILLEGALACCESS;
850                                 __real_send(clifd, ret);
851                         } else {
852                                 __check_host_pid(kb, &cr);
853                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
854
855 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
856                                 // Check the multi-instance app
857                                 ai = appinfo_find(_raf, appid);
858                                 if (ai == NULL) {
859                                         _E("no appinfo");
860                                         __real_send(clifd, -ENOAPP);
861                                 } else {
862                                         const char* multi = appinfo_get_value(ai, AIT_MULTI_INSTANCE);
863                                         if( multi && strncmp(multi, "true", strlen("true")) == 0 ) {
864
865                                                 char* multi_appid =__get_metadata_value(appid, METADATA_MULTI_INSTANCE);
866                                                 if (multi_appid != NULL)
867                                                 {
868                                                         SECURE_LOGD("Multi-instance main: %s, sub: %s", appid, multi_appid);
869                                                         const char* target_appid = __check_target_appid(ai, appid, multi_appid);
870
871                                                         SECURE_LOGD("launch a target appid: - %s", target_appid);
872                                                         ret = _start_app(target_appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
873                                                 } else {
874                                                         SECURE_LOGD("No multi-instance app information, launch a main appid: - %s", appid);
875                                                         ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
876                                                 }
877
878                                                 free(multi_appid);
879                                         }
880                                         else
881                                         {
882                                                 SECURE_LOGD("launch a single-instance appid: %s", appid);
883                                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
884                                         }
885                                 }
886 #else
887                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
888 #endif
889
890                                 if (ret > 0 && bundle_get_type(kb, AUL_K_PRELAUCHING) == BUNDLE_TYPE_NONE) {
891 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
892                                         if (!app_group_is_group_app(kb)) {
893                                                 item_pkt_t *item = g_malloc0(sizeof(item_pkt_t));
894                                                 item->pid = ret;
895                                                 strncpy(item->appid, appid, 511);
896                                                 __add_item_running_list(item);
897                                                 g_free(item);
898                                         }
899 #endif
900 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
901                                         if (home_appid && strncmp(appid, home_appid, strlen(appid)) == 0)
902                                                 __send_home_launch_signal(ret);
903 #endif
904                                         g_timeout_add(1500, __add_history_handler, pkt);
905                                         free_pkt = 0;
906                                 }
907
908                                 if (kb != NULL)
909                                         bundle_free(kb), kb = NULL;
910                         }
911                         break;
912 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
913                 case APP_START_MULTI_INSTANCE:
914                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::launch", "x");
915                         if (cr.pid != 0 && ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
916                                 _E("launch request has been denied by smack");
917                                 ret = -EILLEGALACCESS;
918                                 __real_send(clifd, ret);
919                         } else {
920                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
921
922                                 SECURE_LOGD("launch a multi-instance appid: %s", appid);
923                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
924                         }
925
926                         if (ret > 0) {
927 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
928                                 if (!app_group_is_group_app(kb)) {
929                                         item_pkt_t *item = g_malloc0(sizeof(item_pkt_t));
930                                         item->pid = ret;
931                                         strncpy(item->appid, appid, 511);
932                                         __add_item_running_list(item);
933                                         g_free(item);
934                                 }
935 #endif
936 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
937                                 if (home_appid && strncmp(appid, home_appid, strlen(appid)) == 0)
938                                         __send_home_launch_signal(ret);
939 #endif
940                                 g_timeout_add(1500, __add_history_handler, pkt);
941                                 free_pkt = 0;
942                         }
943
944                         if (kb != NULL)
945                                 bundle_free(kb), kb = NULL;
946
947                         break;
948 #endif
949                 case APP_RESULT:
950                 case APP_CANCEL:
951                         ret = __foward_cmd(pkt->cmd, kb, cr.pid);
952                         close(clifd);
953                         break;
954                 case APP_PAUSE:
955                         appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
956                         ret = _status_app_is_running_v2_cached(appid);
957                         if (ret > 0) {
958                                 _pause_app(ret, clifd);
959                         } else {
960                                 _E("%s is not running", appid);
961                                 close(clifd);
962                         }
963                         break;
964                 case APP_RESUME_BY_PID:
965                 case APP_PAUSE_BY_PID:
966                 case APP_TERM_REQ_BY_PID:
967                         appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
968                         ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
969                         break;
970                 case APP_TERM_BY_PID_WITHOUT_RESTART:
971                 case APP_TERM_BY_PID_ASYNC:
972                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::terminate", "x");
973                         if (cr.pid != 0 && ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
974                                 _E("terminate request has been denied by smack");
975                                 ret = -EILLEGALACCESS;
976                                 __real_send(clifd, ret);
977                         } else {
978                                 term_pid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
979                                 appid = _status_app_get_appid_bypid(atoi(term_pid));
980                                 ai = appinfo_find(_raf, appid);
981                                 if (ai) {
982                                         appinfo_set_value((struct appinfo *)ai, AIT_STATUS, "norestart");
983                                         ret = __app_process_by_pid(pkt->cmd, term_pid, &cr, clifd);
984                                 } else {
985                                         ret = -1;
986                                         __send_result_to_client(clifd, ret);
987                                 }
988                         }
989                         break;
990                 case APP_TERM_BY_PID:
991                 case APP_KILL_BY_PID:
992                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::terminate", "x");
993                         if (cr.pid != 0 && ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
994                                 _E("terminate request has been denied by smack");
995                                 ret = -EILLEGALACCESS;
996                                 __real_send(clifd, ret);
997                         } else {
998                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
999                                 ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
1000                         }
1001                         break;
1002                 case APP_TERM_BGAPP_BY_PID:
1003                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::terminatebgapp", "x");
1004                         if (cr.pid != 0 && ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
1005                                 _E("terminate request has been denied by smack");
1006                                 ret = -EILLEGALACCESS;
1007                                 __real_send(clifd, ret);
1008                         } else {
1009                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
1010                                 ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
1011                         }
1012                         break;
1013                 case APP_RUNNING_INFO:
1014                         _status_send_running_appinfo_v2(clifd);
1015                         break;
1016                 case APP_RUNNING_INFO_MEMORY:
1017                         _status_send_running_appinfo(clifd);
1018                         break;
1019                 case APP_IS_RUNNING:
1020                         appid = malloc(MAX_PACKAGE_STR_SIZE);
1021                         if (appid == NULL) {
1022                                 _E("Failed to allocate memory");
1023                                 __send_result_to_client(clifd, -1);
1024                                 break;
1025                         }
1026                         strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
1027                         ret = _status_app_is_running_v2_cached(appid);
1028                         SECURE_LOGD("APP_IS_RUNNING : %s : %d",appid, ret);
1029                         if (ret > 0 && _status_get_app_info_status(ret) == STATUS_DYING) {
1030                                 SECURE_LOGD("APP_IS_RUNNING: %d is dying", ret);
1031                                 ret = -1;
1032                         }
1033                         __send_result_to_client(clifd, ret);
1034                         free(appid);
1035                         break;
1036                 case APP_GET_APPID_BYPID:
1037                         memcpy(&pid, pkt->data, sizeof(int));
1038                         ret = _status_get_appid_bypid(clifd, pid);
1039                         _D("APP_GET_APPID_BYPID : %d : %d", pid, ret);
1040                         break;
1041                 case APP_GET_PKGID_BYPID:
1042                         memcpy(&pid, pkt->data, sizeof(int));
1043                         ret = _status_get_pkgid_bypid(clifd, pid);
1044                         _D("APP_GET_PKGID_BYPID : %d : %d", pid, ret);
1045                         break;
1046                 case APP_KEY_RESERVE:
1047                         ret = _register_key_event(cr.pid);
1048                         __send_result_to_client(clifd, ret);
1049                         break;
1050                 case APP_KEY_RELEASE:
1051                         ret = _unregister_key_event(cr.pid);
1052                         __send_result_to_client(clifd, ret);
1053                         break;
1054                 case APP_STATUS_UPDATE:
1055                         status = (int *)pkt->data;
1056                         _W("app status : %d", *status);
1057                         if(*status == STATUS_NORESTART) {
1058                                 appid = _status_app_get_appid_bypid(cr.pid);
1059                                 ai = appinfo_find(_raf, appid);
1060                                 appinfo_set_value((struct appinfo *)ai, AIT_STATUS, "norestart");
1061                         } else {
1062                                 ret = _status_update_app_info_list(cr.pid, *status, FALSE);
1063                         }
1064                         close(clifd);
1065                         break;
1066                 case APP_GET_STATUS:
1067                         memcpy(&pid, pkt->data, sizeof(int));
1068                         ret = _status_get_app_info_status(pid);
1069                         __send_result_to_client(clifd, ret);
1070                         break;
1071
1072                 case APP_RUNNING_LIST_UPDATE:
1073                         /*appid = (char *)bundle_get_val(kb, AUL_K_APPID);
1074                           app_path = (char *)bundle_get_val(kb, AUL_K_EXEC);
1075                           tmp_pid = (char *)bundle_get_val(kb, AUL_K_PID);
1076                           pid = atoi(tmp_pid);
1077                           ret = _status_add_app_info_list(appid, app_path, pid);*/
1078                         ret = 0;
1079                         __send_result_to_client(clifd, ret);
1080                         break;
1081
1082                 case APP_GROUP_GET_WINDOW:
1083                         __dispatch_app_group_get_window(clifd, pkt);
1084                         break;
1085
1086                 case APP_GROUP_SET_WINDOW:
1087                         __dispatch_app_group_set_window(clifd, pkt, cr.pid);
1088                         break;
1089
1090                 case APP_GROUP_GET_FG:
1091                         __dispatch_app_group_get_fg_flag(clifd, pkt);
1092                         break;
1093
1094                 case APP_GROUP_GET_LEADER_PIDS:
1095                         __dispatch_app_group_get_leader_pids(clifd, pkt);
1096                         break;
1097
1098                 case APP_GROUP_GET_GROUP_PIDS:
1099                         __dispatch_app_group_get_group_pids(clifd, pkt);
1100                         break;
1101
1102                 case APP_GROUP_CLEAR_TOP:
1103                         __dispatch_app_group_clear_top(clifd, cr.pid);
1104                         break;
1105
1106                 case APP_GROUP_GET_LEADER_PID:
1107                         __dispatch_app_group_get_leader_pid(clifd, pkt);
1108                         break;
1109
1110                 case APP_GROUP_LOWER:
1111                         __dispatch_app_group_lower(clifd, cr.pid);
1112                         break;
1113
1114                 case APP_GROUP_GET_IDLE_PIDS:
1115                         __dispatch_app_group_get_idle_pids(clifd, pkt);
1116                         break;
1117
1118                 case APP_GET_CMDLINE:
1119                         memcpy(&pid, pkt->data, sizeof(int));
1120                         ret = _status_get_cmdline(clifd, pid);
1121                         _D("APP_GET_CMDLINE : %d : %d", pid, ret);
1122                         break;
1123
1124                 case APP_GET_PID:
1125                         appid = (char *)malloc(MAX_PACKAGE_STR_SIZE);
1126                         if (appid == NULL) {
1127                                 _E("failed to allocate appid");
1128                                 __send_result_to_client(clifd, -1);
1129                                 break;
1130                         }
1131                         strncpy(appid, (const char *)pkt->data, MAX_PACKAGE_STR_SIZE - 1);
1132                         ret = _status_app_is_running_v2_cached(appid);
1133                         SECURE_LOGD("APP_GET_PID: %s : %d", appid, ret);
1134                         __send_result_to_client(clifd, ret);
1135                         free(appid);
1136                         break;
1137
1138                 case APP_GET_PID_CACHE:
1139                         appid = (char *)malloc(MAX_PACKAGE_STR_SIZE);
1140                         if (appid == NULL) {
1141                                 _E("failed to allocate appid");
1142                                 __send_result_to_client(clifd, -1);
1143                                 break;
1144                         }
1145                         strncpy(appid, (const char *)pkt->data, MAX_PACKAGE_STR_SIZE - 1);
1146                         ret = _status_app_is_running_from_cache(appid);
1147                         SECURE_LOGD("APP_GET_PID_CACHE: %s : %d", appid, ret);
1148                         __send_result_to_client(clifd, ret);
1149                         free(appid);
1150                         break;
1151
1152                 case APP_GET_LAST_CALLER_PID:
1153                         memcpy(&pid, pkt->data, sizeof(int));
1154                         ret = _status_get_app_info_last_caller_pid(pid);
1155                         SECURE_LOGD("APP_GET_LAST_CALLER_PID: %d : %d", pid, ret);
1156                         __send_result_to_client(clifd, ret);
1157                         break;
1158                 case APP_SET_PROCESS_GROUP:
1159                         owner_pid = atoi(bundle_get_val(kb, AUL_K_OWNER_PID));
1160                         child_pid = atoi(bundle_get_val(kb, AUL_K_CHILD_PID));
1161                         ret = _send_set_process_group_signal_signal(owner_pid, child_pid);
1162                         if (kb != NULL)
1163                                 bundle_free(kb), kb = NULL;
1164                         __send_result_to_client(clifd, ret);
1165                         break;
1166                 case APP_GET_GROUP_INFO:
1167                         _status_send_group_info(clifd);
1168                         break;
1169                 default:
1170                         _E("no support packet");
1171                         close(clifd);
1172         }
1173
1174         if (free_pkt)
1175                 free(pkt);
1176
1177         if (kb != NULL)
1178                 bundle_free(kb), kb = NULL;
1179
1180         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1181         return TRUE;
1182 }
1183
1184 static gboolean __au_glib_check(GSource *src)
1185 {
1186         GSList *fd_list;
1187         GPollFD *tmp;
1188
1189         fd_list = src->poll_fds;
1190         do {
1191                 tmp = (GPollFD *) fd_list->data;
1192                 if ((tmp->revents & (POLLIN | POLLPRI)))
1193                         return TRUE;
1194                 fd_list = fd_list->next;
1195         } while (fd_list);
1196
1197         return FALSE;
1198 }
1199
1200 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
1201                 gpointer data)
1202 {
1203         callback(data);
1204         return TRUE;
1205 }
1206
1207 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
1208 {
1209         return FALSE;
1210 }
1211
1212 static GSourceFuncs funcs = {
1213         .prepare = __au_glib_prepare,
1214         .check = __au_glib_check,
1215         .dispatch = __au_glib_dispatch,
1216         .finalize = NULL
1217 };
1218
1219 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
1220 static void __home_appid_vconf_cb(keynode_t *key, void *data)
1221 {
1222         char *tmpstr;
1223
1224         tmpstr = vconf_keynode_get_str(key);
1225         if (tmpstr == NULL) {
1226                 return;
1227         }
1228
1229         if (home_appid) {
1230                 free(home_appid);
1231         }
1232         home_appid = strdup(tmpstr);
1233 }
1234 #endif
1235
1236 static int __signal_get_sigchld_fd(sigset_t mask)
1237 {
1238         int sfd;
1239
1240         sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
1241
1242         if (sfd == -1) {
1243                 _E("failed to create signalfd for SIGCHLD");
1244                 return -1;
1245         }
1246
1247         return sfd;
1248 }
1249
1250 static void __release_app(int pid)
1251 {
1252         const char *pkg_status;
1253         const char *appid = NULL;
1254         const struct appinfo *ai = NULL;
1255
1256         appid = _status_app_get_appid_bypid(pid);
1257         ai = appinfo_find(_raf, appid);
1258         pkg_status = appinfo_get_value(ai, AIT_STATUS);
1259         SECURE_LOGI("appid: %s", appid);
1260         if (ai && pkg_status && strncmp(pkg_status, "blocking", 8) == 0) {
1261                 appinfo_set_value((struct appinfo *)ai, AIT_STATUS, "restart");
1262         } else if (ai && pkg_status && strncmp(pkg_status, "norestart", 9) == 0) {
1263                 appinfo_set_value((struct appinfo *)ai, AIT_STATUS, "installed");
1264         } else {
1265                 if (appid != NULL && __check_restart(appid)) {
1266                         _release_srv(appid);
1267                 }
1268         }
1269
1270         __send_app_termination_signal(pid);
1271 }
1272
1273 static gboolean __sigchld_handler(gpointer data)
1274 {
1275         int fd = (int)data;
1276         struct signalfd_siginfo si;
1277
1278         while (1) {
1279                 int nr = read(fd, &si, sizeof(struct signalfd_siginfo));
1280
1281                 if (nr != sizeof(struct signalfd_siginfo))
1282                         break;
1283                 while (1) {
1284                         int status;
1285                         pid_t pid = waitpid(-1, &status, WNOHANG);
1286
1287                         if (pid <= 0)
1288                                 break;
1289                         _D("Sig child %d", pid);
1290                         __release_app(pid);
1291                 }
1292
1293         }
1294
1295         return TRUE;
1296 }
1297
1298 int _signal_block_sigchld(void)
1299 {
1300         sigset_t mask;
1301
1302         sigemptyset(&mask);
1303         sigaddset(&mask, SIGCHLD);
1304
1305         if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1) {
1306                 _E("failed to sigprocmask");
1307                 return -1;
1308         }
1309
1310         return __signal_get_sigchld_fd(mask);
1311 }
1312
1313 int _signal_unblock_sigchld(void)
1314 {
1315         if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
1316                 _E("SIG_SETMASK error");
1317                 return -1;
1318         }
1319
1320         _D("SIGCHLD unblocked");
1321         return 0;
1322 }
1323
1324 int _request_init(struct amdmgr *amd, int fd_sig)
1325 {
1326         int fd;
1327         int r;
1328         GPollFD *gpollfd;
1329         GPollFD *gpollfd_sig;
1330         GSource *src;
1331         GSource *src_sig;
1332         DBusError error;
1333
1334         fd = __create_server_sock(AUL_UTIL_PID);
1335         if (fd < 0) {
1336                 _E("fail to create server sock");
1337                 return -1;
1338         }
1339         src = g_source_new(&funcs, sizeof(GSource));
1340
1341         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
1342         if (gpollfd == NULL) {
1343                 g_source_unref(src);
1344                 close(fd);
1345                 return -1;
1346         }
1347
1348         gpollfd->events = POLLIN;
1349         gpollfd->fd = fd;
1350
1351         g_source_add_poll(src, gpollfd);
1352         g_source_set_callback(src, (GSourceFunc) __request_handler,
1353                         (gpointer) gpollfd, NULL);
1354         g_source_set_priority(src, G_PRIORITY_DEFAULT);
1355
1356         r = g_source_attach(src, NULL);
1357         if (r  == 0) {
1358                 _E("fail to attach the source : %d", r);
1359                 return -1;
1360         }
1361
1362         src_sig = g_source_new(&funcs, sizeof(GSource));
1363
1364         gpollfd_sig = (GPollFD *) g_malloc(sizeof(GPollFD));
1365         if (gpollfd_sig == NULL) {
1366                 g_source_unref(src_sig);
1367                 close(fd_sig);
1368                 return -1;
1369         }
1370
1371         gpollfd_sig->events = G_IO_IN;
1372         gpollfd_sig->fd = fd_sig;
1373
1374         g_source_add_poll(src_sig, gpollfd_sig);
1375         g_source_set_callback(src_sig, (GSourceFunc) __sigchld_handler,
1376                         (gpointer) fd_sig, NULL);
1377         g_source_set_priority(src_sig, G_PRIORITY_DEFAULT);
1378         r = g_source_attach(src_sig, NULL);
1379         if (r  == 0) {
1380                 _E("fail to attach the source : %d", r);
1381                 return -1;
1382         }
1383
1384         _raf = amd->af;
1385
1386         r = rua_init();
1387         r = rua_clear_history();
1388
1389         _D("rua_clear_history : %d", r);
1390
1391         dbus_error_init(&error);
1392         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1393
1394 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
1395         home_appid = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
1396         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, __home_appid_vconf_cb, NULL) != 0) {
1397                 _E("Unable to register callback for VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME\n");
1398         }
1399 #endif
1400
1401         restart_tbl = g_hash_table_new(g_str_hash, g_str_equal);
1402         return 0;
1403 }
1404
1405 #ifdef _APPFW_FEATURE_SEND_HOME_LAUNCH_SIGNAL
1406 const char* _get_home_appid(void)
1407 {
1408         return home_appid;
1409 }
1410 #endif
1411