4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 #include <sys/types.h>
25 #include <sys/inotify.h>
28 #include <Ecore_Input.h>
34 #ifdef _APPFW_FEATURE_APP_CHECKER
35 #include <app-checker-server.h>
38 #include <sys/resource.h>
40 #include <pkgmgr-info.h>
41 #include <proc_stat.h>
43 #include "amd_config.h"
44 #include "simple_util.h"
47 #include "amd_appinfo.h"
48 #include "amd_cgutil.h"
50 #include "amd_status.h"
51 #include "amd_launch.h"
52 #include "amd_request.h"
55 # define MOUNT_PATH "/sys/fs/cgroup"
59 # define AGENT_PATH "/usr/bin/daemon-manager-release-agent"
62 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
63 typedef struct _r_app_info_t{
64 char pkg_name[MAX_PACKAGE_STR_SIZE];
68 GSList *r_app_info_list = NULL;
71 gboolean platform_ready = false;
73 #define WINDOW_READY "/tmp/.wm_ready"
75 typedef struct _window_watch {
78 Ecore_Fd_Handler *win_watch_ewd;
80 static _window_watch_t *win_info_t = NULL;
82 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
83 static void __vconf_cb(keynode_t *key, void *data);
85 static int __app_dead_handler(int pid, void *data);
88 extern int _status_init(struct amdmgr* amd);
90 static int __send_to_sigkill(int pid)
94 _D("__send_to_sigkill, pid: %d", pid);
100 if (killpg(pgid, SIGKILL) < 0)
106 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
107 static int __kill_bg_apps(int limit)
112 r_app_info_t *info_t = NULL;
115 len = g_slist_length(r_app_info_list);
121 for ( i=0, iter = r_app_info_list; i<n ; i++) {
122 info_t = (r_app_info_t *)iter->data;
123 //__send_to_sigkill(info_t->pid);
124 proc_group_change_status(PROC_CGROUP_SET_TERMINATE_REQUEST, info_t->pid, NULL);
125 _term_app(info_t->pid, 0);
126 iter = g_slist_next(iter);
127 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
134 static int __remove_item_running_list(int pid)
136 r_app_info_t *info_t = NULL;
139 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
141 info_t = (r_app_info_t *)iter->data;
142 if(pid == info_t->pid) {
143 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
151 gboolean __add_item_running_list(gpointer user_data)
155 pkgmgrinfo_appinfo_h handle = NULL;
157 r_app_info_t *info_t = NULL;
162 item_pkt_t *item = (item_pkt_t *)user_data;
167 char* appid = item->appid;
170 SECURE_LOGD("__add_item_running_list pid: %d", pid);
172 if (vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, &limit) != 0){
173 _E("Unable to get VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS\n");
178 } else if (strncmp(appid, "org.tizen.cluster-home", 24) == 0) {
179 if(limit>0) __kill_bg_apps(limit-1);
183 SECURE_LOGD("__add_item_running_list appid: %s", appid);
185 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
186 if (ret != PMINFO_R_OK) {
187 _E("pkgmgrinfo_pkginfo_get_pkginfo with %s failed", appid);
191 ret = pkgmgrinfo_appinfo_is_taskmanage(handle, &taskmanage);
192 if (ret != PMINFO_R_OK) {
193 _E("pkgmgrinfo_appinfo_is_taskmanage failed");
197 if (taskmanage == false)
200 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
202 info_t = (r_app_info_t *)iter->data;
203 if(pid == info_t->pid) {
205 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
206 r_app_info_list = g_slist_append(r_app_info_list, info_t);
212 info_t = malloc(sizeof(r_app_info_t));
213 if (info_t == NULL) {
218 strncpy(info_t->pkg_name, appid, MAX_PACKAGE_STR_SIZE-1);
220 r_app_info_list = g_slist_append(r_app_info_list, info_t);
223 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
225 info_t = (r_app_info_t *)iter->data;
228 if(limit>0) __kill_bg_apps(limit);
230 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
232 info_t = (r_app_info_t *)iter->data;
236 pkgmgrinfo_appinfo_destroy_appinfo(handle);
242 static void __vconf_cb(keynode_t *key, void *data)
247 name = vconf_keynode_get_name(key);
250 }else if ( strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) == 0){
251 limit = vconf_keynode_get_int(key);
252 if(limit>0) __kill_bg_apps(limit);
257 static int __app_dead_handler(int pid, void *data)
259 char trm_buf[MAX_PACKAGE_STR_SIZE];
260 char buf[MAX_LOCAL_BUFSZ];
262 _I("__app_dead_handler, pid: %d", pid);
267 _unregister_key_event(pid);
268 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
269 __remove_item_running_list(pid);
271 _status_remove_app_info_list(pid);
272 snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_terminated:[PID]%d", pid);
273 __trm_app_info_send_socket(trm_buf);
275 snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, pid);
281 static void __start_cb(void *user_data,
282 const char *filename, const struct appinfo *ai)
284 /*struct amdmgr *amd = user_data;*/
285 const char *componet = NULL;
288 componet = appinfo_get_value(ai, AIT_COMPTYPE);
290 r = appinfo_get_boolean(ai, AIT_ONBOOT);
292 if (r == 1 && componet && strncmp(componet, "svcapp", 6) == 0)
294 const char *appid = appinfo_get_value(ai, AIT_NAME);
295 if (appid && _status_app_is_running(appid) < 0)
297 _I("start service (on-boot) - %s", appid);
298 _start_srv(ai, NULL);
302 _E("service: %s is already running", appid);
307 static void _start_services(struct amdmgr *amd)
309 appinfo_foreach(amd->af, __start_cb, amd);
312 gboolean _get_platform_ready()
314 return platform_ready;
317 static gboolean __platform_ready_handler(gpointer data)
319 _E("[Info]__platform_ready_handler");
320 platform_ready = true;
325 static int __booting_done_handler(int pid, void *data)
329 _E("[Info]__booting_done_handler, pid: %d", pid);
331 _start_services((struct amdmgr*)data);
333 timer_id = g_timeout_add(60000, __platform_ready_handler, NULL);
338 static gboolean _check_window_ready(void)
340 if (access(WINDOW_READY, R_OK) == 0)
346 static void __window_init(void)
357 static Eina_Bool _window_cb(void *data, Ecore_Fd_Handler * fd_handler)
360 char buf[FILENAME_MAX];
362 struct inotify_event* event;
364 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) {
365 _E("An error has occurred. Stop watching this fd and quit");
366 return ECORE_CALLBACK_CANCEL;
369 fd = ecore_main_fd_handler_fd_get(fd_handler);
371 _E("ecore_main_fd_handler_fd_get error");
372 return ECORE_CALLBACK_CANCEL;
374 len = read(fd, buf, FILENAME_MAX);
376 event = (struct inotify_event*) &buf[0];
378 _D("filename : %s", event->name);
380 if (access(WINDOW_READY, R_OK) == 0) {
383 ecore_main_fd_handler_del(win_info_t->win_watch_ewd);
384 inotify_rm_watch(win_info_t->watch_fd, win_info_t->win_watch_wd);
390 return ECORE_CALLBACK_RENEW;
393 static void _register_window_init(void)
395 _D("_register_window_init");
397 win_info_t = malloc(sizeof(_window_watch_t));
399 _E("Unable to allocate memory. don't init widow\n");
402 win_info_t->watch_fd = inotify_init();
403 win_info_t->win_watch_wd = inotify_add_watch(win_info_t->watch_fd, "/tmp", IN_CREATE);
404 win_info_t->win_watch_ewd = ecore_main_fd_handler_add(win_info_t->watch_fd,
405 ECORE_FD_READ, _window_cb, NULL, NULL, NULL);
408 static void _window_init(void)
410 if (_check_window_ready())
413 _register_window_init();
425 _D("ecore init done\n");
427 ret = appinfo_init(&amd.af);
430 ret = cgutil_create(MOUNT_PATH, AGENT_PATH, &amd.cg);
433 ret = _request_init(&amd);
440 _D("AMD init done\n");
442 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
443 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, __vconf_cb, NULL) != 0) {
444 _E("Unable to register callback for VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS\n");
448 aul_listen_app_dead_signal(__app_dead_handler, NULL);
449 aul_listen_booting_done_signal(__booting_done_handler, &amd);
451 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
452 int res = setpriority(PRIO_PROCESS, 0, -12);
455 SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)",
456 getpid(), errno, strerror(errno));
462 gboolean __amd_ready(gpointer user_data)
466 int handle = creat("/tmp/amd_ready", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
473 int main(int argc, char *argv[])
477 #ifdef _APPFW_FEATURE_APP_CHECKER
478 if (ac_server_initialize() != AC_R_OK){
479 _E("ac_server_initialize failed!\n");
486 _E("AMD Initialization failed!\n");
490 g_idle_add(__amd_ready, NULL);
492 ecore_main_loop_begin();