Add a new command
[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 int app_request_local(int cmd, bundle *kb)
191 {
192         bundle *b;
193
194         _E("app_request_to_launchpad : Same Process Send Local");
195
196         switch (cmd) {
197         case APP_START:
198         case APP_START_RES:
199         case APP_START_ASYNC:
200         case WIDGET_UPDATE:
201         case APP_START_RES_ASYNC:
202         case APP_SEND_LAUNCH_REQUEST:
203                 b = bundle_dup(kb);
204                 return aul_launch_local(b);
205         case APP_OPEN:
206         case APP_RESUME:
207         case APP_RESUME_BY_PID:
208         case APP_RESUME_BY_PID_ASYNC:
209                 return aul_resume_local();
210         default:
211                 _E("no support packet");
212                 return AUL_R_LOCAL;
213         }
214 }
215
216 /**
217  * @brief       start caller with kb
218  * @return      callee's pid
219  */
220 int app_request_to_launchpad(int cmd, const char *appid, bundle *kb)
221 {
222         return app_request_to_launchpad_for_uid(cmd, appid, kb, getuid());
223 }
224
225 int app_request_to_launchpad_for_uid(int cmd, const char *appid, bundle *kb, uid_t uid)
226 {
227         int must_free = 0;
228         int ret = 0;
229         char buf[MAX_PID_STR_BUFSZ];
230
231         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "AUL:REQ_TO_PAD");
232         _W("request cmd(%d) : appid(%s), target_uid(%d)", cmd, appid, uid);
233         if (kb == NULL) {
234                 kb = bundle_create();
235                 must_free = 1;
236         } else {
237                 __clear_internal_key(kb);
238         }
239
240         bundle_del(kb, AUL_K_APPID);
241         bundle_add(kb, AUL_K_APPID, appid);
242         __set_stime(kb);
243         snprintf(buf, sizeof(buf), "%d", uid);
244         bundle_del(kb, AUL_K_TARGET_UID);
245         bundle_add(kb, AUL_K_TARGET_UID, buf);
246
247         switch (cmd) {
248         case APP_PAUSE:
249         case APP_PAUSE_BY_PID:
250                 ret = app_send_cmd_with_queue_noreply_for_uid(AUL_UTIL_PID,
251                                 uid, cmd, kb);
252                 break;
253         case APP_SEND_LAUNCH_REQUEST:
254         case APP_SEND_LAUNCH_REQUEST_SYNC:
255                 ret = __send_cmd_async_for_uid_opt(AUL_UTIL_PID,
256                                 uid, cmd, kb, AUL_SOCK_QUEUE);
257                 break;
258         default:
259                 ret = app_send_cmd_with_queue_for_uid(AUL_UTIL_PID, uid, cmd,
260                                 kb);
261                 break;
262         }
263
264         _W("request cmd(%d) result : %d", cmd, ret);
265         if (ret == AUL_R_LOCAL)
266                 ret = app_request_local(cmd, kb);
267
268         /* cleanup */
269         if (must_free)
270                 bundle_free(kb);
271
272         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
273
274         return ret;
275 }
276
277 static int __get_preinit_fd(void)
278 {
279         int fd = -1;
280         const char *listen_fd;
281
282         listen_fd = getenv("AUL_LISTEN_FD");
283         if (listen_fd) {
284                 if (isdigit(*listen_fd))
285                         fd = atoi(listen_fd);
286                 unsetenv("AUL_LISTEN_FD");
287         }
288
289         return fd;
290 }
291
292 int aul_initialize()
293 {
294         int flag;
295
296         if (aul_initialized)
297                 return AUL_R_ECANCELED;
298
299         aul_fd = __get_preinit_fd();
300         if (aul_fd > 0 && aul_fd < sysconf(_SC_OPEN_MAX)) {
301                 flag = fcntl(aul_fd, F_GETFD);
302                 flag |= FD_CLOEXEC;
303                 (void)fcntl(aul_fd, F_SETFD, flag);
304         } else {
305                 _W("Failed to get preinit fd");
306                 aul_fd = aul_sock_create_server(getpid(), getuid());
307                 if (aul_fd < 0) {
308                         _E("aul_init create sock failed");
309                         return AUL_R_ECOMM;
310                 }
311         }
312         aul_notify_start();
313
314         aul_initialized = 1;
315
316         return aul_fd;
317 }
318
319 API void aul_finalize()
320 {
321         aul_launch_fini();
322
323         if (aul_initialized) {
324                 aul_sock_destroy_server(aul_fd);
325                 aul_fd = -1;
326         }
327
328         return;
329 }
330
331 API int aul_request_data_control_socket_pair(bundle *kb, int *fd)
332 {
333         bundle *b = kb;
334         int ret;
335         int clifd;
336         int fds[2] = { 0, };
337
338         if (!fd)
339                 return AUL_R_EINVAL;
340
341         if (b) {
342                 __clear_internal_key(b);
343         } else {
344                 b = bundle_create();
345                 if (!b)
346                         return AUL_R_ERROR;
347         }
348
349         clifd = aul_sock_send_bundle(AUL_UTIL_PID, getuid(), APP_GET_DC_SOCKET_PAIR, b, AUL_SOCK_ASYNC);
350         if (kb == NULL)
351                 bundle_free(b);
352
353         if (clifd > 0) {
354                 ret = aul_sock_recv_result_with_fd(clifd);
355                 if (ret < 0) {
356                         close(clifd);
357                         if (ret == -EILLEGALACCESS) {
358                                 _E("Illegal access in datacontrol socket pair request");
359                                 return AUL_R_EILLACC;
360                         }
361                         return ret;
362                 }
363
364                 ret = aul_sock_recv_reply_sock_fd(clifd, &fds, 1);
365                 if (ret == 0)
366                         fd[0] = fds[0];
367         } else {
368                 return AUL_R_ERROR;
369         }
370
371         return ret;
372 }
373
374 API int aul_request_message_port_socket_pair(int *fd)
375 {
376         int ret;
377         int fds[2] = {0,};
378
379         if (!fd)
380                 return AUL_R_EINVAL;
381
382         ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
383                         APP_GET_MP_SOCKET_PAIR, NULL, 0, AUL_SOCK_ASYNC);
384         if (ret > 0) {
385                 ret = aul_sock_recv_reply_sock_fd(ret, &fds, 2);
386                 if (ret == 0) {
387                         fd[0] = fds[0];
388                         fd[1] = fds[1];
389                 }
390         }
391
392         return ret;
393 }
394
395 API int aul_launch_app(const char *appid, bundle *kb)
396 {
397         return aul_launch_app_for_uid(appid, kb, getuid());
398 }
399
400 API int aul_launch_app_for_uid(const char *appid, bundle *kb, uid_t uid)
401 {
402         int ret;
403
404         if (appid == NULL)
405                 return AUL_R_EINVAL;
406
407         ret = app_request_to_launchpad_for_uid(APP_START, appid, kb, uid);
408         return ret;
409 }
410
411 API int aul_open_app(const char *appid)
412 {
413         return aul_open_app_for_uid(appid, getuid());
414 }
415
416 API int aul_open_app_for_uid(const char *appid, uid_t uid)
417 {
418         int ret;
419
420         if (appid == NULL)
421                 return AUL_R_EINVAL;
422
423         ret = app_request_to_launchpad_for_uid(APP_OPEN, appid, NULL, uid);
424         return ret;
425 }
426
427 API int aul_resume_app(const char *appid)
428 {
429         return aul_resume_app_for_uid(appid, getuid());
430 }
431
432 API int aul_resume_app_for_uid(const char *appid, uid_t uid)
433 {
434         int ret;
435
436         if (appid == NULL)
437                 return AUL_R_EINVAL;
438
439         ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, NULL, uid);
440         return ret;
441 }
442
443 API int aul_resume_pid(int pid)
444 {
445         return aul_resume_pid_for_uid(pid, getuid());
446 }
447
448 API int aul_resume_pid_for_uid(int pid, uid_t uid)
449 {
450         char pid_str[MAX_PID_STR_BUFSZ];
451         int ret;
452
453         if (pid <= 0)
454                 return AUL_R_EINVAL;
455
456         snprintf(pid_str, sizeof(pid_str), "%d", pid);
457         ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID,
458                         pid_str, NULL, uid);
459         return ret;
460 }
461
462 API int aul_terminate_pid(int pid)
463 {
464         return aul_terminate_pid_for_uid(pid, getuid());
465 }
466
467 API int aul_terminate_pid_for_uid(int pid, uid_t uid)
468 {
469         char pid_str[MAX_PID_STR_BUFSZ];
470         int ret;
471
472         if (pid <= 0)
473                 return AUL_R_EINVAL;
474
475         snprintf(pid_str, sizeof(pid_str), "%d", pid);
476         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID,
477                         pid_str, NULL, uid);
478         if (ret == pid)
479                 ret = AUL_R_OK;
480
481         return ret;
482 }
483
484 API int aul_terminate_bgapp_pid(int pid)
485 {
486         char pid_str[MAX_PID_STR_BUFSZ];
487         int ret;
488
489         if (pid <= 0)
490                 return AUL_R_EINVAL;
491
492         snprintf(pid_str, sizeof(pid_str), "%d", pid);
493         ret = app_request_to_launchpad(APP_TERM_BGAPP_BY_PID, pid_str, NULL);
494         if (ret == pid)
495                 ret = AUL_R_OK;
496
497         return ret;
498 }
499
500 API int aul_terminate_pid_without_restart(int pid)
501 {
502         char pid_str[MAX_PID_STR_BUFSZ];
503         int ret;
504
505         if (pid <= 0)
506                 return AUL_R_EINVAL;
507
508         snprintf(pid_str, sizeof(pid_str), "%d", pid);
509         ret = app_request_to_launchpad(APP_TERM_BY_PID_WITHOUT_RESTART,
510                         pid_str, NULL);
511         return ret;
512 }
513
514 API int aul_terminate_pid_sync_without_restart(int pid)
515 {
516         return aul_terminate_pid_sync_without_restart_for_uid(pid, getuid());
517 }
518
519 API int aul_terminate_pid_sync_without_restart_for_uid(int pid, uid_t uid)
520 {
521         char pid_str[MAX_PID_STR_BUFSZ];
522         int ret;
523
524         if (pid <= 0)
525                 return AUL_R_EINVAL;
526
527         snprintf(pid_str, sizeof(pid_str), "%d", pid);
528         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC_WITHOUT_RESTART,
529                         pid_str, NULL, uid);
530         return ret;
531 }
532
533 API int aul_terminate_pid_async(int pid)
534 {
535         return aul_terminate_pid_async_for_uid(pid, getuid());
536 }
537
538 API int aul_terminate_pid_async_for_uid(int pid, uid_t uid)
539 {
540         char pid_str[MAX_PID_STR_BUFSZ];
541         int ret;
542
543         if (pid <= 0)
544                 return AUL_R_EINVAL;
545
546         snprintf(pid_str, sizeof(pid_str), "%d", pid);
547         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_ASYNC, pid_str,
548                         NULL, uid);
549         return ret;
550 }
551
552 API int aul_kill_pid(int pid)
553 {
554         char pid_str[MAX_PID_STR_BUFSZ];
555         int ret;
556
557         if (pid <= 0)
558                 return AUL_R_EINVAL;
559
560         snprintf(pid_str, sizeof(pid_str), "%d", pid);
561         ret = app_request_to_launchpad(APP_KILL_BY_PID, pid_str, NULL);
562         return ret;
563 }
564
565 API void aul_set_preinit_window(void *evas_object)
566 {
567         __window_object = evas_object;
568 }
569
570 API void* aul_get_preinit_window(const char *win_name)
571 {
572         return __window_object;
573 }
574
575 API void aul_set_preinit_background(void *evas_object)
576 {
577         __bg_object = evas_object;
578 }
579
580 API void* aul_get_preinit_background(void)
581 {
582         return __bg_object;
583 }
584
585 API void aul_set_preinit_conformant(void *evas_object)
586 {
587         __conformant_object = evas_object;
588 }
589
590 API void* aul_get_preinit_conformant(void)
591 {
592         return __conformant_object;
593 }
594
595 API int aul_pause_app(const char *appid)
596 {
597         return aul_pause_app_for_uid(appid, getuid());
598 }
599
600 API int aul_pause_app_for_uid(const char *appid, uid_t uid)
601 {
602         int ret;
603
604         if (appid == NULL)
605                 return AUL_R_EINVAL;
606
607         ret = app_request_to_launchpad_for_uid(APP_PAUSE, appid, NULL, uid);
608         return ret;
609 }
610
611 API int aul_pause_pid(int pid)
612 {
613         return aul_pause_pid_for_uid(pid, getuid());
614 }
615
616 API int aul_pause_pid_for_uid(int pid, uid_t uid)
617 {
618         char pid_str[MAX_PID_STR_BUFSZ];
619         int ret;
620
621         if (pid <= 0)
622                 return AUL_R_EINVAL;
623
624         snprintf(pid_str, sizeof(pid_str), "%d", pid);
625         ret = app_request_to_launchpad_for_uid(APP_PAUSE_BY_PID,
626                         pid_str, NULL, uid);
627         return ret;
628 }
629
630 API int aul_reload_appinfo(void)
631 {
632         char pid_str[MAX_PID_STR_BUFSZ];
633
634         snprintf(pid_str, sizeof(pid_str), "%d", getpid());
635
636         return app_request_to_launchpad(AMD_RELOAD_APPINFO, pid_str, NULL);
637 }
638
639 API int aul_is_tep_mount_dbus_done(const char *tep_string)
640 {
641         GError *err = NULL;
642         GDBusConnection *conn;
643         GDBusMessage *msg = NULL;
644         GDBusMessage *reply = NULL;
645         GVariant *body;
646         int ret = AUL_R_ERROR;
647
648         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
649         if (conn == NULL) {
650                 _E("g_bus_get_sync() is failed. %s", err->message);
651                 g_error_free(err);
652                 return AUL_R_ERROR;
653         }
654
655         msg = g_dbus_message_new_method_call(TEP_BUS_NAME,
656                                         TEP_OBJECT_PATH,
657                                         TEP_INTERFACE_NAME,
658                                         TEP_IS_MOUNTED_METHOD);
659         if (msg == NULL) {
660                 _E("g_dbus_message_new_method_call() is failed. %s",
661                                 err->message);
662                 goto end;
663         }
664         g_dbus_message_set_body(msg, g_variant_new("(s)", tep_string));
665
666         reply = g_dbus_connection_send_message_with_reply_sync(conn,
667                                         msg,
668                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
669                                         500,
670                                         NULL,
671                                         NULL,
672                                         &err);
673         if (reply == NULL) {
674                 _E("g_dbus_connection_send_message_with_reply_sync() "
675                                         "is failed. %s", err->message);
676                 goto end;
677         }
678
679         body = g_dbus_message_get_body(reply);
680         if (body == NULL) {
681                 _E("g_dbus_message_get_body() is failed.");
682                 goto end;
683         }
684
685         g_variant_get(body, "(i)", &ret);
686
687 end:
688         if (msg)
689                 g_object_unref(msg);
690         if (reply)
691                 g_object_unref(reply);
692         if (conn)
693                 g_object_unref(conn);
694
695         g_clear_error(&err);
696
697         return ret;
698 }
699
700 API int aul_check_tep_mount(const char *tep_path)
701 {
702         if (tep_path) {
703                 int rv = -1;
704                 int cnt = 0;
705                 while (cnt < TEP_ISMOUNT_MAX_RETRY_CNT) {
706                         rv = aul_is_tep_mount_dbus_done(tep_path);
707                         if (rv == 1)
708                                 break;
709                         usleep(50 * 1000);
710                         cnt++;
711                 }
712                 /* incase after trying 1 sec, not getting mounted then quit */
713                 if (rv != 1) {
714                         _E("Not able to mount within 1 sec");
715                         return -1;
716                 }
717         }
718         return 0;
719 }
720
721 API int aul_add_loader(const char *loader_path, bundle *kb)
722 {
723         return aul_add_loader_for_uid(loader_path, kb, getuid());
724 }
725
726 API int aul_add_loader_for_uid(const char *loader_path, bundle *kb, uid_t uid)
727 {
728         int ret;
729         bundle *b;
730         bundle_raw *kb_raw = NULL;
731         int len;
732         char buf[MAX_PID_STR_BUFSZ];
733
734         if (loader_path == NULL)
735                 return AUL_R_EINVAL;
736
737         b = bundle_create();
738         if (b == NULL)
739                 return AUL_R_ERROR;
740
741         snprintf(buf, sizeof(buf), "%d", uid);
742         bundle_add_str(b, AUL_K_TARGET_UID, buf);
743         bundle_add_str(b, AUL_K_LOADER_PATH, loader_path);
744
745         if (kb) {
746                 ret = bundle_encode(kb, &kb_raw, &len);
747                 if (ret != BUNDLE_ERROR_NONE) {
748                         bundle_free(b);
749                         return AUL_R_EINVAL;
750                 }
751
752                 bundle_add_str(b, AUL_K_LOADER_EXTRA, (const char *)kb_raw);
753         }
754
755         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_ADD_LOADER, b);
756         bundle_free(b);
757         if (kb_raw)
758                 free(kb_raw);
759
760         return ret;
761 }
762
763 API int aul_remove_loader(int loader_id)
764 {
765         return aul_remove_loader_for_uid(loader_id, getuid());
766 }
767
768 API int aul_remove_loader_for_uid(int loader_id, uid_t uid)
769 {
770         char buf[MAX_PID_STR_BUFSZ];
771         int ret;
772         bundle *b;
773
774         if (loader_id <= 0)
775                 return AUL_R_EINVAL;
776
777         b = bundle_create();
778         if (b == NULL) {
779                 _E("out of memory");
780                 return AUL_R_ERROR;
781         }
782
783         snprintf(buf, sizeof(buf), "%d", loader_id);
784         bundle_add_str(b, AUL_K_LOADER_ID, buf);
785         snprintf(buf, sizeof(buf), "%d", uid);
786         bundle_add_str(b, AUL_K_TARGET_UID, buf);
787
788         ret = app_send_cmd_for_uid(AUL_UTIL_PID, uid, APP_REMOVE_LOADER, b);
789         bundle_free(b);
790
791         return ret;
792 }
793
794 API int aul_app_register_pid(const char *appid, int pid)
795 {
796         char pid_str[MAX_PID_STR_BUFSZ];
797         int ret;
798         bundle *b;
799
800         if (!appid || pid <= 0)
801                 return AUL_R_EINVAL;
802
803         b = bundle_create();
804         if (b == NULL) {
805                 _E("out of memory");
806                 return AUL_R_ERROR;
807         }
808
809         bundle_add_str(b, AUL_K_APPID, appid);
810         snprintf(pid_str, sizeof(pid_str), "%d", pid);
811         bundle_add_str(b, AUL_K_PID, pid_str);
812
813         ret = app_send_cmd_with_noreply(AUL_UTIL_PID, APP_REGISTER_PID, b);
814         bundle_free(b);
815
816         return ret;
817 }
818
819 API int aul_launch_app_async(const char *appid, bundle *kb)
820 {
821         return aul_launch_app_async_for_uid(appid, kb, getuid());
822 }
823
824 API int aul_launch_app_async_for_uid(const char *appid, bundle *kb, uid_t uid)
825 {
826         int ret;
827
828         if (appid == NULL)
829                 return AUL_R_EINVAL;
830
831         ret = app_request_to_launchpad_for_uid(APP_START_ASYNC, appid, kb, uid);
832         return ret;
833 }
834
835 API int aul_prepare_candidate_process(void)
836 {
837         unsigned char dummy[1] = { 0 };
838
839         return aul_sock_send_raw(AUL_UTIL_PID, getuid(),
840                         APP_PREPARE_CANDIDATE_PROCESS, dummy, 0, AUL_SOCK_NONE);
841 }
842
843 API int aul_terminate_pid_sync(int pid)
844 {
845         return aul_terminate_pid_sync_for_uid(pid, getuid());
846 }
847
848 API int aul_terminate_pid_sync_for_uid(int pid, uid_t uid)
849 {
850         char pid_str[MAX_PID_STR_BUFSZ];
851         int ret;
852
853         if (pid <= 0)
854                 return AUL_R_EINVAL;
855
856         snprintf(pid_str, sizeof(pid_str), "%d", pid);
857         ret = app_request_to_launchpad_for_uid(APP_TERM_BY_PID_SYNC, pid_str,
858                         NULL, uid);
859         return ret;
860 }
861
862 API int aul_resume_pid_async(int pid)
863 {
864         return aul_resume_pid_async_for_uid(pid, getuid());
865 }
866
867 API int aul_resume_pid_async_for_uid(int pid, uid_t uid)
868 {
869         char pid_str[MAX_PID_STR_BUFSZ];
870         int ret;
871
872         if (pid <= 0)
873                 return AUL_R_EINVAL;
874
875         snprintf(pid_str, sizeof(pid_str), "%d", pid);
876         ret = app_request_to_launchpad_for_uid(APP_RESUME_BY_PID_ASYNC,
877                         pid_str, NULL, uid);
878         return ret;
879 }
880
881 API int aul_resume_app_by_instance_id(const char *appid,
882                 const char *instance_id)
883 {
884         return aul_resume_app_by_instance_id_for_uid(appid,
885                         instance_id, getuid());
886 }
887
888 API int aul_resume_app_by_instance_id_for_uid(const char *appid,
889                 const char *instance_id, uid_t uid)
890 {
891         int ret;
892         bundle *b;
893
894         if (appid == NULL || instance_id == NULL) {
895                 _E("Invalid parameter");
896                 return AUL_R_EINVAL;
897         }
898
899         b = bundle_create();
900         if (b == NULL) {
901                 _E("Out of memory");
902                 return AUL_R_EINVAL;
903         }
904
905         ret = bundle_add(b, AUL_K_INSTANCE_ID, instance_id);
906         if (ret != BUNDLE_ERROR_NONE) {
907                 _E("Failed to add instance id(%s)", instance_id);
908                 bundle_free(b);
909                 return AUL_R_ERROR;
910         }
911
912         ret = app_request_to_launchpad_for_uid(APP_RESUME, appid, b, uid);
913         bundle_free(b);
914
915         return ret;
916 }