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.
24 #include <sys/types.h>
26 #include <sys/inotify.h>
29 #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"
49 #include "amd_status.h"
50 #include "amd_launch.h"
51 #include "amd_request.h"
52 #include "amd_app_group.h"
53 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
54 #include "appfw_env.h"
55 #include "app_signal.h"
59 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
60 typedef struct _r_app_info_t{
61 char pkg_name[MAX_PACKAGE_STR_SIZE];
65 GSList *r_app_info_list = NULL;
68 gboolean platform_ready = false;
69 #ifdef _APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
73 typedef struct _window_watch {
76 Ecore_Fd_Handler *win_watch_ewd;
78 static _window_watch_t *win_info_t = NULL;
80 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
81 extern DBusConnection *conn;
82 extern struct appinfomgr *_laf;
85 static int window_initialized = 0;
87 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
88 static void __vconf_cb(keynode_t *key, void *data);
90 static int __app_dead_handler(int pid, void *data);
93 extern int _status_init(struct amdmgr* amd);
95 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
96 static int __kill_bg_apps(int limit)
101 r_app_info_t *info_t = NULL;
104 len = g_slist_length(r_app_info_list);
110 for ( i=0, iter = r_app_info_list; i<n ; i++) {
111 info_t = (r_app_info_t *)iter->data;
112 aul_send_app_terminate_request_signal(info_t->pid, NULL, NULL, NULL);
113 _term_app(info_t->pid, 0);
114 iter = g_slist_next(iter);
115 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
122 static int __remove_item_running_list(int pid)
124 r_app_info_t *info_t = NULL;
127 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
129 info_t = (r_app_info_t *)iter->data;
130 if(pid == info_t->pid) {
131 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
139 gboolean __add_item_running_list(gpointer user_data)
143 pkgmgrinfo_appinfo_h handle = NULL;
145 r_app_info_t *info_t = NULL;
150 item_pkt_t *item = (item_pkt_t *)user_data;
155 char* appid = item->appid;
158 SECURE_LOGD("__add_item_running_list pid: %d", pid);
160 if (vconf_get_int(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, &limit) != 0){
161 _E("Unable to get VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS\n");
166 } else if (strncmp(appid, "org.tizen.cluster-home", 24) == 0) {
167 if(limit>0) __kill_bg_apps(limit-1);
171 SECURE_LOGD("__add_item_running_list appid: %s", appid);
173 ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
174 if (ret != PMINFO_R_OK) {
175 _E("pkgmgrinfo_pkginfo_get_pkginfo with %s failed", appid);
179 ret = pkgmgrinfo_appinfo_is_taskmanage(handle, &taskmanage);
180 if (ret != PMINFO_R_OK) {
181 _E("pkgmgrinfo_appinfo_is_taskmanage failed");
185 if (taskmanage == false)
188 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
190 info_t = (r_app_info_t *)iter->data;
191 if(pid == info_t->pid) {
193 r_app_info_list = g_slist_remove(r_app_info_list, info_t);
194 r_app_info_list = g_slist_append(r_app_info_list, info_t);
200 info_t = malloc(sizeof(r_app_info_t));
201 if (info_t == NULL) {
206 strncpy(info_t->pkg_name, appid, MAX_PACKAGE_STR_SIZE-1);
208 r_app_info_list = g_slist_append(r_app_info_list, info_t);
211 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
213 info_t = (r_app_info_t *)iter->data;
216 if(limit>0) __kill_bg_apps(limit);
218 for (iter = r_app_info_list; iter != NULL; iter = g_slist_next(iter))
220 info_t = (r_app_info_t *)iter->data;
224 pkgmgrinfo_appinfo_destroy_appinfo(handle);
228 static void __vconf_cb(keynode_t *key, void *data)
233 name = vconf_keynode_get_name(key);
236 }else if ( strcmp(name, VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS) == 0){
237 limit = vconf_keynode_get_int(key);
238 if(limit>0) __kill_bg_apps(limit);
243 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
244 static int __tep_unmount_dbus(char *mnt_path)
247 msg = dbus_message_new_method_call(TEP_BUS_NAME, TEP_OBJECT_PATH,
248 TEP_INTERFACE_NAME, TEP_UNMOUNT_METHOD);
250 _E("dbus_message_new_method_call(%s:%s-%s)", TEP_OBJECT_PATH,
251 TEP_INTERFACE_NAME, TEP_UNMOUNT_METHOD);
255 if (!dbus_message_append_args(msg,
256 DBUS_TYPE_STRING, &mnt_path,
257 DBUS_TYPE_INVALID)) {
258 _E("Ran out of memory while constructing args\n");
259 dbus_message_unref(msg);
263 if (dbus_connection_send(conn, msg, NULL) == FALSE) {
264 _E("dbus send error");
265 dbus_message_unref(msg);
268 dbus_message_unref(msg);
272 static void __send_unmount_request(int pid)
274 const char *tep_name = NULL;
275 const struct appinfo *ai = NULL;
277 appid = _status_app_get_appid_bypid(pid);
279 _E("_status_app_get_appid_bypid : appid not found");
282 ai = appinfo_find(_laf, appid);
283 tep_name = appinfo_get_value(ai, AIT_TEP);
284 if (tep_name != NULL) {
285 char tep_message[PATH_MAX] = {0, };
286 const char *installed_storage = NULL;
287 char *mnt_path = NULL;
288 struct stat link_buf;
290 installed_storage = appinfo_get_value(ai, AIT_STORAGE_TYPE);
291 if (installed_storage != NULL) {
292 if (strncmp(installed_storage, "internal", 8) == 0) {
293 snprintf(tep_message, sizeof(tep_message), "%s%s/res/tep", appfw_env_get_apps_path(), appid);
294 mnt_path = strdup(tep_message);
295 } else if (strncmp(installed_storage, "external", 8) == 0) {
296 snprintf(tep_message, sizeof(tep_message), "%step/tep-access", appfw_env_get_external_storage_path());
297 mnt_path = strdup(tep_message);
300 int ret = __tep_unmount_dbus(mnt_path);
302 _E("dbus call failed for unmount");
304 ret = lstat(mnt_path, &link_buf);
306 ret = unlink(mnt_path);
308 _D("Symbolic link removed");
310 _E("Failed to remove the link");
319 static int __app_dead_handler(int pid, void *data)
321 char trm_buf[MAX_PACKAGE_STR_SIZE];
322 char buf[MAX_LOCAL_BUFSZ];
324 _W("__app_dead_handler, pid: %d", pid);
329 #ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
330 __send_unmount_request(pid);
333 if (app_group_is_leader_pid(pid)) {
334 _W("app_group_leader_app, pid: %d", pid);
335 if (app_group_find_second_leader(pid) == -1) {
336 app_group_clear_top(pid);
337 app_group_set_dead_pid(pid);
338 app_group_remove(pid);
340 app_group_remove_leader_pid(pid);
341 } else if (app_group_is_sub_app(pid)) {
342 _W("app_group_sub_app, pid: %d", pid);
343 int caller_pid = app_group_get_next_caller_pid(pid);
345 if (app_group_can_reroute(pid) || (caller_pid > 0 && caller_pid != pid)) {
346 _W("app_group reroute");
347 app_group_reroute(pid);
349 _W("app_group clear top");
350 app_group_clear_top(pid);
352 app_group_set_dead_pid(pid);
353 app_group_remove(pid);
356 app_group_remove_from_recycle_bin(pid);
358 _unregister_key_event(pid);
359 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
360 __remove_item_running_list(pid);
362 _revoke_temporary_permission(pid);
363 _status_remove_app_info_list(pid);
364 snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_terminated:[PID]%d", pid);
365 __trm_app_info_send_socket(trm_buf);
366 aul_send_app_terminated_signal(pid);
368 snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, pid);
371 #ifdef _APPFW_FEATURE_AMD_MODULE_LOG
372 snprintf(buf, MAX_LOCAL_BUFSZ, "%d", pid);
373 _status_log_save("TERMINATED", buf);
379 static void __start_cb(void *user_data,
380 const char *filename, const struct appinfo *ai)
382 /*struct amdmgr *amd = user_data;*/
383 const char *componet = NULL;
386 componet = appinfo_get_value(ai, AIT_COMPTYPE);
388 r = appinfo_get_boolean(ai, AIT_ONBOOT);
390 if (r == 1 && componet && strncmp(componet, "svcapp", 6) == 0)
392 const char *appid = appinfo_get_value(ai, AIT_NAME);
393 #ifdef _APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
394 r = appinfo_get_boolean(ai, AIT_PRELOAD);
395 if (ups_mode == SETTING_PSMODE_EMERGENCY && r == 0) {
396 _W("In UPS mode, skip to launch the servce apps");
400 if (appid && _status_app_is_running(appid) < 0)
402 _W("start service (on-boot) - %s", appid);
407 _E("service: %s is already running", appid);
412 static void _start_services(struct amdmgr *amd)
414 #ifdef _APPFW_FEATURE_ULTRA_POWER_SAVING_MODE
415 if(vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ups_mode) < 0)
416 _E("vconf_get_int() failed");
419 appinfo_foreach(amd->af, __start_cb, amd);
422 gboolean _get_platform_ready()
424 return platform_ready;
427 static gboolean __platform_ready_handler(gpointer data)
429 _E("[Info]__platform_ready_handler");
430 platform_ready = true;
435 static int __booting_done_handler(int pid, void *data)
437 _E("[Info]__booting_done_handler, pid: %d", pid);
439 _start_services((struct amdmgr*)data);
441 guint timer_id = g_timeout_add(60000, __platform_ready_handler, NULL);
442 SECURE_LOGW("[Info] timer_id: %u", timer_id);
447 static void __window_init(void)
454 window_initialized = 1;
457 int _window_is_initialized()
459 return window_initialized;
462 static Eina_Bool _window_cb(void *data, Ecore_Fd_Handler * fd_handler)
465 char buf[FILENAME_MAX] = {0};
467 struct inotify_event* event;
469 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) {
470 _E("An error has occurred. Stop watching this fd and quit");
471 return ECORE_CALLBACK_CANCEL;
474 fd = ecore_main_fd_handler_fd_get(fd_handler);
476 _E("ecore_main_fd_handler_fd_get error");
477 return ECORE_CALLBACK_CANCEL;
479 len = read(fd, buf, FILENAME_MAX);
481 _E("read failed, error [%s]", strerror(errno));;
483 event = (struct inotify_event*) &buf[0];
486 _D("filename : %s", event->name);
488 if (_status_check_window_ready()) {
491 ecore_main_fd_handler_del(win_info_t->win_watch_ewd);
492 inotify_rm_watch(win_info_t->watch_fd, win_info_t->win_watch_wd);
498 return ECORE_CALLBACK_RENEW;
501 static void _register_window_init(void)
503 _W("_register_window_init");
505 win_info_t = malloc(sizeof(_window_watch_t));
507 _E("Unable to allocate memory. don't init widow\n");
510 win_info_t->watch_fd = inotify_init();
511 win_info_t->win_watch_wd = inotify_add_watch(win_info_t->watch_fd, "/tmp", IN_CREATE);
512 win_info_t->win_watch_ewd = ecore_main_fd_handler_add(win_info_t->watch_fd,
513 ECORE_FD_READ, _window_cb, NULL, NULL, NULL);
516 static void _window_init(void)
518 if (_status_check_window_ready())
521 _register_window_init();
529 /* sigprocmask() is used to fetch and/or change the signal mask of the calling thread.
530 * As a result, please make sure that there are not any other threads except for calling thread.
532 int fd = _signal_block_sigchld();
539 _W("ecore init done\n");
541 ret = appinfo_init(&amd.af);
544 ret = _request_init(&amd, fd);
552 _W("AMD init done\n");
554 #ifdef _APPFW_FEATURE_BG_PROCESS_LIMIT
555 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS, __vconf_cb, NULL) != 0) {
556 _E("Unable to register callback for VCONFKEY_SETAPPL_DEVOPTION_BGPROCESS\n");
560 aul_listen_app_dead_signal(__app_dead_handler, NULL);
561 aul_listen_booting_done_signal(__booting_done_handler, &amd);
563 #ifdef _APPFW_FEATURE_PRIORITY_CHANGE
564 int res = setpriority(PRIO_PROCESS, 0, -12);
567 _E("Setting process (%d) priority to -12 failed, errno: %d (%s)",
568 getpid(), errno, strerror(errno));
574 gboolean __amd_ready(gpointer user_data)
578 int handle = creat("/tmp/amd_ready", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
585 int main(int argc, char *argv[])
589 #ifdef _APPFW_FEATURE_APP_CHECKER
590 if (ac_server_initialize() != AC_R_OK){
591 _E("ac_server_initialize failed!\n");
598 _E("AMD Initialization failed!\n");
602 g_idle_add(__amd_ready, NULL);
604 ecore_main_loop_begin();