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 strncpy(info_t->pkg_name, appid, MAX_PACKAGE_STR_SIZE-1);
215 r_app_info_list = g_slist_append(r_app_info_list, info_t);
218 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
220 info_t = (r_app_info_t *)iter->data;
223 if(limit>0) __kill_bg_apps(limit);
225 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
227 info_t = (r_app_info_t *)iter->data;
231 pkgmgrinfo_appinfo_destroy_appinfo(handle);
237 static void __vconf_cb(keynode_t *key, void *data)
242 name = vconf_keynode_get_name(key);
245 }else if ( strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) == 0){
246 limit = vconf_keynode_get_int(key);
247 if(limit>0) __kill_bg_apps(limit);
252 static int __app_dead_handler(int pid, void *data)
254 char trm_buf[MAX_PACKAGE_STR_SIZE];
255 char buf[MAX_LOCAL_BUFSZ];
257 _I("__app_dead_handler, pid: %d", pid);
262 _unregister_key_event(pid);
263 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
264 __remove_item_running_list(pid);
266 _status_remove_app_info_list(pid);
267 snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_terminated:[PID]%d", pid);
268 __trm_app_info_send_socket(trm_buf);
270 snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, pid);
276 static void __start_cb(void *user_data,
277 const char *filename, const struct appinfo *ai)
279 /*struct amdmgr *amd = user_data;*/
280 const char *componet = NULL;
283 componet = appinfo_get_value(ai, AIT_COMPTYPE);
285 r = appinfo_get_boolean(ai, AIT_ONBOOT);
287 if (r == 1 && strncmp(componet, "svcapp", 6) == 0)
289 const char *appid = appinfo_get_value(ai, AIT_NAME);
290 if (_status_app_is_running(appid) < 0)
292 _I("start service (on-boot) - %s", appid);
293 _start_srv(ai, NULL);
297 _E("service: %s is already running", appid);
302 static void _start_services(struct amdmgr *amd)
304 appinfo_foreach(amd->af, __start_cb, amd);
307 gboolean _get_platform_ready()
309 return platform_ready;
312 static gboolean __platform_ready_handler(gpointer data)
314 _E("[Info]__platform_ready_handler");
315 platform_ready = true;
320 static int __booting_done_handler(int pid, void *data)
324 _E("[Info]__booting_done_handler, pid: %d", pid);
326 _start_services((struct amdmgr*)data);
328 timer_id = g_timeout_add(60000, __platform_ready_handler, NULL);
333 static gboolean _check_window_ready(void)
335 if (access(WINDOW_READY, R_OK) == 0)
341 static void __window_init(void)
352 static Eina_Bool _window_cb(void *data, Ecore_Fd_Handler * fd_handler)
355 char buf[FILENAME_MAX];
357 struct inotify_event* event;
359 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) {
360 _E("An error has occurred. Stop watching this fd and quit");
361 return ECORE_CALLBACK_CANCEL;
364 fd = ecore_main_fd_handler_fd_get(fd_handler);
366 _E("ecore_main_fd_handler_fd_get error");
367 return ECORE_CALLBACK_CANCEL;
369 len = read(fd, buf, FILENAME_MAX);
371 event = (struct inotify_event*) &buf[0];
373 _D("filename : %s", event->name);
375 if (access(WINDOW_READY, R_OK) == 0) {
378 ecore_main_fd_handler_del(win_info_t->win_watch_ewd);
379 inotify_rm_watch(win_info_t->watch_fd, win_info_t->win_watch_wd);
385 return ECORE_CALLBACK_RENEW;
388 static void _register_window_init(void)
390 _D("_register_window_init");
392 win_info_t = malloc(sizeof(_window_watch_t));
394 _E("Unable to allocate memory. don't init widow\n");
397 win_info_t->watch_fd = inotify_init();
398 win_info_t->win_watch_wd = inotify_add_watch(win_info_t->watch_fd, "/tmp", IN_CREATE);
399 win_info_t->win_watch_ewd = ecore_main_fd_handler_add(win_info_t->watch_fd,
400 ECORE_FD_READ, _window_cb, NULL, NULL, NULL);
403 static void _window_init(void)
405 if (_check_window_ready())
408 _register_window_init();
420 _D("ecore init done\n");
422 ret = appinfo_init(&amd.af);
425 ret = cgutil_create(MOUNT_PATH, AGENT_PATH, &amd.cg);
428 ret = _request_init(&amd);
435 _D("AMD init done\n");
437 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
438 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, __vconf_cb, NULL) != 0) {
439 _E("Unable to register callback for VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS\n");
443 aul_listen_app_dead_signal(__app_dead_handler, NULL);
444 aul_listen_booting_done_signal(__booting_done_handler, &amd);
446 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
447 int res = setpriority(PRIO_PROCESS, 0, -12);
450 SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)",
451 getpid(), errno, strerror(errno));
457 gboolean __amd_ready(gpointer user_data)
461 int handle = creat("/tmp/amd_ready", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
468 int main(int argc, char *argv[])
472 #ifdef _APPFW_FEATURE_APP_CHECKER
473 if (ac_server_initialize() != AC_R_OK){
474 _E("ac_server_initialize failed!\n");
481 _E("AMD Initialization failed!\n");
485 g_idle_add(__amd_ready, NULL);
487 ecore_main_loop_begin();