Support launch reqeust async API
[platform/core/appfw/aul-1.git] / src / launch.c
1 /*
2  * Copyright (c) 2000 - 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 <sys/time.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <dirent.h>
26 #include <ctype.h>
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <ttrace.h>
30
31 #include <bundle_internal.h>
32
33 #include "app_signal.h"
34 #include "aul.h"
35 #include "aul_api.h"
36 #include "aul_sock.h"
37 #include "aul_util.h"
38 #include "launch.h"
39 #include "key.h"
40 #include "aul_app_com.h"
41 #include "aul_error.h"
42
43 #define TEP_ISMOUNT_MAX_RETRY_CNT 20
44
45 static int aul_initialized = 0;
46 static int aul_fd;
47 static void *__window_object = NULL;
48 static void *__bg_object = NULL;
49 static void *__conformant_object = NULL;
50
51 static void __clear_internal_key(bundle *kb);
52 static inline void __set_stime(bundle *kb);
53
54 int aul_is_initialized()
55 {
56         return aul_initialized;
57 }
58
59 static int __send_cmd_for_uid_opt(int pid, uid_t uid, int cmd, bundle *kb, int opt)
60 {
61         int res;
62
63         res = aul_sock_send_bundle(pid, uid, cmd, kb, opt);
64         if (res < 0)
65                 res = aul_error_convert(res);
66
67         return res;
68 }
69
70 static int __send_cmd_noreply_for_uid_opt(int pid, uid_t uid,
71                 int cmd, bundle *kb, int opt)
72 {
73         int res;
74
75         res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_NOREPLY);
76         if (res < 0)
77                 res = aul_error_convert(res);
78
79         return res;
80 }
81
82 static int __send_cmd_async_for_uid_opt(int pid, uid_t uid,
83                 int cmd, bundle *kb, int opt)
84 {
85         int res;
86
87         res = aul_sock_send_bundle(pid, uid, cmd, kb, opt | AUL_SOCK_ASYNC);
88         if (res < 0)
89                 res = aul_error_convert(res);
90
91         return res;
92 }
93
94 /**
95  * @brief       encode kb and send it to 'pid'
96  * @param[in]   pid             receiver's pid
97  * @param[in]   cmd             message's status (APP_START | APP_RESULT)
98  * @param[in]   kb              data
99  */
100 API int app_send_cmd(int pid, int cmd, bundle *kb)
101 {
102         return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NONE);
103 }
104
105 API int app_send_cmd_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
106 {
107         return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_NONE);
108 }
109
110 API int app_send_cmd_with_queue_for_uid(int pid, uid_t uid, int cmd, bundle *kb)
111 {
112         return __send_cmd_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
113 }
114
115 API int app_send_cmd_with_queue_noreply_for_uid(int pid, uid_t uid,
116                                         int cmd, bundle *kb)
117 {
118         return __send_cmd_noreply_for_uid_opt(pid, uid, cmd, kb, AUL_SOCK_QUEUE);
119 }
120
121 API int app_send_cmd_with_noreply(int pid, int cmd, bundle *kb)
122 {
123         return __send_cmd_for_uid_opt(pid, getuid(), cmd, kb, AUL_SOCK_NOREPLY);
124 }
125
126 API int app_send_cmd_to_launchpad(const char *pad_type, uid_t uid, int cmd, bundle *kb)
127 {
128         int fd;
129         int len;
130         int res;
131         char buf[1024];
132
133         fd = aul_sock_create_launchpad_client(pad_type, uid);
134         if (fd < 0)
135                 return -1;
136
137         res = aul_sock_send_bundle_with_fd(fd, cmd,
138                         kb, AUL_SOCK_ASYNC);
139         if (res < 0) {
140                 close(fd);
141                 return res;
142         }
143
144 retry_recv:
145         len = recv(fd, &res, sizeof(int), 0);
146         if (len == -1) {
147                 if (errno == EAGAIN) {
148                         _E("recv timeout: %d(%s)",
149                                         errno,
150                                         strerror_r(errno, buf, sizeof(buf)));
151                         res = -EAGAIN;
152                 } else if (errno == EINTR) {
153                         _D("recv: %d(%s)",
154                                         errno,
155                                         strerror_r(errno, buf, sizeof(buf)));
156                         goto retry_recv;
157                 } else {
158                         _E("recv error: %d(%s)",
159                                         errno,
160                                         strerror_r(errno, buf, sizeof(buf)));
161                         res = -ECOMM;
162                 }
163         }
164
165         close(fd);
166
167         return res;
168 }
169
170 static void __clear_internal_key(bundle *kb)
171 {
172         bundle_del(kb, AUL_K_CALLER_PID);
173         bundle_del(kb, AUL_K_APPID);
174         bundle_del(kb, AUL_K_WAIT_RESULT);
175         bundle_del(kb, AUL_K_SEND_RESULT);
176         bundle_del(kb, AUL_K_ARGV0);
177 }
178
179 static inline void __set_stime(bundle *kb)
180 {
181         struct timeval tv;
182         char tmp[MAX_LOCAL_BUFSZ];
183
184         gettimeofday(&tv, NULL);
185         snprintf(tmp, MAX_LOCAL_BUFSZ, "%ld/%ld", tv.tv_sec, tv.tv_usec);
186         bundle_del(kb, AUL_K_STARTTIME);
187         bundle_add(kb, AUL_K_STARTTIME, tmp);
188 }
189
190 /**
191  * @brief       start caller with kb
192  * @return      callee's pid
193  */
194 int app_request_to_launchpad(int cmd, const char *appid, bundle *kb)
195 {
196         return app_request_to_launchpad_for_uid(cmd, appid, kb, getuid());
197 }
198
199 int app_request_to_launchpad_for_uid(int cmd, const char *appid, bundle *kb, uid_t uid)
200 {
201         int must_free = 0;
202         int ret = 0;
203         bundle *b;
204         char buf[MAX_PID_STR_BUFSZ];
205
206         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
207         _W("request cmd(%d) : appid(%s), target_uid(%d)", cmd, appid, uid);
208         if (kb == NULL) {
209                 kb = bundle_create();
210                 must_free = 1;
211         } else {
212                 __clear_internal_key(kb);
213         }
214
215         bundle_del(kb, AUL_K_APPID);
216         bundle_add(kb, AUL_K_APPID, appid);
217         __set_stime(kb);
218         snprintf(buf, sizeof(buf), "%d", uid);
219         bundle_del(kb, AUL_K_TARGET_UID);
220         bundle_add(kb, AUL_K_TARGET_UID, buf);
221
222         switch (cmd) {
223         case APP_PAUSE:
224         case APP_PAUSE_BY_PID:
225                 ret = app_send_cmd_with_queue_noreply_for_uid(AUL_UTIL_PID,
226                                 uid, cmd, kb);
227                 break;
228         case APP_SEND_LAUNCH_REQUEST:
229                 ret = __send_cmd_async_for_uid_opt(AUL_UTIL_PID,
230                                 uid, cmd, kb, AUL_SOCK_QUEUE);
231                 break;
232         default:
233                 ret = app_send_cmd_with_queue_for_uid(AUL_UTIL_PID, uid, cmd,
234                                 kb);
235                 break;
236         }
237
238         _W("request cmd(%d) result : %d", cmd, ret);
239         if (ret == AUL_R_LOCAL) {
240                 _E("app_request_to_launchpad : Same Process Send Local");
241
242                 switch (cmd) {
243                 case APP_START:
244                 case APP_START_RES:
245                 case APP_START_ASYNC:
246                 case WIDGET_UPDATE:
247                 case APP_START_RES_ASYNC:
248                 case APP_SEND_LAUNCH_REQUEST:
249                         b = bundle_dup(kb);
250                         ret = aul_launch_local(b);
251                         break;
252                 case APP_OPEN:
253                 case APP_RESUME:
254                 case APP_RESUME_BY_PID:
255                 case APP_RESUME_BY_PID_ASYNC:
256                         ret = aul_resume_local();
257                         break;
258                 default:
259                         _E("no support packet");
260                 }
261
262         }
263
264         /* cleanup */
265         if (must_free)
266                 bundle_free(kb);
267
268         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
269
270         return ret;
271 }
272
273 static int __get_preinit_fd(void)
274 {
275         int fd = -1;
276         const char *listen_fd;
277
278         listen_fd = getenv("AUL_LISTEN_FD");
279         if (listen_fd) {
280                 if (isdigit(*listen_fd))
281                         fd = atoi(listen_fd);
282                 unsetenv("AUL_LISTEN_FD");
283         }
284
285         return fd;
286 }
287
288 int aul_initialize()
289 {
290         int flag;
291
292         if (aul_initialized)
293                 return AUL_R_ECANCELED;
294
295         aul_fd = __get_preinit_fd();
296         if (aul_fd > 0 && aul_fd < sysconf(_SC_OPEN_MAX)) {
297                 flag = fcntl(aul_fd, F_GETFD);
298                 flag |= FD_CLOEXEC;
299                 (void)fcntl(aul_fd, F_SETFD, flag);
300         } else {
301                 _W("Failed to get preinit fd");
302                 aul_fd = aul_sock_create_server(getpid(), getuid());
303                 if (aul_fd < 0) {
304                         _E("aul_init create sock failed");
305                         return AUL_R_ECOMM;
306                 }
307         }
308         aul_notify_start();
309
310         aul_initialized = 1;
311
312         return aul_fd;
313 }
314
315 API void aul_finalize()
316 {
317         aul_launch_fini();
318
319         if (aul_initialized) {
320                 aul_sock_destroy_server(aul_fd);
321                 aul_fd = -1;
322         }
323
324         return;
325 }
326
327 API int aul_request_data_control_socket_pair(bundle *kb, int *fd)
328 {
329         bundle *b = kb;
330         int ret;
331         int clifd;
332         int fds[2] = { 0, };
333
334         if (!fd)
335                 return AUL_R_EINVAL;
336
337         if (b) {
338                 __clear_internal_key(b);
339         } else {
340                 b = bundle_create();
341                 if (!b)
342                         return AUL_R_ERROR;
343         }
344
345         clifd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_GET_DC_SOCKET_PAIR, b, AUL_SOCK_ASYNC);
346         if (kb == NULL)
347                 bundle_free(b);
348
349         if (clifd > 0) {
350                 ret = aul_sock_recv_result_with_fd(clifd);
351                 if (ret < 0) {
352                         close(clifd);
353                         if (ret == -EILLEGALACCESS) {
354                                 _E("Illegal access in datacontrol socket pair request");
355                                 return AUL_R_EILLACC;
356                         }
357                         return ret;
358                 }
359
360                 ret = aul_sock_recv_reply_sock_fd(clifd, &fds, 1);
361                 if (ret == 0)
362                         fd[0] = fds[0];
363         } else {
364                 return AUL_R_ERROR;
365         }
366
367         return ret;
368 }
369
370 API int aul_request_message_port_socket_pair(int *fd)
371 {
372         int ret;
373         int fds[2] = {0,};
374
375         if (!fd)
376                 return AUL_R_EINVAL;
377
378         ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
379                         APP_GET_MP_SOCKET_PAIR, NULL, 0, AUL_SOCK_ASYNC);
380         if (ret > 0) {
381                 ret = aul_sock_recv_reply_sock_fd(ret, &fds, 2);
382                 if (ret == 0) {
383                         fd[0] = fds[0];
384                         fd[1] = fds[1];
385                 }
386         }
387
388         return ret;
389 }
390
391 API int aul_launch_app(const char *appid, bundle *kb)
392 {
393         return aul_launch_app_for_uid(appid, kb, getuid());
394 }
395
396 API int aul_launch_app_for_uid(const char *appid, bundle *kb, uid_t uid)
397 {
398         int ret;
399
400         if (appid == NULL)
401                 return AUL_R_EINVAL;
402
403         ret = app_request_to_launchpad_for_uid(APP_START, appid, kb, uid);
404         return ret;
405 }
406
407 API int aul_open_app(const char *appid)
408 {
409         return aul_open_app_for_uid(appid, getuid());
410 }
411
412 API int aul_open_app_for_uid(const char *appid, uid_t uid)
413 {
414         int ret;
415
416         if (appid == NULL)
417                 return AUL_R_EINVAL;
418
419         ret = app_request_to_launchpad_for_uid(APP_OPEN, appid, NULL, uid);
420         return ret;
421 }
422
423 API int aul_resume_app(const char *appid)
424 {
425         return aul_resume_app_for_uid(appid, getuid());
426 }
427
428 API int aul_resume_app_for_uid(const char *appid, uid_t uid)
429 {
430         int ret;
431
432         if (appid == NULL)
433                 return AUL_R_EINVAL;
434
435         ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, NULL, uid);
436         return ret;
437 }
438
439 API int aul_resume_pid(int pid)
440 {
441         return aul_resume_pid_for_uid(pid, getuid());
442 }
443
444 API int aul_resume_pid_for_uid(int pid, uid_t uid)
445 {
446         char pid_str[MAX_PID_STR_BUFSZ];
447         int ret;
448
449         if (pid <= 0)
450                 return AUL_R_EINVAL;
451
452         snprintf(pid_str, sizeof(pid_str), "%d", pid);
453         ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID,
454                         pid_str, NULL, uid);
455         return ret;
456 }
457
458 API int aul_terminate_pid(int pid)
459 {
460         return aul_terminate_pid_for_uid(pid, getuid());
461 }
462
463 API int aul_terminate_pid_for_uid(int pid, uid_t uid)
464 {
465         char pid_str[MAX_PID_STR_BUFSZ];
466         int ret;
467
468         if (pid <= 0)
469                 return AUL_R_EINVAL;
470
471         snprintf(pid_str, sizeof(pid_str), "%d", pid);
472         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID,
473                         pid_str, NULL, uid);
474         if (ret == pid)
475                 ret = AUL_R_OK;
476
477         return ret;
478 }
479
480 API int aul_terminate_bgapp_pid(int pid)
481 {
482         char pid_str[MAX_PID_STR_BUFSZ];
483         int ret;
484
485         if (pid <= 0)
486                 return AUL_R_EINVAL;
487
488         snprintf(pid_str, sizeof(pid_str), "%d", pid);
489         ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pid_str, NULL);
490         if (ret == pid)
491                 ret = AUL_R_OK;
492
493         return ret;
494 }
495
496 API int aul_terminate_pid_without_restart(int pid)
497 {
498         char pid_str[MAX_PID_STR_BUFSZ];
499         int ret;
500
501         if (pid <= 0)
502                 return AUL_R_EINVAL;
503
504         snprintf(pid_str, sizeof(pid_str), "%d", pid);
505         ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART,
506                         pid_str, NULL);
507         return ret;
508 }
509
510 API int aul_terminate_pid_sync_without_restart(int pid)
511 {
512         return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
513 }
514
515 API int aul_terminate_pid_sync_without_restart_for_uid(int pid, uid_t uid)
516 {
517         char pid_str[MAX_PID_STR_BUFSZ];
518         int ret;
519
520         if (pid <= 0)
521                 return AUL_R_EINVAL;
522
523         snprintf(pid_str, sizeof(pid_str), "%d", pid);
524         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
525                         pid_str, NULL, uid);
526         return ret;
527 }
528
529 API int aul_terminate_pid_async(int pid)
530 {
531         return aul_terminate_pid_async_for_uid(pid, getuid());
532 }
533
534 API int aul_terminate_pid_async_for_uid(int pid, uid_t uid)
535 {
536         char pid_str[MAX_PID_STR_BUFSZ];
537         int ret;
538
539         if (pid <= 0)
540                 return AUL_R_EINVAL;
541
542         snprintf(pid_str, sizeof(pid_str), "%d", pid);
543         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_ASYNC, pid_str,
544                         NULL, uid);
545         return ret;
546 }
547
548 API int aul_kill_pid(int pid)
549 {
550         char pid_str[MAX_PID_STR_BUFSZ];
551         int ret;
552
553         if (pid <= 0)
554                 return AUL_R_EINVAL;
555
556         snprintf(pid_str, sizeof(pid_str), "%d", pid);
557         ret = app_request_to_launchpad(APP_KILL_BY_PID, pid_str, NULL);
558         return ret;
559 }
560
561 API void aul_set_preinit_window(void *evas_object)
562 {
563         __window_object = evas_object;
564 }
565
566 API void* aul_get_preinit_window(const char *win_name)
567 {
568         return __window_object;
569 }
570
571 API void aul_set_preinit_background(void *evas_object)
572 {
573         __bg_object = evas_object;
574 }
575
576 API void* aul_get_preinit_background(void)
577 {
578         return __bg_object;
579 }
580
581 API void aul_set_preinit_conformant(void *evas_object)
582 {
583         __conformant_object = evas_object;
584 }
585
586 API void* aul_get_preinit_conformant(void)
587 {
588         return __conformant_object;
589 }
590
591 API int aul_pause_app(const char *appid)
592 {
593         return aul_pause_app_for_uid(appid, getuid());
594 }
595
596 API int aul_pause_app_for_uid(const char *appid, uid_t uid)
597 {
598         int ret;
599
600         if (appid == NULL)
601                 return AUL_R_EINVAL;
602
603         ret = app_request_to_launchpad_for_uid(APP_PAUSE, appid, NULL, uid);
604         return ret;
605 }
606
607 API int aul_pause_pid(int pid)
608 {
609         return aul_pause_pid_for_uid(pid, getuid());
610 }
611
612 API int aul_pause_pid_for_uid(int pid, uid_t uid)
613 {
614         char pid_str[MAX_PID_STR_BUFSZ];
615         int ret;
616
617         if (pid <= 0)
618                 return AUL_R_EINVAL;
619
620         snprintf(pid_str, sizeof(pid_str), "%d", pid);
621         ret = app_request_to_launchpad_for_uid(APP_PAUSE_BY_PID,
622                         pid_str, NULL, uid);
623         return ret;
624 }
625
626 API int aul_reload_appinfo(void)
627 {
628         char pid_str[MAX_PID_STR_BUFSZ];
629
630         snprintf(pid_str, sizeof(pid_str), "%d", getpid());
631
632         return app_request_to_launchpad(AMD_RELOAD_APPINFO, pid_str, NULL);
633 }
634
635 API int aul_is_tep_mount_dbus_done(const char *tep_string)
636 {
637         GError *err = NULL;
638         GDBusConnection *conn;
639         GDBusMessage *msg = NULL;
640         GDBusMessage *reply = NULL;
641         GVariant *body;
642         int ret = AUL_R_ERROR;
643
644         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
645         if (conn == NULL) {
646                 _E("g_bus_get_sync() is failed. %s", err->message);
647                 g_error_free(err);
648                 return AUL_R_ERROR;
649         }
650
651         msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
652                                         TEP_OBJECT_PATH,
653                                         TEP_INTERFACE_NAME,
654                                         TEP_IS_MOUNTED_METHOD);
655         if (msg == NULL) {
656                 _E("g_dbus_message_new_method_call() is failed. %s",
657                                 err->message);
658                 goto end;
659         }
660         g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
661
662         reply = g_dbus_connection_send_message_with_reply_sync(conn,
663                                         msg,
664                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
665                                         500,
666                                         NULL,
667                                         NULL,
668                                         &err);
669         if (reply == NULL) {
670                 _E("g_dbus_connection_send_message_with_reply_sync() "
671                                         "is failed. %s", err->message);
672                 goto end;
673         }
674
675         body = g_dbus_message_get_body(reply);
676         if (body == NULL) {
677                 _E("g_dbus_message_get_body() is failed.");
678                 goto end;
679         }
680
681         g_variant_get(body, "(i)", &ret);
682
683 end:
684         if (msg)
685                 g_object_unref(msg);
686         if (reply)
687                 g_object_unref(reply);
688         if (conn)
689                 g_object_unref(conn);
690
691         g_clear_error(&err);
692
693         return ret;
694 }
695
696 API int aul_check_tep_mount(const char *tep_path)
697 {
698         if (tep_path) {
699                 int rv = -1;
700                 int cnt = 0;
701                 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
702                         rv = aul_is_tep_mount_dbus_done(tep_path);
703                         if (rv == 1)
704                                 break;
705                         usleep(50 * 1000);
706                         cnt++;
707                 }
708                 /* incase after trying 1 sec, not getting mounted then quit */
709                 if (rv != 1) {
710                         _E("Not able to mount within 1 sec");
711                         return -1;
712                 }
713         }
714         return 0;
715 }
716
717 API int aul_add_loader(const char *loader_path, bundle *kb)
718 {
719         return aul_add_loader_for_uid(loader_path, kb, getuid());
720 }
721
722 API int aul_add_loader_for_uid(const char *loader_path, bundle *kb, uid_t uid)
723 {
724         int ret;
725         bundle *b;
726         bundle_raw *kb_raw = NULL;
727         int len;
728         char buf[MAX_PID_STR_BUFSZ];
729
730         if (loader_path == NULL)
731                 return AUL_R_EINVAL;
732
733         b = bundle_create();
734         if (b == NULL)
735                 return AUL_R_ERROR;
736
737         snprintf(buf, sizeof(buf), "%d", uid);
738         bundle_add_str(b, AUL_K_TARGET_UID, buf);
739         bundle_add_str(b, AUL_K_LOADER_PATH, loader_path);
740
741         if (kb) {
742                 ret = bundle_encode(kb, &kb_raw, &len);
743                 if (ret != BUNDLE_ERROR_NONE) {
744                         bundle_free(b);
745                         return AUL_R_EINVAL;
746                 }
747
748                 bundle_add_str(b, AUL_K_LOADER_EXTRA, (const char *)kb_raw);
749         }
750
751         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_ADD_LOADER, b);
752         bundle_free(b);
753         if (kb_raw)
754                 free(kb_raw);
755
756         return ret;
757 }
758
759 API int aul_remove_loader(int loader_id)
760 {
761         return aul_remove_loader_for_uid(loader_id, getuid());
762 }
763
764 API int aul_remove_loader_for_uid(int loader_id, uid_t uid)
765 {
766         char buf[MAX_PID_STR_BUFSZ];
767         int ret;
768         bundle *b;
769
770         if (loader_id <= 0)
771                 return AUL_R_EINVAL;
772
773         b = bundle_create();
774         if (b == NULL) {
775                 _E("out of memory");
776                 return AUL_R_ERROR;
777         }
778
779         snprintf(buf, sizeof(buf), "%d", loader_id);
780         bundle_add_str(b, AUL_K_LOADER_ID, buf);
781         snprintf(buf, sizeof(buf), "%d", uid);
782         bundle_add_str(b, AUL_K_TARGET_UID, buf);
783
784         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_REMOVE_LOADER, b);
785         bundle_free(b);
786
787         return ret;
788 }
789
790 API int aul_app_register_pid(const char *appid, int pid)
791 {
792         char pid_str[MAX_PID_STR_BUFSZ];
793         int ret;
794         bundle *b;
795
796         if (!appid || pid <= 0)
797                 return AUL_R_EINVAL;
798
799         b = bundle_create();
800         if (b == NULL) {
801                 _E("out of memory");
802                 return AUL_R_ERROR;
803         }
804
805         bundle_add_str(b, AUL_K_APPID, appid);
806         snprintf(pid_str, sizeof(pid_str), "%d", pid);
807         bundle_add_str(b, AUL_K_PID, pid_str);
808
809         ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b);
810         bundle_free(b);
811
812         return ret;
813 }
814
815 API int aul_launch_app_async(const char *appid, bundle *kb)
816 {
817         return aul_launch_app_async_for_uid(appid, kb, getuid());
818 }
819
820 API int aul_launch_app_async_for_uid(const char *appid, bundle *kb, uid_t uid)
821 {
822         int ret;
823
824         if (appid == NULL)
825                 return AUL_R_EINVAL;
826
827         ret = app_request_to_launchpad_for_uid(APP_START_ASYNC, appid, kb, uid);
828         return ret;
829 }
830
831 API int aul_prepare_candidate_process(void)
832 {
833         unsigned char dummy[1] = { 0 };
834
835         return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
836                         APP_PREPARE_CANDIDATE_PROCESS, dummy, 0, AUL_SOCK_NONE);
837 }
838
839 API int aul_terminate_pid_sync(int pid)
840 {
841         return aul_terminate_pid_sync_for_uid(pid, getuid());
842 }
843
844 API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid)
845 {
846         char pid_str[MAX_PID_STR_BUFSZ];
847         int ret;
848
849         if (pid <= 0)
850                 return AUL_R_EINVAL;
851
852         snprintf(pid_str, sizeof(pid_str), "%d", pid);
853         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC, pid_str,
854                         NULL, uid);
855         return ret;
856 }
857
858 API int aul_resume_pid_async(int pid)
859 {
860         return aul_resume_pid_async_for_uid(pid, getuid());
861 }
862
863 API int aul_resume_pid_async_for_uid(int pid, uid_t uid)
864 {
865         char pid_str[MAX_PID_STR_BUFSZ];
866         int ret;
867
868         if (pid <= 0)
869                 return AUL_R_EINVAL;
870
871         snprintf(pid_str, sizeof(pid_str), "%d", pid);
872         ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID_ASYNC,
873                         pid_str, NULL, uid);
874         return ret;
875 }
876
877 API int aul_resume_app_by_instance_id(const char *appid,
878                 const char *instance_id)
879 {
880         return aul_resume_app_by_instance_id_for_uid(appid,
881                         instance_id, getuid());
882 }
883
884 API int aul_resume_app_by_instance_id_for_uid(const char *appid,
885                 const char *instance_id, uid_t uid)
886 {
887         int ret;
888         bundle *b;
889
890         if (appid == NULL || instance_id == NULL) {
891                 _E("Invalid parameter");
892                 return AUL_R_EINVAL;
893         }
894
895         b = bundle_create();
896         if (b == NULL) {
897                 _E("Out of memory");
898                 return AUL_R_EINVAL;
899         }
900
901         ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
902         if (ret != BUNDLE_ERROR_NONE) {
903                 _E("Failed to add instance id(%s)", instance_id);
904                 bundle_free(b);
905                 return AUL_R_ERROR;
906         }
907
908         ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, b, uid);
909         bundle_free(b);
910
911         return ret;
912 }