3f75b6e3e94a99ad633db11e1c8c3419ad39f33f
[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 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <dlfcn.h>
29 #include <poll.h>
30 #include <aul.h>
31 #include <glib.h>
32 #include <bundle.h>
33 #include <rua.h>
34 #include <proc_stat.h>
35 #include <security-server.h>
36 #include <vconf.h>
37
38 #include "amd_config.h"
39 #include "simple_util.h"
40 #include "app_sock.h"
41 #include "app_signal.h"
42 #include "aul_util.h"
43 #include "amd_request.h"
44 #include "amd_key.h"
45 #include "amd_launch.h"
46 #include "amd_appinfo.h"
47 #include "amd_cgutil.h"
48 #include "amd_status.h"
49
50 #include <pkgmgr-info.h>
51
52 #define INHOUSE_UID     5000
53
54 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
55 #define METADATA_MULTI_INSTANCE         "http://developer.samsung.com/tizen/metadata/multiinstance"
56 #endif
57
58 struct appinfomgr *_raf;
59 struct cginfo *_rcg;
60 static DBusConnection *bus = NULL;
61 char *home_appid = NULL;
62
63
64 static int __send_result_to_client(int fd, int res);
65 static gboolean __request_handler(gpointer data);
66
67 static int __send_result_to_client(int fd, int res)
68 {
69         _D("__send_result_to_client, res: %d", fd, res);
70
71         if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
72                 if (errno == EPIPE) {
73                         _E("send failed due to EPIPE.\n");
74                 }
75
76                 _E("send fail to client");
77         }
78         close(fd);
79         return 0;
80 }
81
82 static void __real_send(int clifd, int ret)
83 {
84         if(clifd <= 0) {
85                 return;
86         }
87         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
88                 if (errno == EPIPE) {
89                         _E("send failed due to EPIPE.\n");
90                 }
91                 _E("send fail to client");
92         }
93
94         close(clifd);
95 }
96
97 static int __get_caller_pid(bundle *kb)
98 {
99         const char *pid_str;
100         int pid;
101
102         pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
103         if(pid_str)
104                 goto end;
105
106         pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
107         if (pid_str == NULL)
108                 return -1;
109
110 end:
111         pid = atoi(pid_str);
112         if (pid <= 1)
113                 return -1;
114
115         return pid;
116 }
117
118 static int __foward_cmd(int cmd, bundle *kb, int cr_pid)
119 {
120         int pid;
121         int pgid;
122         char tmp_pid[MAX_PID_STR_BUFSZ];
123         int datalen;
124         bundle_raw *kb_data;
125         int res;
126
127         if ((pid = __get_caller_pid(kb)) < 0)
128         {
129                 return AUL_R_ERROR;
130         }
131
132         pgid = getpgid(cr_pid);
133         if(pgid > 0) {
134                 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", pgid);
135                 bundle_del(kb, AUL_K_CALLEE_PID);
136                 bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
137         }
138
139         _D("__forward_cmd: %d %d", cr_pid, pgid);
140
141         bundle_encode(kb, &kb_data, &datalen);
142         if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
143                 res = AUL_R_ERROR;
144
145         free(kb_data);
146
147         return res;
148 }
149
150 static int __app_process_by_pid(int cmd,
151         const char *pkg_name, struct ucred *cr, int clifd)
152 {
153         int pid;
154         int ret = -1;
155         int dummy;
156
157         if (pkg_name == NULL)
158                 return -1;
159
160         pid = atoi(pkg_name);
161         if (pid <= 1) {
162                 _E("invalid pid");
163                 return -1;
164         }
165
166         if (_status_get_app_info_status(pid) == -1) {
167                 char buf[512];
168                 if (_status_get_pkgname_bypid(pid, buf, 512) == -1) {
169                         _E("request for unknown pid. It might not be a pid of app: %d", pid);
170                         return -1;
171                 }
172         }
173
174         if (cmd == APP_RESUME_BY_PID)
175                 proc_group_change_status(PROC_CGROUP_SET_RESUME_REQUEST, pid, NULL);
176         else
177                 proc_group_change_status(PROC_CGROUP_SET_TERMINATE_REQUEST, pid, NULL);
178
179         _D("__app_process_by_pid, cmd: %d, pid: %d, ", cmd, pid);
180         switch (cmd) {
181         case APP_RESUME_BY_PID:
182                 ret = _resume_app(pid, clifd);
183                 break;
184         case APP_TERM_BY_PID:
185         case APP_TERM_BY_PID_WITHOUT_RESTART:
186                 ret = _term_app(pid, clifd);
187                 break;
188         case APP_KILL_BY_PID:
189                 if ((ret = _send_to_sigkill(pid)) < 0)
190                         _E("fail to killing - %d\n", pid);
191                 __real_send(clifd, ret);
192                 break;
193         case APP_TERM_REQ_BY_PID:
194                 if ((ret = __app_send_raw(pid, cmd, (unsigned char *)&dummy, sizeof(int))) < 0) {
195                         _D("terminate req packet send error");
196                 }
197                 __real_send(clifd, ret);
198                 break;
199         case APP_TERM_BY_PID_ASYNC:
200                 if ((ret = __app_send_raw_with_noreply(pid, cmd, (unsigned char *)&dummy, sizeof(int))) < 0) {
201                         _D("terminate req packet send error");
202                 }
203                 __real_send(clifd, ret);
204                 break;
205         }
206
207         return ret;
208 }
209
210 static gboolean __add_history_handler(gpointer user_data)
211 {
212         struct rua_rec rec;
213         int ret;
214         bundle *kb = NULL;
215         char *appid = NULL;
216         char *app_path = NULL;
217         struct appinfo *ai;
218         app_pkt_t *pkt = (app_pkt_t *)user_data;
219
220         if (!pkt)
221                 return FALSE;
222
223         kb = bundle_decode(pkt->data, pkt->len);
224         appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
225
226 #ifdef _APPFW_FEATURE_CONTACT_PHONE_AS_ONE_APP
227         // When the Phone is executed, the Contacts is shown on task manager.
228         int need_free = 0;
229         if (strncmp(appid, "org.tizen.phone", strlen("org.tizen.phone")) == 0)
230         {
231                 appid = strndup("org.tizen.contacts", strlen("org.tizen.contacts"));
232                 need_free = 1;
233         }
234 #endif
235         ai = (struct appinfo *)appinfo_find(_raf, appid);
236         app_path = (char *)appinfo_get_value(ai, AIT_EXEC);
237
238         memset((void *)&rec, 0, sizeof(rec));
239
240         rec.pkg_name = appid;
241         rec.app_path = app_path;
242
243         if(pkt->len > 0) {
244                 rec.arg = (char *)pkt->data;
245         }
246
247         SECURE_LOGD("add rua history %s %s", rec.pkg_name, rec.app_path);
248
249         ret = rua_add_history(&rec);
250         if (ret == -1)
251                 _D("rua add history error");
252
253         if (kb != NULL)
254                 bundle_free(kb);
255         free(pkt);
256
257 #ifdef _APPFW_FEATURE_CONTACT_PHONE_AS_ONE_APP
258         if (need_free)
259                 free(appid);
260 #endif
261
262         return FALSE;
263 }
264
265 static int __get_pid_cb(void *user_data, const char *group, pid_t pid)
266 {
267         int *sz = user_data;
268
269         _D("%s: %d : %d", *sz, pid);
270         *sz = 1; /* 1 is enough */
271
272         return -1; /* stop the iteration */
273 }
274
275 static int __releasable(const char *filename)
276 {
277         int sz;
278         int r;
279
280         if (!filename || !*filename) {
281                 _E("release service: name is empty");
282                 return -1;
283         }
284
285         r = cgutil_exist_group(_rcg, CTRL_MGR, filename);
286         if (r == -1) {
287                 SECURE_LOGE("release service: exist: %s", strerror(errno));
288                 return -1;
289         }
290         if (r == 0) {
291                 SECURE_LOGE("release service: '%s' already not exist", filename);
292                 return -1;
293         }
294
295         sz = 0;
296         r = cgutil_group_foreach_pid(_rcg, CTRL_MGR, filename,
297                         __get_pid_cb, &sz);
298         if (r == -1) {
299                 SECURE_LOGE("release service: '%s' read pid error", filename);
300                 return -1;
301         }
302         if (sz > 0) {
303                 SECURE_LOGE("release service: '%s' group has process", filename);
304                 return -1;
305         }
306
307         return 0;
308 }
309
310 int __release_srv(const char *filename)
311 {
312         int r;
313         const struct appinfo *ai;
314
315         r = __releasable(filename);
316         if (r == -1)
317                 return -1;
318
319         ai = (struct appinfo *)appinfo_find(_raf, filename);
320         if (!ai) {
321                 SECURE_LOGE("release service: '%s' not found", filename);
322                 return -1;
323         }
324
325         r = appinfo_get_boolean(ai, AIT_RESTART);
326         if (r == 1) {
327                 SECURE_LOGD("Auto restart set: '%s'", filename);
328                 return _start_srv(ai, NULL);
329         }
330
331         service_release(filename);
332
333         r = cgutil_remove_group(_rcg, CTRL_MGR, filename);
334         if (r == -1) {
335                 SECURE_LOGE("'%s' group remove error: %s", filename, strerror(errno));
336                 return -1;
337         }
338
339         return 0;
340 }
341
342 static inline int __send_home_launch_signal(int pid)
343 {
344         DBusMessage *message;
345
346         if (bus == NULL)
347                 return -1;
348
349         message = dbus_message_new_signal(AUL_DBUS_PATH,
350                                           AUL_DBUS_SIGNAL_INTERFACE,
351                                           AUL_DBUS_HOMELAUNCH_SIGNAL);
352
353         if (dbus_message_append_args(message,
354                                      DBUS_TYPE_UINT32, &pid,
355                                      DBUS_TYPE_INVALID) == FALSE) {
356                 _E("Failed to load data error");
357                 return -1;
358         }
359
360         if (dbus_connection_send(bus, message, NULL) == FALSE) {
361                 _E("dbus send error");
362                 return -1;
363         }
364
365         dbus_connection_flush(bus);
366         dbus_message_unref(message);
367
368         _D("send dead signal done\n");
369
370         return 0;
371 }
372
373 static inline int __send_app_termination_signal(int dead_pid)
374 {
375         DBusMessage *message;
376
377         if (bus == NULL)
378                 return -1;
379
380         message = dbus_message_new_signal(AUL_DBUS_PATH,
381                                           AUL_DBUS_SIGNAL_INTERFACE,
382                                           AUL_DBUS_APPDEAD_SIGNAL);
383
384         if (dbus_message_append_args(message,
385                                      DBUS_TYPE_UINT32, &dead_pid,
386                                      DBUS_TYPE_INVALID) == FALSE) {
387                 _E("Failed to load data error");
388                 return -1;
389         }
390
391         if (dbus_connection_send(bus, message, NULL) == FALSE) {
392                 _E("dbus send error");
393                 return -1;
394         }
395
396         dbus_connection_flush(bus);
397         dbus_message_unref(message);
398
399         _D("send dead signal done\n");
400
401         return 0;
402 }
403
404 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
405 static char* __get_metadata_value(const char *appid, const char *metadata_key)
406 {
407         int ret = 0;
408         pkgmgrinfo_appinfo_h handle;
409         char *metadata_value = NULL;
410         char *multi_appid = NULL;
411
412         ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
413         if (ret != PMINFO_R_OK)
414                 return NULL;
415
416         ret = pkgmgrinfo_appinfo_get_metadata_value(handle, metadata_key, &metadata_value);
417         if (ret != PMINFO_R_OK) {
418                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
419                 return NULL;
420         }
421
422         multi_appid = strdup(metadata_value);
423
424         pkgmgrinfo_appinfo_destroy_appinfo(handle);
425
426         return multi_appid;
427 }
428
429 static const char* __check_target_appid(const struct appinfo* ai, const char *appid, const char *multi_appid)
430 {
431         const char* target = NULL;
432
433         // Both apps are running
434         if (_status_app_is_running(appid) != -1 && _status_app_is_running(multi_appid) != -1) {
435                 const char* toggle = appinfo_get_value(ai, AIT_TOGGLE_ORDER);
436                 int order = atoi(toggle);
437
438                 _D("launch a multi-instance app with toggle mode: %d", order);
439                 switch (order) {
440                         case 0:
441                                 target = multi_appid;
442                                 appinfo_set_value(ai, AIT_TOGGLE_ORDER, "1");
443                                 break;
444
445                         case 1:
446                                 target = appid;
447                                 appinfo_set_value(ai, AIT_TOGGLE_ORDER, "0");
448                                 break;
449
450                         default:
451                                 break;
452                 }
453         } else {
454                 // Main app is running
455                 if (_status_app_is_running(appid) != -1) {
456                         _D("Send a request to the running main appid: %s", appid);
457                         target = appid;
458                         // Sub app is running
459                 } else if (_status_app_is_running(multi_appid) != -1) {
460                         _D("Send a request to the running sub appid: %s", multi_appid);
461                         target = multi_appid;
462                 } else {
463                         _D("Both apps are not running, launch a main app - %s", appid);
464                         target = appid;
465                 }
466         }
467
468         return target;
469 }
470 #endif
471
472 static gboolean __request_handler(gpointer data)
473 {
474         GPollFD *gpollfd = (GPollFD *) data;
475         int fd = gpollfd->fd;
476         app_pkt_t *pkt;
477         int clifd;
478         struct ucred cr;
479         int *status;
480         int ret = -1;
481         int free_pkt = 1;
482         char *appid;
483         char *term_pid = NULL;
484         int pid;
485         bundle *kb = NULL;
486         const struct appinfo *ai;
487         const char *pkg_status;
488         item_pkt_t *item;
489
490         if ((pkt = __app_recv_raw(fd, &clifd, &cr)) == NULL) {
491                 _E("recv error");
492                 return FALSE;
493         }
494
495         _D("__request_handler: %d", pkt->cmd);
496         switch (pkt->cmd) {
497                 case APP_OPEN:
498                 case APP_RESUME:
499                 case APP_START:
500                 case APP_START_RES:
501                 case APP_START_ASYNC:
502                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::launch", "x");
503                         if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
504                                 _E("launch request has been denied by smack");
505                                 ret = -EILLEGALACCESS;
506                                 __real_send(clifd, ret);
507                         } else {
508                                 kb = bundle_decode(pkt->data, pkt->len);
509                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
510
511 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
512                                 // Check the multi-instance app
513                                 ai = appinfo_find(_raf, appid);
514                                 if (ai == NULL) {
515                                         _E("no appinfo");
516                                         __real_send(clifd, -1);
517                                         ret = -1;
518                                 } else {
519                                         const char* multi = appinfo_get_value(ai, AIT_MULTI_INSTANCE);
520                                         if( multi && strncmp(multi, "true", strlen("true")) == 0 ) {
521
522                                                 char* multi_appid =__get_metadata_value(appid, METADATA_MULTI_INSTANCE);
523                                                 if (multi_appid != NULL)
524                                                 {
525                                                         _D("Multi-instance main: %s, sub: %s", appid, multi_appid);
526
527                                                         const char* target_appid = __check_target_appid(ai, appid, multi_appid);
528
529                                                         _D("launch a target appid: - %s", target_appid);
530                                                         ret = _start_app(target_appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
531                                                 } else {
532                                                         _D("No multi-instance app information, launch a main appid: - %s", appid);
533                                                         ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
534                                                 }
535
536                                                 free(multi_appid);
537                                         }
538                                         else
539                                         {
540                                                 _D("launch a single-instance appid: %s", appid);
541                                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
542                                         }
543                                 }
544 #else
545                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
546 #endif
547
548                                 if(ret > 0 && bundle_get_type(kb, AUL_K_PRELAUCHING) == BUNDLE_TYPE_NONE) {
549                                         item = calloc(1, sizeof(item_pkt_t));
550                                         item->pid = ret;
551                                         strncpy(item->appid, appid, 511);
552                                         free_pkt = 0;
553
554                                         if (home_appid && strncmp(appid, home_appid, strlen(appid)) == 0)
555                                                 __send_home_launch_signal(ret);
556 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
557                                         __add_item_running_list(item);
558 #endif
559                                         g_timeout_add(1000, __add_history_handler, pkt);
560                                 }
561
562                                 if (kb != NULL)
563                                         bundle_free(kb), kb = NULL;
564                         }
565                         break;
566 #ifdef _APPFW_FEATURE_MULTI_INSTANCE
567                 case APP_START_MULTI_INSTANCE:
568                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::launch", "x");
569                         if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
570                                 _E("launch request has been denied by smack");
571                                 ret = -EILLEGALACCESS;
572                                 __real_send(clifd, ret);
573                         } else {
574                                 kb = bundle_decode(pkt->data, pkt->len);
575                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
576
577                                 _D("launch a multi-instance appid: %s", appid);
578                                 ret = _start_app(appid, kb, pkt->cmd, cr.pid, cr.uid, clifd);
579                         }
580
581                         if(ret > 0) {
582                                 item = calloc(1, sizeof(item_pkt_t));
583                                 item->pid = ret;
584                                 strncpy(item->appid, appid, 511);
585                                 free_pkt = 0;
586
587                                 if (home_appid && strncmp(appid, home_appid, strlen(appid)) == 0)
588                                         __send_home_launch_signal(ret);
589 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
590                                 __add_item_running_list(item);
591 #endif
592                                 g_timeout_add(1000, __add_history_handler, pkt);
593                         }
594
595                         if (kb != NULL)
596                                 bundle_free(kb), kb = NULL;
597
598                         break;
599 #endif
600                 case APP_RESULT:
601                 case APP_CANCEL:
602                         kb = bundle_decode(pkt->data, pkt->len);
603                         ret = __foward_cmd(pkt->cmd, kb, cr.pid);
604                         //__real_send(clifd, ret);
605                         close(clifd);
606                         break;
607                 case APP_RESUME_BY_PID:
608                 case APP_TERM_REQ_BY_PID:
609                         kb = bundle_decode(pkt->data, pkt->len);
610                         appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
611                         ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
612                         break;
613                 case APP_TERM_BY_PID_WITHOUT_RESTART:
614                 case APP_TERM_BY_PID_ASYNC:
615                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::terminate", "x");
616                         if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
617                                 _E("terminate request has been denied by smack");
618                                 ret = -EILLEGALACCESS;
619                                 __real_send(clifd, ret);
620                         } else {
621                                 kb = bundle_decode(pkt->data, pkt->len);
622                                 term_pid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
623                                 appid = _status_app_get_appid_bypid(atoi(term_pid));
624                                 ai = appinfo_find(_raf, appid);
625                                 if(ai) {
626                                         appinfo_set_value(ai, AIT_STATUS, "norestart");
627                                         ret = __app_process_by_pid(pkt->cmd, term_pid, &cr, clifd);
628                                 } else {
629                                         ret = -1;
630                                         __real_send(clifd, ret);
631                                 }
632                         }
633                         break;
634                 case APP_TERM_BY_PID:
635                 case APP_KILL_BY_PID:
636                         ret = security_server_check_privilege_by_sockfd(clifd, "aul::terminate", "x");
637                         if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
638                                 _E("terminate request has been denied by smack");
639                                 ret = -EILLEGALACCESS;
640                                 __real_send(clifd, ret);
641                         } else {
642                                 kb = bundle_decode(pkt->data, pkt->len);
643                                 appid = (char *)bundle_get_val(kb, AUL_K_PKG_NAME);
644                                 ret = __app_process_by_pid(pkt->cmd, appid, &cr, clifd);
645                         }
646                         break;
647                 case APP_RUNNING_INFO:
648                         _status_send_running_appinfo_v2(clifd);
649                         break;
650                 case APP_RUNNING_INFO_MEMORY:
651                         _status_send_running_appinfo(clifd);
652                         break;
653                 case APP_IS_RUNNING:
654                         appid = malloc(MAX_PACKAGE_STR_SIZE);
655                         if (appid == NULL) {
656                                 _E("out of memory");
657                                 ret = -1;
658                                 __send_result_to_client(clifd, ret);
659                                 break;
660                         }
661
662                         strncpy(appid, (const char*)pkt->data, MAX_PACKAGE_STR_SIZE-1);
663                         ret = _status_app_is_running_v2(appid);
664                         SECURE_LOGD("APP_IS_RUNNING : %s : %d",appid, ret);
665                         __send_result_to_client(clifd, ret);
666                         free(appid);
667                         break;
668                 case APP_GET_APPID_BYPID:
669                         memcpy(&pid, pkt->data, sizeof(int));
670                         ret = _status_get_appid_bypid(clifd, pid);
671                         _D("APP_GET_APPID_BYPID : %d : %d", pid, ret);
672                         break;
673                 case APP_GET_PKGID_BYPID:
674                         memcpy(&pid, pkt->data, sizeof(int));
675                         ret = _status_get_pkgid_bypid(clifd, pid);
676                         _D("APP_GET_PKGID_BYPID : %d : %d", pid, ret);
677                         break;
678                 case APP_KEY_RESERVE:
679                         ret = _register_key_event(cr.pid);
680                         __send_result_to_client(clifd, ret);
681                         break;
682                 case APP_KEY_RELEASE:
683                         ret = _unregister_key_event(cr.pid);
684                         __send_result_to_client(clifd, ret);
685                         break;
686                 case APP_STATUS_UPDATE:
687                         status = (int *)pkt->data;
688                         if(*status == STATUS_NORESTART) {
689                                 appid = _status_app_get_appid_bypid(cr.pid);
690                                 ai = appinfo_find(_raf, appid);
691                                 if (ai)
692                                         appinfo_set_value(ai, AIT_STATUS, "norestart");
693                         } else {
694                                 ret = _status_update_app_info_list(cr.pid, *status);
695                         }
696                         //__send_result_to_client(clifd, ret);
697                         close(clifd);
698                         break;
699                 case APP_RELEASED:
700                         appid = malloc(MAX_PACKAGE_STR_SIZE);
701                         if (appid == NULL) {
702                                 _E("out of memory");
703                                 ret = -1;
704                                 __send_result_to_client(clifd, ret);
705                                 break;
706                         }
707
708                         strncpy(appid, (const char*)&pkt->data[1], MAX_PACKAGE_STR_SIZE-1);
709                         ai = appinfo_find(_raf, appid);
710                         pkg_status = appinfo_get_value(ai, AIT_STATUS);
711                         SECURE_LOGD("appid(%s) pkg_status(%s)", appid, pkg_status);
712                         if(ai && pkg_status && strncmp(pkg_status, "blocking", 8) == 0) {
713                                 appinfo_set_value(ai, AIT_STATUS, "restart");
714                         } else if (ai && pkg_status && strncmp(pkg_status, "norestart", 9) == 0) {
715                                 appinfo_set_value(ai, AIT_STATUS, "installed");
716                         } else {
717                                 ret = __release_srv(appid);
718                         }
719                         __send_result_to_client(clifd, ret);
720                         ret = _status_app_is_running(appid);
721                         SECURE_LOGI("appid(%s) dead pid(%d)", appid, ret);
722                         if(ret > 0)
723                                 __send_app_termination_signal(ret);
724                         free(appid);
725                         break;
726                 case APP_RUNNING_LIST_UPDATE:
727                         /*kb = bundle_decode(pkt->data, pkt->len);
728                           appid = (char *)bundle_get_val(kb, AUL_K_APPID);
729                           app_path = (char *)bundle_get_val(kb, AUL_K_EXEC);
730                           tmp_pid = (char *)bundle_get_val(kb, AUL_K_PID);
731                           pid = atoi(tmp_pid);
732                           ret = _status_add_app_info_list(appid, app_path, pid);*/
733                         ret = 0;
734                         __send_result_to_client(clifd, ret);
735                         break;
736
737                 case APP_GET_CMDLINE:
738                         memcpy(&pid, pkt->data, sizeof(int));
739                         ret = _status_get_cmdline(clifd, pid);
740                         _D("APP_GET_CMDLINE : %d : %d", pid, ret);
741                         break;
742
743                 default:
744                         _E("no support packet");
745                         close(clifd);
746         }
747
748         if (free_pkt)
749                 free(pkt);
750
751         if (kb != NULL)
752                 bundle_free(kb), kb = NULL;
753
754         return TRUE;
755 }
756
757 static gboolean __au_glib_check(GSource *src)
758 {
759         GSList *fd_list;
760         GPollFD *tmp;
761
762         fd_list = src->poll_fds;
763         do {
764                 tmp = (GPollFD *) fd_list->data;
765                 if ((tmp->revents & (POLLIN | POLLPRI)))
766                         return TRUE;
767                 fd_list = fd_list->next;
768         } while (fd_list);
769
770         return FALSE;
771 }
772
773 static gboolean __au_glib_dispatch(GSource *src, GSourceFunc callback,
774                 gpointer data)
775 {
776         callback(data);
777         return TRUE;
778 }
779
780 static gboolean __au_glib_prepare(GSource *src, gint *timeout)
781 {
782         return FALSE;
783 }
784
785 static GSourceFuncs funcs = {
786         .prepare = __au_glib_prepare,
787         .check = __au_glib_check,
788         .dispatch = __au_glib_dispatch,
789         .finalize = NULL
790 };
791
792 static void __home_appid_vconf_cb(keynode_t *key, void *data)
793 {
794         char *tmpstr;
795
796         tmpstr = vconf_keynode_get_str(key);
797         if (tmpstr == NULL) {
798                 return;
799         }
800
801         if (home_appid) {
802                 free(home_appid);
803         }
804         home_appid = strdup(tmpstr);
805 }
806
807 int _request_init(struct amdmgr *amd)
808 {
809         int fd;
810         int r;
811         GPollFD *gpollfd;
812         GSource *src;
813         DBusError error;
814
815         fd = __create_server_sock(AUL_UTIL_PID);
816         src = g_source_new(&funcs, sizeof(GSource));
817
818         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
819         if (gpollfd == NULL) {
820                 _E("out of memory");
821                 g_source_unref(src);
822                 close(fd);
823                 return -1;
824         }
825
826         gpollfd->events = POLLIN;
827         gpollfd->fd = fd;
828
829         g_source_add_poll(src, gpollfd);
830         g_source_set_callback(src, (GSourceFunc) __request_handler,
831                         (gpointer) gpollfd, NULL);
832         g_source_set_priority(src, G_PRIORITY_DEFAULT);
833
834         r = g_source_attach(src, NULL);
835         if (r  == 0)
836         {
837                 _E("fail to attach the source : %d", r);
838                 return -1;
839         }
840
841         _raf = amd->af;
842         _rcg = amd->cg;
843
844         r = rua_init();
845         r = rua_clear_history();
846
847         _D("rua_clear_history : %d", r);
848
849         dbus_error_init(&error);
850         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
851         home_appid = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
852         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, __home_appid_vconf_cb, NULL) != 0) {
853                 _E("Unable to register callback for VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME\n");
854         }
855
856         return 0;
857 }
858
859