2 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <systemd/sd-daemon.h>
22 #include <sys/prctl.h>
23 #include <sys/socket.h>
25 #include <sys/types.h>
28 #include <sys/capability.h>
32 #include <bundle_internal.h>
33 #include <security-manager.h>
35 #include <systemd/sd-daemon.h>
37 #include <linux/limits.h>
41 #include <trust-anchor.h>
44 #include "launcher_info.h"
45 #include "launchpad_common.h"
46 #include "launchpad_config.h"
47 #include "launchpad_dbus.h"
48 #include "launchpad_debug.h"
49 #include "launchpad_inotify.h"
50 #include "launchpad_io_channel.h"
51 #include "launchpad_log.h"
52 #include "launchpad_memory_monitor.h"
53 #include "launchpad_plugin.h"
54 #include "launchpad_proc.h"
55 #include "launchpad_signal.h"
56 #include "launchpad_types.h"
57 #include "loader_info.h"
60 #define AUL_PR_NAME 16
61 #define EXEC_CANDIDATE_EXPIRED 5
62 #define EXEC_CANDIDATE_WAIT 1
63 #define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a))
64 #define CANDIDATE_NONE 0
66 #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock"
67 #define LAUNCHPAD_LOGGER_SOCK ".launchpad-logger-sock"
68 #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader"
69 #define LOADER_INFO_PATH "/usr/share/aul"
70 #define OPT_SHARE_PATH "/opt/share"
71 #define LOADERS_PATH "loaders"
72 #define APP_DEFINED_LOADER_INFO_PATH OPT_SHARE_PATH "/" LOADERS_PATH
73 #define COMMON_LOADER_NAME "common-loader1"
75 #define LAUNCHER_INFO_PATH LOADER_INFO_PATH
76 #define REGULAR_UID_MIN 5000
77 #define PAD_ERR_FAILED -1
78 #define PAD_ERR_REJECTED -2
79 #define PAD_ERR_INVALID_ARGUMENT -3
80 #define PAD_ERR_INVALID_PATH -4
81 #define CPU_CHECKER_TIMEOUT 1000
84 #define LOSE_SCORE_RATE 0.7f
86 enum candidate_process_state_e {
87 CANDIDATE_PROCESS_STATE_RUNNING,
88 CANDIDATE_PROCESS_STATE_PAUSED,
94 int pid; /* for hydra this pid is not the pid of hydra itself */
95 /* but pid of non-hydra candidate, which was forked from hydra */
106 int detection_method;
108 unsigned long long cpu_total_time;
109 unsigned long long cpu_idle_time;
117 int activation_method;
118 int deactivation_method;
124 io_channel_h client_channel;
125 io_channel_h channel;
126 io_channel_h hydra_channel;
130 } candidate_process_context_t;
142 candidate_process_context_t *running_cpc;
145 struct app_launch_arg {
147 const char *app_path;
148 appinfo_t *menu_info;
162 static int __sys_hwacc;
163 static GList *loader_info_list;
164 static GList *app_defined_loader_info_list;
165 static int user_slot_offset;
166 static GList *candidate_slot_list;
167 static app_labels_monitor *label_monitor;
168 static GList *launcher_info_list;
169 static GHashTable *__pid_table;
170 static int __memory_status_low;
171 static int __memory_status_normal;
172 static sequencer __sequencer;
173 static int MEMORY_STATUS_LOW;
174 static int MEMORY_STATUS_NORMAL;
175 static int MAX_CPU_CHECK_COUNT;
177 static io_channel_h __logger_channel;
178 static io_channel_h __label_monitor_channel;
179 static io_channel_h __launchpad_channel;
181 static candidate_process_context_t *__add_slot(int type, int loader_id,
182 int caller_pid, const char *loader_name,
183 const char *loader_path, const char *extra,
184 int detection_method, int activation_method,
185 int deactivation_method, unsigned int ttl, int timeout_val,
186 int threshold_max, int threshold_min, bool on_boot,
187 bool app_exists, bool is_hydra, bool app_check);
188 static int __remove_slot(int type, int loader_id);
189 static int __add_default_slots(void);
190 static gboolean __handle_idle_checker(gpointer data);
191 static int __add_idle_checker(int detection_method, GList *cur);
192 static void __dispose_candidate_process(candidate_process_context_t *cpc);
193 static bool __is_low_memory(void);
194 static void __update_slot_state(candidate_process_context_t *cpc, int method,
196 static void __init_app_defined_loader_monitor(void);
197 static gboolean __launchpad_recovery_cb(gpointer data);
198 static gboolean __logger_recovery_cb(gpointer data);
200 static gboolean __handle_queuing_slots(gpointer data)
202 candidate_process_context_t *cpc;
203 unsigned long long total = 0;
204 unsigned long long idle = 0;
206 if (__sequencer.idle_checker > 0)
207 return G_SOURCE_CONTINUE;
209 if (g_queue_is_empty(__sequencer.queue)) {
210 __sequencer.timer = 0;
211 return G_SOURCE_REMOVE;
214 cpc = (candidate_process_context_t *)g_queue_pop_head(
217 _E("Critical error!");
218 __sequencer.timer = 0;
219 return G_SOURCE_REMOVE;;
222 if (cpc->app_check && !cpc->app_exists) {
223 _W("The application is not installed. Type(%d)", cpc->type);
224 return G_SOURCE_CONTINUE;
228 g_source_remove(cpc->timer);
232 if (cpc->pid != CANDIDATE_NONE) {
233 _W("The slot(%d) is already running. pid(%d)",
234 cpc->type, cpc->pid);
235 return G_SOURCE_CONTINUE;
238 _get_cpu_idle(&total, &idle);
239 cpc->cpu_idle_time = idle;
240 cpc->cpu_total_time = total;
241 cpc->cpu_check_count = 0;
243 __sequencer.idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT,
244 __handle_idle_checker, cpc);
245 __sequencer.running_cpc = cpc;
247 _D("[__SEQUENCER__] Add idle checker. Type(%d)", cpc->type);
249 return G_SOURCE_CONTINUE;
252 static bool __sequencer_slot_is_running(candidate_process_context_t *cpc)
254 if (__sequencer.running_cpc == cpc)
260 static bool __sequencer_slot_exist(candidate_process_context_t *cpc)
264 found = g_queue_find(__sequencer.queue, cpc);
271 static int __sequencer_add_slot(candidate_process_context_t *cpc)
273 if (__sequencer_slot_exist(cpc)) {
274 _W("Already exists");
278 if (__sequencer_slot_is_running(cpc)) {
279 _W("slot(%d) is running", cpc->type);
283 g_queue_push_tail(__sequencer.queue, cpc);
288 static void __sequencer_remove_slot(candidate_process_context_t *cpc)
290 g_queue_remove(__sequencer.queue, cpc);
293 static void __sequencer_run(void)
295 if (__sequencer.timer)
298 __sequencer.timer = g_timeout_add(500, __handle_queuing_slots, NULL);
299 if (!__sequencer.timer)
300 _E("Failed to add sequencer timer");
303 static void __sequencer_stop(void)
305 if (!__sequencer.timer)
308 g_source_remove(__sequencer.timer);
309 __sequencer.timer = 0;
312 static bool __sequencer_queue_is_empty(void)
314 if (g_queue_is_empty(__sequencer.queue))
320 static int __sequencer_init(void)
322 _D("[__SEQUENCER__] Init");
324 __sequencer.queue = g_queue_new();
325 if (!__sequencer.queue) {
333 static void __sequencer_fini(void)
335 _D("[__SEQUENCER__] Finish");
337 if (__sequencer.idle_checker > 0)
338 g_source_remove(__sequencer.idle_checker);
340 if (__sequencer.timer > 0)
341 g_source_remove(__sequencer.timer);
343 g_queue_free(__sequencer.queue);
346 static int __make_loader_id(void)
348 static int id = PAD_LOADER_ID_DYNAMIC_BASE;
353 static candidate_process_context_t *__find_slot_from_static_type(int type)
355 candidate_process_context_t *cpc;
356 GList *iter = candidate_slot_list;
358 if (type == LAUNCHPAD_LOADER_TYPE_DYNAMIC ||
359 type == LAUNCHPAD_LOADER_TYPE_UNSUPPORTED)
363 cpc = (candidate_process_context_t *)iter->data;
364 if (type == cpc->type)
367 iter = g_list_next(iter);
373 static candidate_process_context_t *__find_slot_from_pid(int pid)
375 candidate_process_context_t *cpc;
376 GList *iter = candidate_slot_list;
379 cpc = (candidate_process_context_t *)iter->data;
383 iter = g_list_next(iter);
389 static candidate_process_context_t *__find_hydra_slot_from_pid(int pid)
391 candidate_process_context_t *cpc;
392 GList *iter = candidate_slot_list;
395 cpc = (candidate_process_context_t *)iter->data;
396 if (cpc->is_hydra && pid == cpc->hydra_pid)
399 iter = g_list_next(iter);
405 static candidate_process_context_t *__find_slot_from_caller_pid(int caller_pid)
407 candidate_process_context_t *cpc;
408 GList *iter = candidate_slot_list;
411 cpc = (candidate_process_context_t *)iter->data;
412 if (caller_pid == cpc->caller_pid)
415 iter = g_list_next(iter);
421 static candidate_process_context_t *__find_slot_from_loader_id(int id)
423 candidate_process_context_t *cpc;
424 GList *iter = candidate_slot_list;
427 cpc = (candidate_process_context_t *)iter->data;
428 if (id == cpc->loader_id)
431 iter = g_list_next(iter);
437 static candidate_process_context_t *__find_slot_from_loader_name(const char *loader_name)
439 candidate_process_context_t *cpc;
440 GList *iter = candidate_slot_list;
443 cpc = (candidate_process_context_t *)iter->data;
444 if (strcmp(cpc->loader_name, loader_name) == 0)
447 iter = g_list_next(iter);
453 static candidate_process_context_t *__find_slot(int type, int loader_id)
455 if (type == LAUNCHPAD_LOADER_TYPE_DYNAMIC)
456 return __find_slot_from_loader_id(loader_id);
458 return __find_slot_from_static_type(type);
461 static void __update_slot_score(candidate_process_context_t *slot)
466 slot->score *= LOSE_SCORE_RATE;
467 slot->score += WIN_SCORE;
470 static void __update_slots_pss(void)
472 candidate_process_context_t *cpc;
475 iter = candidate_slot_list;
477 cpc = (candidate_process_context_t *)iter->data;
478 iter = g_list_next(iter);
480 if (cpc->pid == CANDIDATE_NONE)
483 _proc_get_mem_pss(cpc->pid, &cpc->pss);
487 static gint __compare_slot(gconstpointer a, gconstpointer b)
489 candidate_process_context_t *slot_a = (candidate_process_context_t *)a;
490 candidate_process_context_t *slot_b = (candidate_process_context_t *)b;
492 if (slot_a->is_hydra && !slot_b->is_hydra)
494 if (!slot_a->is_hydra && slot_b->is_hydra)
497 if (slot_a->score < slot_b->score)
499 if (slot_a->score > slot_b->score)
502 if (slot_a->pss < slot_b->pss)
504 if (slot_a->pss > slot_b->pss)
510 static candidate_process_context_t *__get_running_slot(bool is_hydra)
512 candidate_process_context_t *cpc;
515 iter = candidate_slot_list;
517 cpc = (candidate_process_context_t *)iter->data;
518 if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE)
521 iter = g_list_next(iter);
527 static void __pause_last_running_slot(bool is_hydra)
529 candidate_process_context_t *cpc = NULL;
532 iter = g_list_last(candidate_slot_list);
534 cpc = (candidate_process_context_t *)iter->data;
535 if (cpc->is_hydra == is_hydra && cpc->pid != CANDIDATE_NONE)
538 iter = g_list_previous(iter);
544 __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, true);
547 static void __resume_all_slots(void)
549 candidate_process_context_t *cpc;
552 iter = candidate_slot_list;
554 cpc = (candidate_process_context_t *)iter->data;
555 __update_slot_state(cpc, METHOD_AVAILABLE_MEMORY, false);
557 iter = g_list_next(iter);
561 static void __kill_process(int pid)
563 char err_str[MAX_LOCAL_BUFSZ] = { 0, };
565 if (kill(pid, SIGKILL) == -1) {
566 _E("send SIGKILL: %s",
567 strerror_r(errno, err_str, sizeof(err_str)));
571 static void __refuse_candidate_process(int server_fd)
575 if (server_fd == -1) {
576 _E("arguments error!");
580 client_fd = accept(server_fd, NULL, NULL);
581 if (client_fd == -1) {
587 _D("refuse connection!");
593 static int __accept_candidate_process(int server_fd, int *out_client_fd,
600 if (server_fd == -1 || out_client_fd == NULL ||
601 out_client_pid == NULL) {
602 _E("arguments error!");
606 client_fd = accept(server_fd, NULL, NULL);
607 if (client_fd == -1) {
612 if (_set_sock_option(client_fd, 1) < 0) {
613 _E("Failed to set sock option");
617 recv_ret = recv(client_fd, &client_pid, sizeof(client_pid),
619 if (recv_ret == -1) {
624 *out_client_fd = client_fd;
625 *out_client_pid = client_pid;
627 return *out_client_fd;
636 static int __listen_addr(struct sockaddr_un *addr)
639 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
645 unlink(addr->sun_path);
647 _D("bind to %s", addr->sun_path);
648 if (bind(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un)) < 0) {
653 _D("listen to %s", addr->sun_path);
654 if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) {
659 SECURE_LOGD("[launchpad] done, listen fd: %d", fd);
669 static int __listen_candidate_process(int type, int loader_id)
671 struct sockaddr_un addr;
673 _D("[launchpad] enter, type: %d", type);
675 memset(&addr, 0x00, sizeof(struct sockaddr_un));
676 addr.sun_family = AF_UNIX;
677 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%u/%s%d-%d",
678 SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME,
681 return __listen_addr(&addr);
684 static int __listen_hydra_process(int type, int loader_id)
686 struct sockaddr_un addr;
688 _D("[launchpad] enter, type: %d", type);
690 memset(&addr, 0x00, sizeof(struct sockaddr_un));
691 addr.sun_family = AF_UNIX;
692 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d",
693 SOCKET_PATH, getuid(), HYDRA_LOADER_SOCKET_NAME,
696 return __listen_addr(&addr);
699 static int __get_loader_id(bundle *kb)
703 val = bundle_get_val(kb, AUL_K_LOADER_ID);
706 _W("Requested loader id: %s", val);
711 static int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt)
713 return _send_pkt_raw(candidate_fd, pkt);
716 static int __real_send(int clifd, int ret)
719 _E("Invalid parameter. clifd(%d)", clifd);
723 if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
724 if (errno == EPIPE) {
725 _E("send failed due to EPIPE.");
729 _E("send fail to client");
736 static void __send_result_to_caller(int clifd, int ret, const char *app_path)
738 _W("send result: %d", ret);
744 _E("launching failed");
745 __real_send(clifd, ret);
749 if (__real_send(clifd, ret) < 0)
753 static int __fork_app_process(int (*child_fn)(void *), void *arg)
761 _E("failed to fork child process");
766 _W("security_manager_prepare_app_candidate ++");
767 ret = security_manager_prepare_app_candidate();
768 _W("security_manager_prepare_app_candidate --");
769 if (ret != SECURITY_MANAGER_SUCCESS) {
770 _E("failed to prepare app candidate process (%d)", ret);
775 _E("failed to exec app process (%d)", errno);
782 static int __exec_loader_process(void *arg)
787 _send_cmd_to_amd(LAUNCHPAD_CHILD_PROCESS);
788 _signal_unblock_sigchld();
790 _setup_stdio(basename(argv[LOADER_ARG_PATH]));
792 if (execv(argv[LOADER_ARG_PATH], argv) < 0) {
793 _send_message_to_logger(argv[LOADER_ARG_PATH],
794 "Failed to prepare candidate process. error(%d:%s)",
795 errno, strerror_r(errno, err_buf, sizeof(err_buf)));
797 _D("Succeeded to prepare candidate_process");
803 static gboolean __handle_deactivate_event(gpointer user_data)
805 candidate_process_context_t *cpc;
807 cpc = (candidate_process_context_t *)user_data;
808 __update_slot_state(cpc, METHOD_TTL, false);
809 _D("Deactivate event: type(%d)", cpc->type);
811 return G_SOURCE_REMOVE;
814 static void __set_live_timer(candidate_process_context_t *cpc)
819 if (cpc->deactivation_method & METHOD_TTL) {
820 if (cpc->live_timer == 0) {
821 cpc->live_timer = g_timeout_add_seconds(cpc->ttl,
822 __handle_deactivate_event, cpc);
827 static int __hydra_send_request(int fd, enum hydra_cmd cmd)
830 int size = sizeof(cmd);
833 while (sent != size) {
834 send_ret = send(fd, (char *)&cmd + sent,
835 size - sent, MSG_NOSIGNAL);
836 if (send_ret == -1) {
837 _E("send error! (%d)", errno);
842 _D("send(%d: ret: %d) : %d / %d",
843 fd, send_ret, sent, size);
849 static int __hydra_send_launch_candidate_request(int fd)
851 SECURE_LOGD("Send launch cmd to hydra, fd: %d", fd);
852 return __hydra_send_request(fd, LAUNCH_CANDIDATE);
855 static int __prepare_candidate_process(int type, int loader_id)
858 char type_str[12] = {0, };
859 char loader_id_str[12] = {0, };
860 char argbuf[LOADER_ARG_LEN];
861 char *argv[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
862 candidate_process_context_t *cpt = __find_slot(type, loader_id);
867 if (cpt->is_hydra && cpt->hydra_pid != HYDRA_NONE)
868 return __hydra_send_launch_candidate_request(cpt->hydra_fd);
870 _D("prepare candidate process / type:%d", type);
871 memset(argbuf, ' ', LOADER_ARG_LEN);
872 argbuf[LOADER_ARG_LEN - 1] = '\0';
873 argv[LOADER_ARG_DUMMY] = argbuf;
875 cpt->last_exec_time = time(NULL);
877 snprintf(loader_id_str, sizeof(loader_id_str), "%d", loader_id);
878 snprintf(type_str, sizeof(type_str), "%d", type);
879 argv[LOADER_ARG_PATH] = cpt->loader_path;
880 argv[LOADER_ARG_TYPE] = type_str;
881 argv[LOADER_ARG_ID] = loader_id_str;
882 argv[LOADER_ARG_HYDRA] = cpt->is_hydra ? "1" : "0";
883 argv[LOADER_ARG_EXTRA] = cpt->loader_extra;
885 pid = __fork_app_process(__exec_loader_process, argv);
887 _E("Failed to fork candidate_process");
892 cpt->hydra_pid = pid;
895 __set_live_timer(cpt);
898 _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)",
899 pid, cpt->loader_id, cpt->loader_name);
900 _memory_monitor_reset_timer();
905 static gboolean __handle_timeout_event(gpointer user_data)
907 candidate_process_context_t *cpc;
909 cpc = (candidate_process_context_t *)user_data;
912 if (cpc->pid != CANDIDATE_NONE) {
913 _W("Candidate(%d) process(%d) is running", cpc->type, cpc->pid);
914 return G_SOURCE_REMOVE;
917 __sequencer_add_slot(cpc);
919 return G_SOURCE_REMOVE;
922 static void __set_timer(candidate_process_context_t *cpc)
924 if (cpc == NULL || cpc->timer > 0)
927 if ((cpc->detection_method & METHOD_TIMEOUT) &&
928 cpc->state == CANDIDATE_PROCESS_STATE_RUNNING) {
929 cpc->timer = g_timeout_add(cpc->timeout_val,
930 __handle_timeout_event, cpc);
934 static void __reset_slot(candidate_process_context_t *cpc)
940 cpc->prepared = false;
941 cpc->pid = CANDIDATE_NONE;
942 cpc->client_channel = NULL;
947 static void __dispose_candidate_process(candidate_process_context_t *cpc)
952 _D("Dispose candidate process %d", cpc->type);
954 _D("kill process %d", cpc->pid);
955 __kill_process(cpc->pid);
957 if (cpc->live_timer > 0)
958 g_source_remove(cpc->live_timer);
959 if (cpc->client_channel)
960 _io_channel_destroy(cpc->client_channel);
962 g_source_remove(cpc->timer);
963 if (cpc->send_fd > 0)
968 static void __dispose_hydra_process(candidate_process_context_t *cpc)
973 __dispose_candidate_process(cpc);
975 _D("Dispose hydra process %d", cpc->type);
976 if (cpc->hydra_pid > 0) {
977 _D("kill process %d", cpc->hydra_pid);
978 __kill_process(cpc->hydra_pid);
979 cpc->hydra_pid = HYDRA_NONE;
982 if (cpc->hydra_fd > 0) {
983 close(cpc->hydra_fd);
988 static int __send_launchpad_loader(candidate_process_context_t *cpc,
989 app_pkt_t *pkt, const char *app_path, int clifd)
994 ret = _delete_sock_path(cpc->pid, getuid());
998 __candidate_process_real_launch(cpc->send_fd, pkt);
999 SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s",
1000 cpc->pid, app_path);
1003 cpc->pid = CANDIDATE_NONE;
1004 __dispose_candidate_process(cpc);
1006 __update_slot_score(cpc);
1011 static int __normal_fork_exec(int argc, char **argv, const char *app_path)
1016 _D("start real fork and exec");
1018 libdir = _get_libdir(app_path);
1020 setenv("LD_LIBRARY_PATH", libdir, 1);
1026 if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */
1027 _send_message_to_logger(argv[LOADER_ARG_PATH],
1028 "Failed to execute a file. error(%d:%s)",
1029 errno, strerror_r(errno, err_buf, sizeof(err_buf)));
1036 static int __create_launcher_argv(int *argc, char ***argv, const char *app_type)
1039 char **launcher_argv;
1040 launcher_info_h launcher_info;
1042 const char *extra_arg;
1047 launcher_info = _launcher_info_find(launcher_info_list, app_type);
1048 if (launcher_info == NULL)
1051 exe = _launcher_info_get_exe(launcher_info);
1053 _E("Failed to get launcher exe");
1057 extra_args = _launcher_info_get_extra_args(launcher_info);
1058 launcher_argc = g_list_length(extra_args) + 1;
1059 launcher_argv = (char **)calloc(launcher_argc, sizeof(char *));
1060 if (launcher_argv == NULL) {
1061 _E("out of memory");
1065 i = LOADER_ARG_PATH;
1066 launcher_argv[i++] = strdup(exe);
1068 iter = g_list_first(extra_args);
1070 extra_arg = (const char *)iter->data;
1072 launcher_argv[i++] = strdup(extra_arg);
1074 iter = g_list_next(iter);
1077 *argc = launcher_argc;
1078 *argv = launcher_argv;
1084 static void __destroy_launcher_argv(int argc, char **argv)
1091 for (i = 0; i < argc; i++)
1096 static int __create_app_argv(int *argc, char ***argv, const char *app_path,
1097 bundle *kb, const char *app_type)
1101 bool attach = false;
1102 struct app_arg debug_arg = {0,};
1103 struct app_arg launcher_arg = {0,};
1104 struct app_arg arg = {0,};
1105 struct app_arg debug_extra_arg = {0,};
1110 ret = _debug_create_argv(&debug_arg.argc, &debug_arg.argv, &attach);
1112 _E("Failed to create debugger argv");
1117 *argc = debug_arg.argc;
1118 *argv = debug_arg.argv;
1122 ret = _debug_create_extra_argv(&debug_extra_arg.argc,
1123 &debug_extra_arg.argv);
1125 _E("Failed to create debugger extra argv");
1126 _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
1130 ret = __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv,
1133 _E("Failed to create launcher argv");
1134 _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
1135 _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
1139 arg.argc = bundle_export_to_argv(kb, &arg.argv);
1140 if (arg.argc <= 0) {
1141 _E("Failed to export bundle");
1142 __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
1143 _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
1144 _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
1147 arg.argv[LOADER_ARG_PATH] = strdup(app_path);
1149 new_argc = debug_arg.argc + launcher_arg.argc + arg.argc +
1150 debug_extra_arg.argc;
1151 if (new_argc == arg.argc) {
1157 new_argv = (char **)calloc(new_argc + 1, sizeof(char *));
1158 if (new_argv == NULL) {
1159 _E("out of memory");
1160 free(arg.argv[LOADER_ARG_PATH]);
1161 bundle_free_exported_argv(arg.argc, &arg.argv);
1162 __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv);
1163 _debug_destroy_argv(debug_extra_arg.argc, debug_extra_arg.argv);
1164 _debug_destroy_argv(debug_arg.argc, debug_arg.argv);
1168 c = LOADER_ARG_PATH;
1169 for (i = 0; i < debug_arg.argc; i++)
1170 new_argv[c++] = debug_arg.argv[i];
1171 for (i = 0; i < launcher_arg.argc; i++)
1172 new_argv[c++] = launcher_arg.argv[i];
1173 for (i = 0; i < arg.argc; i++)
1174 new_argv[c++] = arg.argv[i];
1175 for (i = 0; i < debug_extra_arg.argc; i++)
1176 new_argv[c++] = debug_extra_arg.argv[i];
1184 static void __real_launch(const char *app_path, bundle *kb,
1185 appinfo_t *menu_info)
1192 if (bundle_get_val(kb, AUL_K_DEBUG) != NULL)
1193 putenv("TIZEN_DEBUGGING_PORT=1");
1195 ret = __create_app_argv(&app_argc, &app_argv, app_path,
1196 kb, menu_info->app_type);
1198 _E("Failed to create app argv");
1202 for (i = 0; i < app_argc; i++)
1203 SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
1205 PERF("setup argument done");
1206 __normal_fork_exec(app_argc, app_argv, app_path);
1209 static int __prepare_exec(const char *appid, const char *app_path,
1210 appinfo_t *menu_info, bundle *kb)
1213 char process_name[AUL_PR_NAME];
1216 /* Set new session ID & new process group ID*/
1217 /* In linux, child can set new session ID without check permission */
1218 /* TODO : should be add to check permission in the kernel*/
1221 ret = _launchpad_plugin_prepare_app(appid, kb);
1223 _E("_launchpad_plugin_prepare_app() is failed. error(%d)", ret);
1224 return PAD_ERR_FAILED;
1227 ret = _enable_external_pkg(kb, menu_info->pkgid,
1228 menu_info->global ? GLOBAL_USER : getuid());
1230 return PAD_ERR_FAILED;
1232 if (menu_info->global)
1233 ret = trust_anchor_launch(menu_info->pkgid, GLOBAL_USER);
1235 ret = trust_anchor_launch(menu_info->pkgid, getuid());
1236 if (ret != TRUST_ANCHOR_ERROR_NONE &&
1237 ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
1238 _E("trust_anchor_launch() returns %d", ret);
1239 return PAD_ERR_REJECTED;
1243 _W("security_manager_prepare_app ++");
1244 ret = security_manager_prepare_app(appid);
1245 _W("security_manager_prepare_app --");
1246 if (ret != SECURITY_MANAGER_SUCCESS)
1247 return PAD_ERR_REJECTED;
1249 _send_cmd_to_amd(APP_STARTUP_SIGNAL);
1250 if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE)
1251 _setup_stdio(basename(app_path));
1253 /* SET DUMPABLE - for coredump*/
1254 prctl(PR_SET_DUMPABLE, 1);
1256 /* SET PROCESS NAME*/
1257 if (app_path == NULL)
1258 return PAD_ERR_INVALID_ARGUMENT;
1260 file_name = strrchr(app_path, '/');
1261 if (file_name == NULL)
1262 return PAD_ERR_INVALID_PATH;
1265 if (*file_name == '\0')
1266 return PAD_ERR_INVALID_PATH;
1268 memset(process_name, '\0', AUL_PR_NAME);
1269 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
1270 prctl(PR_SET_NAME, process_name);
1273 _set_env(menu_info, kb);
1275 ret = _wait_tep_mount(kb);
1277 return PAD_ERR_FAILED;
1279 if (bundle_get_type(kb, AUL_K_SDK) == BUNDLE_TYPE_NONE) {
1280 ret = _prepare_app_socket();
1282 return PAD_ERR_FAILED;
1284 ret = _prepare_id_file();
1286 return PAD_ERR_FAILED;
1292 static int __exec_app_process(void *arg)
1294 struct app_launch_arg *launch_arg = arg;
1297 _print_hwc_log("%d|after calling fork(). %s",
1298 getpid(), launch_arg->appid);
1300 _D("lock up test log(no error) : fork done");
1302 if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
1303 _debug_prepare_debugger(launch_arg->kb);
1305 _signal_unblock_sigchld();
1307 _delete_sock_path(getpid(), getuid());
1309 PERF("prepare exec - first done");
1310 ret = __prepare_exec(launch_arg->appid, launch_arg->app_path,
1311 launch_arg->menu_info, launch_arg->kb);
1315 PERF("prepare exec - second done");
1316 __real_launch(launch_arg->app_path, launch_arg->kb,
1317 launch_arg->menu_info);
1319 return PAD_ERR_FAILED;
1322 static int __launch_directly(const char *appid, const char *app_path, int clifd,
1323 bundle *kb, appinfo_t *menu_info,
1324 candidate_process_context_t *cpc)
1326 struct app_launch_arg arg;
1330 arg.app_path = app_path;
1331 arg.menu_info = menu_info;
1334 _print_hwc_log("before calling fork(). %s", appid);
1335 pid = __fork_app_process(__exec_app_process, &arg);
1337 _E("failed to fork app process");
1339 SECURE_LOGD("==> real launch pid : %d %s", pid, app_path);
1344 static int __create_sock_activation(void)
1347 char launchpad_process_pool_sock_path[108];
1350 fds = sd_listen_fds(0);
1351 snprintf(launchpad_process_pool_sock_path,
1352 sizeof(launchpad_process_pool_sock_path), "%s/daemons/%u/%s",
1353 SOCKET_PATH, getuid(), PROCESS_POOL_LAUNCHPAD_SOCK);
1355 for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + fds; ++i) {
1356 if (sd_is_socket_unix(i, SOCK_STREAM, 1,
1357 launchpad_process_pool_sock_path, 0) > 0)
1361 _W("There is no socket stream");
1365 static int __launchpad_pre_init(int argc, char **argv)
1369 /* create launchpad sock */
1370 fd = __create_sock_activation();
1372 fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_SOCK);
1374 _E("server sock error %d", fd);
1382 static bool __handle_loader_client_event(int fd, io_condition_e cond,
1385 candidate_process_context_t *cpc = data;
1390 if (cond & (IO_HUP | IO_NVAL)) {
1391 SECURE_LOGE("Type %d candidate process was "
1392 "(POLLHUP|POLLNVAL), pid: %d",
1393 cpc->type, cpc->pid);
1394 cpc->pid = CANDIDATE_NONE;
1395 __dispose_candidate_process(cpc);
1396 __prepare_candidate_process(cpc->type, cpc->loader_id);
1404 static bool __handle_hydra_client_event(int fd, io_condition_e cond,
1407 candidate_process_context_t *cpc = data;
1412 if (cond & (IO_HUP | IO_NVAL)) {
1413 SECURE_LOGE("Type %d hydra process was "
1414 "(POLLHUP|POLLNVAL), pid: %d",
1415 cpc->type, cpc->hydra_pid);
1416 __dispose_hydra_process(cpc);
1417 __prepare_candidate_process(cpc->type, cpc->loader_id);
1424 static bool __handle_loader_event(int fd, io_condition_e cond, void *data)
1426 candidate_process_context_t *cpc = data;
1434 if (!cpc->prepared) {
1435 ret = __accept_candidate_process(fd, &client_fd, &client_pid);
1437 /* for hydra need to set pid to pid of non-hydra candidate, */
1438 /* which is connecting now */
1440 cpc->pid = client_pid;
1442 cpc->prepared = true;
1443 cpc->send_fd = client_fd;
1445 SECURE_LOGD("Type %d candidate process was connected, "
1446 "pid: %d", cpc->type, cpc->pid);
1447 cpc->client_channel = _io_channel_create(client_fd,
1449 __handle_loader_client_event,
1451 if (!cpc->client_channel)
1455 __refuse_candidate_process(fd);
1456 _E("Refused candidate process connection");
1462 static bool __handle_hydra_event(int fd, io_condition_e cond, void *data)
1464 candidate_process_context_t *cpc = data;
1472 if (!cpc->prepared) {
1473 ret = __accept_candidate_process(fd, &client_fd, &client_pid);
1475 cpc->hydra_fd = client_fd;
1477 SECURE_LOGD("Type %d hydra process was connected,"
1478 " pid: %d", cpc->type, cpc->hydra_pid);
1480 cpc->client_channel = _io_channel_create(client_fd,
1482 __handle_hydra_client_event,
1484 if (!cpc->client_channel)
1488 __refuse_candidate_process(fd);
1489 _E("Refused hydra process connection");
1495 static void __handle_sigchild(int pid, void *user_data)
1497 candidate_process_context_t *cpc;
1500 appid = g_hash_table_lookup(__pid_table, GINT_TO_POINTER(pid));
1502 security_manager_cleanup_app(appid, getuid(), pid);
1503 g_hash_table_remove(__pid_table, GINT_TO_POINTER(pid));
1506 _log_print("[SIGCHLD]", "pid(%7d)", pid);
1507 cpc = __find_slot_from_pid(pid);
1509 cpc->pid = CANDIDATE_NONE;
1510 __dispose_candidate_process(cpc);
1511 __prepare_candidate_process(cpc->type, cpc->loader_id);
1513 cpc = __find_hydra_slot_from_pid(pid);
1515 cpc->hydra_pid = HYDRA_NONE;
1516 __dispose_hydra_process(cpc);
1517 __prepare_candidate_process(cpc->type, cpc->loader_id);
1521 cpc = __find_slot_from_caller_pid(pid);
1523 __remove_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, cpc->loader_id);
1524 cpc = __find_slot_from_caller_pid(pid);
1528 static bool __handle_label_monitor(int fd, io_condition_e cond, void *data)
1530 candidate_process_context_t *cpc;
1531 GList *iter = candidate_slot_list;
1533 if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
1534 _E("fd(%d), io_condition(%d)", fd, cond);
1539 _log_print("[LABEL]", "fd(%d), condition(%d)", fd, cond);
1540 security_manager_app_labels_monitor_process(label_monitor);
1543 cpc = (candidate_process_context_t *)iter->data;
1544 if (cpc->is_hydra) {
1545 if (cpc->hydra_pid > 0) {
1546 __dispose_hydra_process(cpc);
1547 __prepare_candidate_process(cpc->type,
1550 } else if (cpc->pid > 0) {
1551 __dispose_candidate_process(cpc);
1552 __prepare_candidate_process(cpc->type, cpc->loader_id);
1555 iter = g_list_next(iter);
1561 static float __interpolator(float input, int cpu_max, int cpu_min)
1564 float min = cpu_min / 100.0f;
1565 float max = cpu_max / 100.0f;
1572 ret = cos(input * PI) / 2.0f + 0.5f;
1579 static void __update_threshold(candidate_process_context_t *cpc, float delta)
1581 static float pos = 0.0f;
1590 cpc->threshold = (int)(__interpolator(pos,
1591 cpc->threshold_max, cpc->threshold_min) * 100);
1592 _D("[CPU] type:%d / delta:%f / input cursor : %f / threshold : %d",
1593 cpc->type, delta, pos, cpc->threshold);
1596 static gboolean __handle_idle_checker(gpointer data)
1598 unsigned long long total = 0;
1599 unsigned long long idle = 0;
1601 candidate_process_context_t *cpc;
1604 _E("Critical error!");
1605 __sequencer.idle_checker = 0;
1606 __sequencer.running_cpc = NULL;
1607 return G_SOURCE_REMOVE;
1610 cpc = (candidate_process_context_t *)data;
1611 if (cpc->app_check && !cpc->app_exists) {
1612 _W("The application is not installed. loader(%s:%d)",
1613 cpc->loader_name, cpc->type);
1614 __sequencer.idle_checker = 0;
1615 __sequencer.running_cpc = NULL;
1616 return G_SOURCE_REMOVE;
1619 if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
1620 _W("Slot state is not running. loader(%s:%d)",
1621 cpc->loader_name, cpc->type);
1622 __sequencer.idle_checker = 0;
1623 __sequencer.running_cpc = NULL;
1624 return G_SOURCE_REMOVE;
1627 _get_cpu_idle(&total, &idle);
1628 if (total == cpc->cpu_total_time)
1631 per = (idle - cpc->cpu_idle_time) * 100 / (total - cpc->cpu_total_time);
1632 _D("[CPU] Idle : %d / loader(%s:%d)", per, cpc->loader_name, cpc->type);
1634 if (per >= cpc->threshold) {
1635 __update_threshold(cpc, -0.02f * (per - cpc->threshold));
1636 __prepare_candidate_process(cpc->type, cpc->loader_id);
1637 cpc->touched = true;
1638 __sequencer.idle_checker = 0;
1639 __sequencer.running_cpc = NULL;
1640 return G_SOURCE_REMOVE;
1643 cpc->cpu_idle_time = idle;
1644 cpc->cpu_total_time = total;
1645 __update_threshold(cpc, 0.05f);
1647 cpc->cpu_check_count++;
1648 if (cpc->cpu_check_count == MAX_CPU_CHECK_COUNT) {
1649 _W("CPU check count has exceeded %d times. loader(%s:%d)",
1650 cpc->cpu_check_count,
1653 __sequencer.idle_checker = 0;
1654 __sequencer.running_cpc = NULL;
1655 __sequencer_add_slot(cpc);
1656 return G_SOURCE_REMOVE;
1659 return G_SOURCE_CONTINUE;
1662 static int __add_idle_checker(int detection_method, GList *cur)
1664 candidate_process_context_t *cpc;
1668 cpc = (candidate_process_context_t *)iter->data;
1669 if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
1670 iter = g_list_next(iter);
1674 if (strcmp("null", cpc->loader_path) == 0) {
1675 iter = g_list_next(iter);
1679 if (!cpc->touched && !cpc->on_boot) {
1680 iter = g_list_next(iter);
1684 if (cpc->app_check && !cpc->app_exists) {
1685 iter = g_list_next(iter);
1689 if (cpc->pid == CANDIDATE_NONE &&
1691 (cpc->detection_method & detection_method))) {
1692 if (cpc->timer > 0) {
1693 g_source_remove(cpc->timer);
1697 cpc->cur_event = detection_method;
1698 __sequencer_add_slot(cpc);
1702 iter = g_list_next(iter);
1708 static int __dispatch_cmd_hint(bundle *kb, int detection_method)
1710 _W("cmd hint %d", detection_method);
1711 __add_idle_checker(detection_method, candidate_slot_list);
1716 static int __dispatch_cmd_add_loader(bundle *kb)
1718 const char *add_slot_str = NULL;
1719 const char *caller_pid = NULL;
1723 candidate_process_context_t *cpc;
1725 _W("cmd add loader");
1726 add_slot_str = bundle_get_val(kb, AUL_K_LOADER_PATH);
1727 caller_pid = bundle_get_val(kb, AUL_K_CALLER_PID);
1728 extra = bundle_get_val(kb, AUL_K_LOADER_EXTRA);
1730 if (add_slot_str && caller_pid) {
1731 lid = __make_loader_id();
1733 size = snprintf(0, 0, "%s%s%d", add_slot_str, caller_pid, lid);
1734 loader_name = (char *)malloc(size + 1);
1735 if (loader_name == NULL) {
1736 _E("Out of memory");
1740 snprintf(loader_name, size, "%s%s%d", add_slot_str, caller_pid, lid);
1742 cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid,
1743 atoi(caller_pid), loader_name,
1744 add_slot_str, extra,
1745 METHOD_TIMEOUT | METHOD_VISIBILITY,
1746 METHOD_REQUEST | METHOD_AVAILABLE_MEMORY,
1747 METHOD_TTL | METHOD_OUT_OF_MEMORY,
1750 DEFAULT_CPU_THRESHOLD_MAX,
1751 DEFAULT_CPU_THRESHOLD_MIN,
1764 static int __dispatch_cmd_add_app_defined_loader(bundle *kb)
1766 const char *loader_name;
1768 candidate_process_context_t *cpc;
1769 loader_info_t *info;
1772 _W("cmd add defined loader");
1773 loader_name = bundle_get_val(kb, AUL_K_LOADER_NAME);
1775 if (loader_name == NULL) {
1776 _E("loader_name is NULL");
1780 info = _loader_info_find_loader_by_loader_name(
1781 app_defined_loader_info_list, loader_name);
1782 if (info == NULL || info->extra == NULL) {
1783 _E("loader_name %s, info %d", loader_name, info != NULL);
1787 bundle_encode(info->extra, &extra, &len);
1789 cpc = __find_slot_from_loader_name(loader_name);
1791 lid = __make_loader_id();
1792 cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid, 0,
1793 loader_name, "/usr/bin/app-defined-loader", (const char *)extra,
1794 METHOD_TIMEOUT | METHOD_VISIBILITY,
1795 METHOD_REQUEST | METHOD_AVAILABLE_MEMORY,
1796 METHOD_TTL | METHOD_OUT_OF_MEMORY,
1799 DEFAULT_CPU_THRESHOLD_MAX,
1800 DEFAULT_CPU_THRESHOLD_MIN,
1807 bundle_free_encoded_rawdata(&extra);
1811 lid = cpc->loader_id;
1814 if (cpc->pid == CANDIDATE_NONE)
1815 __prepare_candidate_process(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid);
1820 static int __dispatch_cmd_remove_loader(bundle *kb)
1822 const char *id = bundle_get_val(kb, AUL_K_LOADER_ID);
1825 _W("cmd remove loader");
1828 if (__remove_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid) == 0)
1835 static int __check_caller_by_pid(int pid)
1838 char buf[PATH_MAX] = { 0, };
1840 ret = _proc_get_attr(pid, buf, sizeof(buf));
1844 if (strcmp(buf, "User") == 0 ||
1845 strcmp(buf, "System") == 0 ||
1846 strcmp(buf, "System::Privileged") == 0)
1852 static bool __is_hw_acc(const char *hwacc)
1854 if (strcmp(hwacc, "USE") == 0 ||
1855 (strcmp(hwacc, "SYS") == 0 &&
1856 __sys_hwacc == SETTING_HW_ACCELERATION_ON))
1862 static candidate_process_context_t *__find_available_slot(const char *hwacc,
1863 const char *app_type, const char *loader_name,
1864 candidate_process_context_t **org_cpc)
1867 candidate_process_context_t *cpc;
1873 type = _loader_info_find_type_by_loader_name(loader_info_list,
1876 type = _loader_info_find_type(loader_info_list,
1877 app_type, __is_hw_acc(hwacc));
1879 cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
1888 a_types = _loader_get_alternative_types(loader_info_list, type, &len);
1892 for (i = 0; i < len; i++) {
1893 cpc = __find_slot(a_types[i], PAD_LOADER_ID_STATIC);
1896 if (cpc->prepared) {
1906 static void __update_slot(int type, bool app_exists)
1908 candidate_process_context_t *cpc;
1910 cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
1914 cpc->app_exists = app_exists;
1915 if (cpc->app_check && !cpc->app_exists) {
1917 __dispose_candidate_process(cpc);
1918 __sequencer_remove_slot(cpc);
1919 if (__sequencer_queue_is_empty())
1922 if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING)
1925 if (!cpc->touched && !cpc->on_boot)
1928 if (cpc->timer > 0) {
1929 g_source_remove(cpc->timer);
1933 if (cpc->pid == CANDIDATE_NONE) {
1934 __sequencer_add_slot(cpc);
1940 static void __foreach_loader_info(loader_info_t *info, void *data)
1942 struct app_info *ai = (struct app_info *)data;
1945 exist = _loader_info_exist_app_type(info, ai->type);
1949 info->app_exists = ai->exists;
1950 __update_slot(info->type, info->app_exists);
1953 static int __dispatch_cmd_update_app_type(bundle *b)
1956 struct app_info info;
1957 const char *is_installed;
1959 info.type = bundle_get_val(b, AUL_K_APP_TYPE);
1963 is_installed = bundle_get_val(b, AUL_K_IS_INSTALLED);
1964 if (is_installed && !strcmp(is_installed, "true"))
1967 info.exists = false;
1969 _I("[LAUNCHPAD] type(%s), exists(%d)", info.type, info.exists);
1971 r = _loader_info_foreach(loader_info_list, __foreach_loader_info,
1974 _E("Failed to retrieve loader info");
1981 static void __deactivate_slot(candidate_process_context_t *cpc)
1983 if (cpc->state == CANDIDATE_PROCESS_STATE_PAUSED)
1986 cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
1987 __dispose_candidate_process(cpc);
1990 static void __activate_slot(candidate_process_context_t *cpc)
1992 if (cpc->state == CANDIDATE_PROCESS_STATE_RUNNING)
1995 cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
1996 if (!cpc->touched && !cpc->on_boot)
1999 if ((cpc->app_check && !cpc->app_exists) || cpc->pid > CANDIDATE_NONE)
2002 if (cpc->detection_method & METHOD_TIMEOUT)
2006 static void __update_slot_state(candidate_process_context_t *cpc, int method,
2010 case METHOD_OUT_OF_MEMORY:
2011 if ((force || cpc->deactivation_method & method) &&
2013 __deactivate_slot(cpc);
2015 __activate_slot(cpc);
2018 if (force || cpc->deactivation_method & method)
2019 __deactivate_slot(cpc);
2021 case METHOD_AVAILABLE_MEMORY:
2022 if (force || cpc->activation_method & method)
2023 __activate_slot(cpc);
2025 case METHOD_REQUEST:
2026 if (force || cpc->activation_method & method)
2027 __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, force);
2030 __activate_slot(cpc);
2035 static bool __handle_launch_event(int fd, io_condition_e cond, void *data)
2038 app_pkt_t *pkt = NULL;
2039 appinfo_t *menu_info = NULL;
2040 candidate_process_context_t *cpc = NULL;
2041 candidate_process_context_t *org_cpc = NULL;
2042 const char *app_path = NULL;
2050 if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
2051 _E("fd(%d), condition(%d)", fd, cond);
2052 g_idle_add(__launchpad_recovery_cb, __launchpad_channel);
2053 __launchpad_channel = NULL;
2057 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH");
2058 pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
2060 _E("packet is NULL");
2064 if (cr.uid >= REGULAR_UID_MIN) {
2065 if (__check_caller_by_pid(cr.pid) < 0) {
2066 _E("Invalid caller pid");
2071 kb = bundle_decode(pkt->data, pkt->len);
2073 _E("bundle decode error");
2077 if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
2081 case PAD_CMD_VISIBILITY:
2082 ret = __dispatch_cmd_hint(kb, METHOD_VISIBILITY);
2083 __real_send(clifd, ret);
2086 case PAD_CMD_ADD_LOADER:
2087 ret = __dispatch_cmd_add_loader(kb);
2088 __real_send(clifd, ret);
2091 case PAD_CMD_REMOVE_LOADER:
2092 ret = __dispatch_cmd_remove_loader(kb);
2093 __real_send(clifd, ret);
2096 case PAD_CMD_MAKE_DEFAULT_SLOTS:
2097 ret = __add_default_slots();
2099 _E("Failed to make default slots");
2100 __real_send(clifd, ret);
2103 case PAD_CMD_PREPARE_APP_DEFINED_LOADER:
2104 ret = __dispatch_cmd_add_app_defined_loader(kb);
2105 __real_send(clifd, ret);
2108 case PAD_CMD_DEMAND:
2109 ret = __dispatch_cmd_hint(kb, METHOD_DEMAND);
2110 __real_send(clifd, ret);
2114 __real_send(clifd, getpid());
2117 case PAD_CMD_UPDATE_APP_TYPE:
2118 __dispatch_cmd_update_app_type(kb);
2125 PERF("packet processing start");
2127 menu_info = _appinfo_create(kb);
2128 if (menu_info == NULL) {
2129 _E("such pkg no found");
2133 app_path = _appinfo_get_app_path(menu_info);
2134 if (app_path == NULL) {
2135 _E("app_path is NULL");
2138 if (app_path[0] != '/') {
2139 _E("app_path is not absolute path");
2143 if (menu_info->hwacc == NULL) {
2144 _E("[launchpad] Failed to find H/W acceleration type");
2148 SECURE_LOGD("exec : %s", menu_info->app_path);
2149 SECURE_LOGD("comp_type : %s", menu_info->comp_type);
2150 SECURE_LOGD("internal pool : %s", menu_info->internal_pool);
2151 SECURE_LOGD("hwacc : %s", menu_info->hwacc);
2152 SECURE_LOGD("app_type : %s", menu_info->app_type);
2153 SECURE_LOGD("pkg_type : %s", menu_info->pkg_type);
2155 if (menu_info->comp_type &&
2156 strcmp(menu_info->comp_type, "svcapp") == 0) {
2157 loader_id = __get_loader_id(kb);
2158 if (loader_id > PAD_LOADER_ID_DYNAMIC_BASE) {
2159 type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
2160 cpc = __find_slot(type, loader_id);
2161 if (cpc && !cpc->prepared)
2164 loader_id = PAD_LOADER_ID_DIRECT;
2166 } else if (menu_info->comp_type && menu_info->app_type &&
2167 strcmp(menu_info->comp_type, "widgetapp") == 0 &&
2168 strcmp(menu_info->app_type, "webapp") == 0) {
2169 loader_id = PAD_LOADER_ID_DIRECT;
2171 loader_id = __get_loader_id(kb);
2172 if (loader_id <= PAD_LOADER_ID_STATIC) {
2173 cpc = __find_available_slot(menu_info->hwacc,
2174 menu_info->app_type,
2175 menu_info->loader_name, &org_cpc);
2177 type = LAUNCHPAD_LOADER_TYPE_DYNAMIC;
2178 cpc = __find_slot(type, loader_id);
2179 if (cpc && !cpc->prepared)
2184 _modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
2185 if (menu_info->appid == NULL) {
2186 _E("unable to get appid from menu_info");
2190 PERF("get package information & modify bundle done");
2192 if (loader_id == PAD_LOADER_ID_DIRECT || cpc == NULL) {
2193 _W("Launch directly %d %p", loader_id, cpc);
2194 pid = __launch_directly(menu_info->appid, app_path, clifd, kb,
2196 if (org_cpc && (!org_cpc->app_check || org_cpc->app_exists) &&
2197 org_cpc->pid == CANDIDATE_NONE &&
2198 !__sequencer_slot_exist(org_cpc)) {
2199 if (org_cpc->timer > 0) {
2200 g_source_remove(org_cpc->timer);
2204 __update_slot_state(org_cpc, METHOD_REQUEST, true);
2205 __set_timer(org_cpc);
2208 _W("Launch %d type process", cpc->type);
2209 pid = __send_launchpad_loader(cpc, pkt, app_path, clifd);
2212 _memory_monitor_reset_timer();
2213 __send_result_to_caller(clifd, pid, app_path);
2220 _dbus_send_app_launch_signal(pid, menu_info->appid);
2221 g_hash_table_insert(__pid_table, GINT_TO_POINTER(pid),
2222 strdup(menu_info->appid));
2223 _log_print("[LAUNCH]", "pid(%7d) | appid(%s)",
2224 pid, menu_info->appid);
2227 if (menu_info != NULL)
2228 _appinfo_free(menu_info);
2235 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
2240 static void __destroy_slot(candidate_process_context_t *cpc)
2245 if (cpc->hydra_channel)
2246 _io_channel_destroy(cpc->hydra_channel);
2249 _io_channel_destroy(cpc->channel);
2251 if (cpc->loader_extra)
2252 free(cpc->loader_extra);
2254 if (cpc->loader_path)
2255 free(cpc->loader_path);
2257 if (cpc->loader_name)
2258 free(cpc->loader_name);
2263 static candidate_process_context_t *__create_slot(int type, int loader_id,
2264 int caller_pid, const char *loader_name, const char *loader_path,
2265 const char *loader_extra, int detection_method,
2266 int activation_method, int deactivation_method,
2267 unsigned int ttl, int timeout_val,
2268 int threshold_max, int threshold_min,
2269 bool on_boot, bool app_exists, bool is_hydra, bool app_check)
2271 candidate_process_context_t *cpc;
2273 cpc = calloc(1, sizeof(candidate_process_context_t));
2275 _E("Out of memory");
2279 cpc->loader_name = strdup(loader_name);
2280 if (cpc->loader_name == NULL) {
2281 _E("Failed to duplicate loader name(%s)", loader_name);
2282 __destroy_slot(cpc);
2286 cpc->loader_path = strdup(loader_path);
2287 if (cpc->loader_path == NULL) {
2288 _E("Failed to duplicate loader path(%s)", loader_path);
2289 __destroy_slot(cpc);
2293 cpc->loader_extra = loader_extra ? strdup(loader_extra) : strdup("");
2294 if (cpc->loader_extra == NULL) {
2295 _E("Failed to duplicate loader extra(%s)",
2296 loader_extra ? loader_extra : "null");
2297 __destroy_slot(cpc);
2302 cpc->prepared = false;
2303 cpc->pid = CANDIDATE_NONE;
2304 cpc->hydra_pid = HYDRA_NONE;
2305 cpc->caller_pid = caller_pid;
2306 cpc->loader_id = loader_id;
2309 cpc->last_exec_time = 0;
2311 cpc->detection_method = detection_method;
2312 cpc->timeout_val = timeout_val;
2313 cpc->cpu_total_time = 0;
2314 cpc->cpu_idle_time = 0;
2315 cpc->threshold = threshold_max;
2316 cpc->threshold_max = threshold_max;
2317 cpc->threshold_min = threshold_min;
2318 cpc->on_boot = on_boot;
2319 cpc->app_exists = app_exists;
2320 cpc->touched = false;
2322 cpc->activation_method = activation_method;
2323 cpc->deactivation_method = deactivation_method;
2325 cpc->live_timer = 0;
2326 cpc->is_hydra = is_hydra;
2327 cpc->app_check = app_check;
2328 cpc->score = WIN_SCORE;
2330 cpc->cpu_check_count = 0;
2332 if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) &&
2334 cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
2336 cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
2338 _W("loader(%s), type(%d), state(%d)",
2339 cpc->loader_name, cpc->type, cpc->state);
2343 static candidate_process_context_t *__add_slot(int type, int loader_id,
2344 int caller_pid, const char *loader_name, const char *loader_path,
2345 const char *loader_extra, int detection_method,
2346 int activation_method, int deactivation_method,
2347 unsigned int ttl, int timeout_val,
2348 int threshold_max, int threshold_min,
2349 bool on_boot, bool app_exists, bool is_hydra, bool app_check)
2351 candidate_process_context_t *cpc;
2353 io_channel_h channel;
2355 io_channel_h hydra_channel;
2357 if (__find_slot(type, loader_id) != NULL)
2360 cpc = __create_slot(type, loader_id,
2361 caller_pid, loader_name, loader_path,
2362 loader_extra, detection_method,
2363 activation_method, deactivation_method,
2365 threshold_max, threshold_min,
2366 on_boot, app_exists, is_hydra, app_check);
2370 fd = __listen_candidate_process(cpc->type, cpc->loader_id);
2372 _E("[launchpad] Listening the socket to " \
2373 "the type %d candidate process failed.",
2375 __destroy_slot(cpc);
2379 channel = _io_channel_create(fd, IO_IN, __handle_loader_event, cpc);
2382 __destroy_slot(cpc);
2386 cpc->channel = channel;
2389 hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id);
2390 if (hydra_fd == -1) {
2391 _E("[launchpad] Listening the socket to " \
2392 "the type %d hydra process failed.",
2394 __destroy_slot(cpc);
2398 hydra_channel = _io_channel_create(hydra_fd, IO_IN,
2399 __handle_hydra_event, cpc);
2400 if (!hydra_channel) {
2402 __destroy_slot(cpc);
2406 cpc->hydra_channel = hydra_channel;
2410 candidate_slot_list = g_list_append(candidate_slot_list, cpc);
2415 static int __remove_slot(int type, int loader_id)
2417 candidate_process_context_t *cpc;
2420 iter = candidate_slot_list;
2422 cpc = (candidate_process_context_t *)iter->data;
2423 if (type == cpc->type && loader_id == cpc->loader_id) {
2424 __dispose_candidate_process(cpc);
2425 candidate_slot_list = g_list_delete_link(
2426 candidate_slot_list, iter);
2427 __destroy_slot(cpc);
2431 iter = g_list_next(iter);
2437 static int __init_launchpad_fd(int argc, char **argv)
2439 io_condition_e cond;
2442 fd = __launchpad_pre_init(argc, argv);
2444 _E("launchpad pre init failed");
2448 cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
2449 __launchpad_channel = _io_channel_create(fd, cond,
2450 __handle_launch_event, NULL);
2451 if (!__launchpad_channel) {
2459 static bool __on_directory_create(const char *event_name, uint32_t mask,
2463 _E("Invalid parameter");
2467 if (!strcmp(event_name, LOADERS_PATH)) {
2468 __init_app_defined_loader_monitor();
2475 static bool __on_file_change(const char *event_name, uint32_t mask,
2480 loader_info_t* info;
2481 candidate_process_context_t *cpc;
2484 _E("Invalid parameter");
2488 ext = strrchr(event_name, '.');
2489 if (ext == NULL || strcmp(ext, ".loader") != 0)
2492 if (mask & IN_CREATE) {
2493 snprintf(buf, sizeof(buf), "%s/%s",
2494 APP_DEFINED_LOADER_INFO_PATH, event_name);
2495 app_defined_loader_info_list = _loader_info_load_file(
2496 app_defined_loader_info_list, buf);
2497 } else if (mask & IN_DELETE) {
2498 snprintf(buf, ext - event_name + 1, "%s", event_name);
2500 info = _loader_info_find_loader_by_loader_name(
2501 app_defined_loader_info_list, buf);
2502 cpc = __find_slot_from_loader_name(info->name);
2503 __remove_slot(cpc->type, cpc->loader_id);
2504 app_defined_loader_info_list = _loader_info_unload(
2505 app_defined_loader_info_list, buf);
2511 static void __init_app_defined_loader_monitor(void)
2515 ret = access(APP_DEFINED_LOADER_INFO_PATH, F_OK);
2517 _W("Failed to access %s", APP_DEFINED_LOADER_INFO_PATH);
2518 ret = _inotify_add_watch(OPT_SHARE_PATH,
2519 IN_CREATE, __on_directory_create, NULL);
2521 _E("Failed to add inotify watch %s", OPT_SHARE_PATH);
2526 ret = _inotify_add_watch(APP_DEFINED_LOADER_INFO_PATH,
2527 IN_CREATE | IN_DELETE, __on_file_change, NULL);
2530 _E("Failed to add inotify watch %s",
2531 APP_DEFINED_LOADER_INFO_PATH);
2538 static int __init_label_monitor_fd(void)
2540 io_condition_e cond;
2544 r = security_manager_app_labels_monitor_init(&label_monitor);
2545 if (r != SECURITY_MANAGER_SUCCESS)
2548 r = security_manager_app_labels_monitor_process(label_monitor);
2549 if (r != SECURITY_MANAGER_SUCCESS)
2552 security_manager_app_labels_monitor_get_fd(label_monitor, &fd);
2554 _E("failed to get fd");
2558 cond = IO_IN | IO_PRI | IO_HUP | IO_ERR | IO_NVAL;
2559 __label_monitor_channel = _io_channel_create(fd, cond,
2560 __handle_label_monitor, NULL);
2561 if (!__label_monitor_channel)
2570 if (label_monitor) {
2571 security_manager_app_labels_monitor_finish(label_monitor);
2572 label_monitor = NULL;
2578 static int __verify_loader_caps(const char *loader)
2581 cap_flag_value_t eff_state;
2582 cap_flag_value_t inh_state;
2583 cap_value_t values[] = {CAP_SETGID, CAP_MAC_ADMIN};
2586 int size = ARRAY_SIZE(values);
2588 /* If Dytransition feature is enabled, CAP_MAC_ADMIN is unnecessary */
2592 cap_d = cap_get_file(loader);
2594 _E("Failed to get cap from file(%s)", loader);
2598 for (i = 0; i < size; i++) {
2599 r = cap_get_flag(cap_d, values[i], CAP_INHERITABLE, &inh_state);
2601 _E("Failed to get cap inh - errno(%d)", errno);
2606 r = cap_get_flag(cap_d, values[i], CAP_EFFECTIVE, &eff_state);
2608 _E("Failed to get cap eff - errno(%d)", errno);
2613 if ((inh_state != CAP_SET) || (eff_state != CAP_SET)) {
2614 _E("The %s doesn't have %d cap", loader, values[i]);
2624 static void __add_slot_from_info(gpointer data, gpointer user_data)
2626 loader_info_t *info = (loader_info_t *)data;
2627 candidate_process_context_t *cpc;
2628 bundle_raw *extra = NULL;
2631 if (!strcmp(info->exe, "null")) {
2632 cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset,
2633 PAD_LOADER_ID_DIRECT,
2634 0, info->name, info->exe, NULL,
2636 info->cpu_threshold_max,
2637 info->cpu_threshold_min,
2645 info->type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset;
2650 if (access(info->exe, F_OK | X_OK) == 0) {
2651 if (__verify_loader_caps(info->exe) < 0)
2655 bundle_encode(info->extra, &extra, &len);
2657 cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset,
2658 PAD_LOADER_ID_STATIC,
2659 0, info->name, info->exe, (char *)extra,
2660 info->detection_method,
2661 info->activation_method,
2662 info->deactivation_method,
2665 info->cpu_threshold_max,
2666 info->cpu_threshold_min,
2674 info->type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset;
2679 static int __add_default_slots(void)
2681 if (loader_info_list)
2682 _loader_info_dispose(loader_info_list);
2684 loader_info_list = _loader_info_load_dir(LOADER_INFO_PATH);
2685 if (loader_info_list == NULL)
2688 user_slot_offset = 0;
2689 g_list_foreach(loader_info_list, __add_slot_from_info, NULL);
2690 __add_idle_checker(0, candidate_slot_list);
2695 static void __add_app_defined_loaders(void)
2697 app_defined_loader_info_list = _loader_info_load_dir(APP_DEFINED_LOADER_INFO_PATH);
2700 static bool __is_low_memory(void)
2702 if (_memory_monitor_is_low_memory())
2705 if (__memory_status_low >= MEMORY_STATUS_LOW)
2711 static void __hw_acceleration_changed_cb(keynode_t *key, void *data)
2713 __sys_hwacc = vconf_keynode_get_int(key);
2714 _D("sys hwacc: %d", __sys_hwacc);
2717 static void __update_lang(keynode_t *node, void *user_data)
2721 lang = vconf_keynode_get_str(node);
2723 _E("Failed to get language");
2727 setenv("LANG", lang, 1);
2730 static void __region_format_changed_cb(keynode_t *node, void *data)
2734 region = vconf_keynode_get_str(node);
2736 _E("Failed to get value");
2740 setenv("LC_CTYPE", region, 1);
2743 static void __memory_status_low_changed_cb(keynode_t *node, void *data)
2745 candidate_process_context_t *cpc;
2748 __memory_status_low = vconf_keynode_get_int(node);
2749 if (__memory_status_low >= MEMORY_STATUS_LOW) {
2751 iter = candidate_slot_list;
2753 cpc = (candidate_process_context_t *)iter->data;
2754 __update_slot_state(cpc, METHOD_OUT_OF_MEMORY, false);
2755 iter = g_list_next(iter);
2760 static void __memory_status_normal_changed_cb(keynode_t *node, void *data)
2762 candidate_process_context_t *cpc;
2765 __memory_status_normal = vconf_keynode_get_int(node);
2766 if (__memory_status_normal == MEMORY_STATUS_NORMAL) {
2768 iter = candidate_slot_list;
2770 cpc = (candidate_process_context_t *)iter->data;
2771 __update_slot_state(cpc, METHOD_AVAILABLE_MEMORY, true);
2772 iter = g_list_next(iter);
2777 static void __unregister_vconf_events(void)
2782 type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
2783 key = _config_get_string_value(type);
2784 vconf_ignore_key_changed(key, __memory_status_normal_changed_cb);
2786 type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
2787 key = _config_get_string_value(type);
2788 vconf_ignore_key_changed(key, __memory_status_low_changed_cb);
2790 vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT,
2791 __region_format_changed_cb);
2792 vconf_ignore_key_changed(VCONFKEY_LANGSET,
2794 vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
2795 __hw_acceleration_changed_cb);
2798 static int __register_vconf_events(void)
2806 r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
2808 _E("Failed to get vconf hw acceleration. err = %d", r);
2810 r = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
2811 __hw_acceleration_changed_cb, NULL);
2812 if (r != VCONF_OK) {
2813 _E("Failed to register callback for hw acceleration. err = %d",
2817 lang = vconf_get_str(VCONFKEY_LANGSET);
2819 setenv("LANG", lang, 1);
2823 r = vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, NULL);
2825 _E("Failed to register callback for langset. err = %d", r);
2827 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
2829 setenv("LC_CTYPE", region, 1);
2833 r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT,
2834 __region_format_changed_cb, NULL);
2836 _E("Failed to register callback for regionformat. err = %d", r);
2838 type = CONFIG_TYPE_MEMORY_STATUS_LOW_KEY;
2839 key = _config_get_string_value(type);
2840 type = CONFIG_TYPE_MEMORY_STATUS_LOW_VALUE;
2841 MEMORY_STATUS_LOW = _config_get_int_value(type);
2843 r = vconf_get_int(key, &__memory_status_low);
2845 _E("Failed to get vconf low memory. err = %d", r);
2847 r = vconf_notify_key_changed(key,
2848 __memory_status_low_changed_cb, NULL);
2850 _E("Failed to register callback for low memory. err = %d", r);
2852 type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_KEY;
2853 key = _config_get_string_value(type);
2854 type = CONFIG_TYPE_MEMORY_STATUS_NORMAL_VALUE;
2855 MEMORY_STATUS_NORMAL = _config_get_int_value(type);
2857 r = vconf_get_int(key, &__memory_status_normal);
2859 _E("Failed to get vconf normal memory. err = %d", r);
2861 r = vconf_notify_key_changed(key,
2862 __memory_status_normal_changed_cb, NULL);
2864 _E("Failed to register callback for normal memory. err = %d", r);
2869 static bool __handle_logger(int fd, io_condition_e cond, void *data)
2875 if (cond & (IO_ERR | IO_HUP | IO_NVAL)) {
2876 _E("fd(%d), io_condition(%d)", fd, cond);
2877 g_idle_add(__logger_recovery_cb, __logger_channel);
2878 __logger_channel = NULL;
2882 pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
2884 _E("Failed to receive the packet");
2888 if (getuid() != cr.uid) {
2889 _E("Invalid caller");
2893 if (pkt->len <= 0) {
2894 _E("Invalid message");
2898 _E("[%d] %s", cr.pid, (const char *)pkt->data);
2899 _log_print("[ERROR]", "pid(%7d) | message(%s)",
2900 cr.pid, (const char *)pkt->data);
2910 static int __init_logger_fd(void)
2912 io_condition_e cond;
2915 fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK);
2917 _E("Failed to create logger socker");
2921 cond = IO_IN | IO_PRI | IO_ERR | IO_HUP | IO_NVAL;
2922 __logger_channel = _io_channel_create(fd, cond, __handle_logger, NULL);
2923 if (!__logger_channel) {
2931 static int __memory_monitor_cb(bool low_memory, void *user_data)
2933 candidate_process_context_t *cpc;
2935 cpc = __get_running_slot(false);
2936 if (!cpc && low_memory)
2941 __update_slots_pss();
2943 candidate_slot_list = g_list_sort(candidate_slot_list,
2947 __pause_last_running_slot(false);
2949 cpc = __get_running_slot(false);
2952 } while (__is_low_memory());
2954 __resume_all_slots();
2960 static gboolean __logger_recovery_cb(gpointer data)
2962 io_channel_h channel = data;
2965 _io_channel_destroy(channel);
2967 ret = __init_logger_fd();
2969 _E("Failed to recover logger socket");
2970 return G_SOURCE_REMOVE;
2973 _E("[__RECOVERY__] Logger socket");
2975 return G_SOURCE_REMOVE;
2978 static gboolean __launchpad_recovery_cb(gpointer data)
2980 io_channel_h channel = data;
2983 _io_channel_destroy(channel);
2985 ret = __init_launchpad_fd(0, NULL);
2987 _E("Failed to recover launchpad socket");
2989 return G_SOURCE_REMOVE;
2992 _E("[__RECOVERY__] Launchpad socket");
2994 return G_SOURCE_REMOVE;
2997 static int __before_loop(int argc, char **argv)
3001 ret = __sequencer_init();
3003 _E("Failed to initialize sequencer");
3007 ret = _signal_init();
3009 _E("Failed to initialize signal");
3013 _signal_set_sigchld_cb(__handle_sigchild, NULL);
3015 ret = __init_launchpad_fd(argc, argv);
3017 _E("__init_launchpad_fd() failed");
3021 ret = __init_logger_fd();
3023 _E("__init_logger_fd() failed");
3027 ret = __init_label_monitor_fd();
3029 _W("Failed to initialize label monitor");
3031 ret = _config_init();
3033 _W("Failed to initialize config");
3037 _W("Failed to initialize dbus");
3041 MAX_CPU_CHECK_COUNT = _config_get_int_value(
3042 CONFIG_TYPE_CPU_CHECKER_MAX_COUNT);
3043 __add_default_slots();
3044 launcher_info_list = _launcher_info_load(LAUNCHER_INFO_PATH);
3046 __add_app_defined_loaders();
3048 ret = _send_cmd_to_amd(LAUNCHPAD_LAUNCH_SIGNAL);
3050 _W("Failed to send cmd(%d) to amd", LAUNCHPAD_LAUNCH_SIGNAL);
3052 __pid_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
3055 _E("Failed to create pid table");
3059 __register_vconf_events();
3060 __init_app_defined_loader_monitor();
3061 _memory_monitor_init();
3062 _memory_monitor_set_event_cb(__memory_monitor_cb, NULL);
3068 static void __after_loop(void)
3071 _memory_monitor_fini();
3072 __unregister_vconf_events();
3074 g_hash_table_destroy(__pid_table);
3076 if (_send_cmd_to_amd(LAUNCHPAD_DEAD_SIGNAL) < 0)
3077 _W("Failed to send cmd(%d) to amd", LAUNCHPAD_DEAD_SIGNAL);
3080 _launcher_info_unload(launcher_info_list);
3084 _loader_info_dispose(app_defined_loader_info_list);
3086 if (__label_monitor_channel)
3087 _io_channel_destroy(__label_monitor_channel);
3090 security_manager_app_labels_monitor_finish(label_monitor);
3092 if (__logger_channel)
3093 _io_channel_destroy(__logger_channel);
3095 if (__launchpad_channel)
3096 _io_channel_destroy(__launchpad_channel);
3103 int main(int argc, char **argv)
3105 GMainLoop *mainloop = NULL;
3107 mainloop = g_main_loop_new(NULL, FALSE);
3109 _E("Failed to create glib main loop");
3113 if (__before_loop(argc, argv) != 0) {
3114 _E("process-pool Initialization failed!");
3118 #ifdef TIZEN_FEATURE_PRIORITY_CHANGE
3121 g_main_loop_run(mainloop);