Manage loader slot state 54/171354/12
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 2 Mar 2018 02:07:18 +0000 (11:07 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 7 Mar 2018 05:19:47 +0000 (14:19 +0900)
Adds new attributes of loader for managing loader slot state:
 - TTL (minutes): Denote timeout value for DEACTIVATION_METHOD.
 - ACTIVATION_METHOD: REQUEST and AVAILABLE_MEMORY methods are available.
 - DEACTIVATION_METHOD: TTL and OUT_OF_MEMORY methods are available.

After this patch is applied, loaders are managed by two states(running or paused).
When the loader is paused, the launchpad cannot make candidate process.
And, if the candidate process is running, it will be disposed.

Change-Id: I7de4f28e513aefb022a51f30e974d7f481053bdd
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
inc/loader_info.h
src/launchpad.c
src/loader_info.c

index 5a7e298..3e650af 100644 (file)
 #include <glib.h>
 #include <bundle.h>
 
-#define METHOD_TIMEOUT         0x1
-#define METHOD_VISIBILITY      0x2
-#define METHOD_DEMAND          0x4
-
 #define DEFAULT_CPU_THRESHOLD_MAX              90
 #define DEFAULT_CPU_THRESHOLD_MIN              40
 
+enum loader_method_e {
+       METHOD_TIMEOUT = 0x0001,
+       METHOD_VISIBILITY = 0x0002,
+       METHOD_DEMAND = 0x0004,
+       METHOD_REQUEST = 0x0010,
+       METHOD_AVAILABLE_MEMORY = 0x0020,
+       METHOD_TTL = 0x0040,
+       METHOD_OUT_OF_MEMORY = 0x0100,
+};
+
 typedef struct _loader_info {
        int type;
        char *name;
@@ -42,6 +48,9 @@ typedef struct _loader_info {
        bool on_boot;
        bool global;
        bool app_exists;
+       int activation_method;
+       int deactivation_method;
+       unsigned int ttl;
 } loader_info_t;
 
 typedef void (*loader_info_foreach_cb)(loader_info_t *info, void *data);
index 175e503..ae0def3 100755 (executable)
 #define CPU_CHECKER_TIMEOUT            1000
 #define PI                             3.14159265
 
+enum candidate_process_state_e {
+       CANDIDATE_PROCESS_STATE_RUNNING,
+       CANDIDATE_PROCESS_STATE_PAUSED,
+};
+
 typedef struct {
        int type;
        bool prepared;
@@ -88,6 +93,11 @@ typedef struct {
        bool on_boot;
        bool app_exists;
        bool touched;
+       int activation_method;
+       int deactivation_method;
+       unsigned int ttl;
+       guint live_timer;
+       int state;
 } candidate_process_context_t;
 
 typedef struct {
@@ -120,16 +130,22 @@ static GList *candidate_slot_list;
 static app_labels_monitor *label_monitor;
 static GList *launcher_info_list;
 static GHashTable *__pid_table;
+static int __memory_status;
 
 static candidate_process_context_t *__add_slot(int type, int loader_id,
                int caller_pid, const char *loader_path, const char *extra,
-               int detection_method, int timeout_val,
+               int detection_method, int activation_method,
+               int deactivation_method, unsigned int ttl, int timeout_val,
                int threshold_max, int threshold_min, bool on_boot,
                bool app_exists);
 static int __remove_slot(int type, int loader_id);
 static int __add_default_slots(void);
 static gboolean __handle_idle_checker(gpointer data);
 static int __add_idle_checker(int detection_method, GList *cur);
+static void __dispose_candidate_process(candidate_process_context_t *cpc);
+static bool __is_low_memory(void);
+static void __update_slot_state(candidate_process_context_t *cpc, int method);
+static void __set_idle_checker_timer(candidate_process_context_t *cpc);
 
 static int __make_loader_id(void)
 {
@@ -417,6 +433,30 @@ static int __exec_loader_process(void *arg)
        return -1;
 }
 
+static gboolean __handle_deactivate_event(gpointer user_data)
+{
+       candidate_process_context_t *cpc;
+
+       cpc = (candidate_process_context_t *)user_data;
+       __update_slot_state(cpc, METHOD_TTL);
+       _D("Deactivate event: type(%d)", cpc->type);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void __set_live_timer(candidate_process_context_t *cpc)
+{
+       if (!cpc)
+               return;
+
+       if (cpc->deactivation_method & METHOD_TTL) {
+               if (cpc->live_timer == 0) {
+                       cpc->live_timer = g_timeout_add_seconds(cpc->ttl,
+                                       __handle_deactivate_event, cpc);
+               }
+       }
+}
+
 static int __prepare_candidate_process(int type, int loader_id)
 {
        int pid;
@@ -450,39 +490,49 @@ static int __prepare_candidate_process(int type, int loader_id)
        }
 
        cpt->pid = pid;
+       __set_live_timer(cpt);
 
        return 0;
 }
 
-static gboolean __handle_timeout_event(gpointer user_data)
+static void __set_idle_checker_timer(candidate_process_context_t *cpc)
 {
-       candidate_process_context_t *cpc;
        unsigned long long total = 0;
        unsigned long long idle = 0;
 
-       cpc = (candidate_process_context_t *)user_data;
-       cpc->timer = 0;
-
        if (cpc->idle_checker > 0)
-               return G_SOURCE_REMOVE;
+               return;
 
        _get_cpu_idle(&total, &idle);
        cpc->cpu_idle_time = idle;
        cpc->cpu_total_time = total;
-       _D("Add idle checker");
        cpc->idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT,
                                __handle_idle_checker,
                                g_list_find(candidate_slot_list, cpc));
+       _D("Add idle checker: type(%d)", cpc->type);
+}
 
+static gboolean __handle_timeout_event(gpointer user_data)
+{
+       candidate_process_context_t *cpc;
+
+       cpc = (candidate_process_context_t *)user_data;
+       cpc->timer = 0;
+
+       if (cpc->idle_checker > 0)
+               return G_SOURCE_REMOVE;
+
+       __set_idle_checker_timer(cpc);
        return G_SOURCE_REMOVE;
 }
 
 static void __set_timer(candidate_process_context_t *cpc)
 {
-       if (cpc == NULL)
+       if (cpc == NULL || cpc->timer > 0)
                return;
 
-       if (cpc->detection_method & METHOD_TIMEOUT) {
+       if ((cpc->detection_method & METHOD_TIMEOUT) &&
+                       cpc->state == CANDIDATE_PROCESS_STATE_RUNNING) {
                cpc->timer = g_timeout_add(cpc->timeout_val,
                                __handle_timeout_event, cpc);
        }
@@ -499,6 +549,30 @@ static void __reset_slot(candidate_process_context_t *cpc)
        cpc->source = 0;
        cpc->timer = 0;
        cpc->idle_checker = 0;
+       cpc->live_timer = 0;
+}
+
+static void __dispose_candidate_process(candidate_process_context_t *cpc)
+{
+       if (!cpc)
+               return;
+
+       _D("Dispose candidate process %d", cpc->type);
+       if (cpc->pid > 0) {
+               _D("kill process %d", cpc->pid);
+               __kill_process(cpc->pid);
+       }
+       if (cpc->live_timer > 0)
+               g_source_remove(cpc->live_timer);
+       if (cpc->source > 0)
+               g_source_remove(cpc->source);
+       if (cpc->timer > 0)
+               g_source_remove(cpc->timer);
+       if (cpc->idle_checker > 0)
+               g_source_remove(cpc->idle_checker);
+       if (cpc->send_fd > 0)
+               close(cpc->send_fd);
+       __reset_slot(cpc);
 }
 
 static int __send_launchpad_loader(candidate_process_context_t *cpc,
@@ -516,17 +590,8 @@ static int __send_launchpad_loader(candidate_process_context_t *cpc,
                cpc->pid, app_path);
 
        pid = cpc->pid;
-
-       if (cpc->send_fd > 0)
-               close(cpc->send_fd);
-       if (cpc->source > 0)
-               g_source_remove(cpc->source);
-       if (cpc->timer > 0)
-               g_source_remove(cpc->timer);
-       if (cpc->idle_checker > 0)
-               g_source_remove(cpc->idle_checker);
-
-       __reset_slot(cpc);
+       cpc->pid = CANDIDATE_NONE;
+       __dispose_candidate_process(cpc);
        __set_timer(cpc);
        return pid;
 }
@@ -997,17 +1062,9 @@ static gboolean __handle_loader_client_event(gpointer data)
                SECURE_LOGE("Type %d candidate process was " \
                                "(POLLHUP|POLLNVAL), pid: %d",
                                cpc->type, cpc->pid);
-               if (cpc->send_fd > 0)
-                       close(cpc->send_fd);
-               if (cpc->timer > 0)
-                       g_source_remove(cpc->timer);
-               if (cpc->idle_checker > 0)
-                       g_source_remove(cpc->idle_checker);
-
-               __reset_slot(cpc);
-
+               cpc->pid = CANDIDATE_NONE;
+               __dispose_candidate_process(cpc);
                __prepare_candidate_process(cpc->type, cpc->loader_id);
-
                return G_SOURCE_REMOVE;
        }
 
@@ -1080,7 +1137,8 @@ static gboolean __handle_sigchild(gpointer data)
 
                cpc = __find_slot_from_pid(siginfo.ssi_pid);
                if (cpc != NULL) {
-                       __reset_slot(cpc);
+                       cpc->pid = CANDIDATE_NONE;
+                       __dispose_candidate_process(cpc);
                        __prepare_candidate_process(cpc->type, cpc->loader_id);
                }
 
@@ -1105,17 +1163,7 @@ static gboolean __handle_label_monitor(gpointer data)
        while (iter) {
                cpc = (candidate_process_context_t *)iter->data;
                if (cpc->pid > 0) {
-                       if (cpc->source > 0)
-                               g_source_remove(cpc->source);
-                       if (cpc->timer > 0)
-                               g_source_remove(cpc->timer);
-                       if (cpc->idle_checker > 0)
-                               g_source_remove(cpc->idle_checker);
-                       if (cpc->send_fd > 0)
-                               close(cpc->send_fd);
-                       _D("Dispose candidate process %d", cpc->pid);
-                       __kill_process(cpc->pid);
-                       __reset_slot(cpc);
+                       __dispose_candidate_process(cpc);
                        __prepare_candidate_process(cpc->type, cpc->loader_id);
                }
 
@@ -1199,11 +1247,13 @@ static int __add_idle_checker(int detection_method, GList *cur)
 {
        candidate_process_context_t *cpc;
        GList *iter = cur;
-       unsigned long long total = 0;
-       unsigned long long idle = 0;
 
        while (iter) {
                cpc = (candidate_process_context_t *)iter->data;
+               if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING) {
+                       iter = g_list_next(iter);
+                       continue;
+               }
 
                if (strcmp("null", cpc->loader_path) == 0) {
                        iter = g_list_next(iter);
@@ -1229,13 +1279,8 @@ static int __add_idle_checker(int detection_method, GList *cur)
                        }
 
                        if (cpc->idle_checker == 0) {
-                               _get_cpu_idle(&total, &idle);
-                               cpc->cpu_idle_time = idle;
-                               cpc->cpu_total_time = total;
                                cpc->cur_event = detection_method;
-                               cpc->idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT,
-                                               __handle_idle_checker, iter);
-                               _D("Add Idler checker");
+                               __set_idle_checker_timer(cpc);
                                return 0;
                        }
                }
@@ -1271,7 +1316,11 @@ static int __dispatch_cmd_add_loader(bundle *kb)
                lid = __make_loader_id();
                cpc = __add_slot(LAUNCHPAD_TYPE_DYNAMIC, lid, atoi(caller_pid),
                                add_slot_str, extra,
-                               METHOD_TIMEOUT | METHOD_VISIBILITY, 2000,
+                               METHOD_TIMEOUT | METHOD_VISIBILITY,
+                               METHOD_REQUEST | METHOD_AVAILABLE_MEMORY,
+                               METHOD_TTL | METHOD_OUT_OF_MEMORY,
+                               600,
+                               2000,
                                DEFAULT_CPU_THRESHOLD_MAX,
                                DEFAULT_CPU_THRESHOLD_MIN,
                                false,
@@ -1372,8 +1421,6 @@ static candidate_process_context_t *__find_available_slot(const char *hwacc,
 static void __update_slot(int type, bool app_exists)
 {
        candidate_process_context_t *cpc;
-       unsigned long long total = 0;
-       unsigned long long idle = 0;
 
        cpc = __find_slot(type, PAD_LOADER_ID_STATIC);
        if (!cpc)
@@ -1381,20 +1428,12 @@ static void __update_slot(int type, bool app_exists)
 
        cpc->app_exists = app_exists;
        if (!cpc->app_exists) {
-               if (cpc->pid > 0) {
-                       if (cpc->source > 0)
-                               g_source_remove(cpc->source);
-                       if (cpc->timer > 0)
-                               g_source_remove(cpc->timer);
-                       if (cpc->idle_checker > 0)
-                               g_source_remove(cpc->idle_checker);
-                       if (cpc->send_fd > 0)
-                               close(cpc->send_fd);
-                       _D("Dispose candidate process %d", cpc->pid);
-                       __kill_process(cpc->pid);
-                       __reset_slot(cpc);
-               }
+               if (cpc->pid > 0)
+                       __dispose_candidate_process(cpc);
        } else {
+               if (cpc->state != CANDIDATE_PROCESS_STATE_RUNNING)
+                       return;
+
                if (!cpc->touched && !cpc->on_boot)
                        return;
 
@@ -1404,15 +1443,8 @@ static void __update_slot(int type, bool app_exists)
                }
 
                if (cpc->pid == CANDIDATE_NONE &&
-                               cpc->idle_checker == 0) {
-                       _get_cpu_idle(&total, &idle);
-                       cpc->cpu_idle_time = idle;
-                       cpc->cpu_total_time = total;
-                       _D("Add idle checker");
-                       cpc->idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT,
-                                       __handle_idle_checker,
-                                       g_list_find(candidate_slot_list, cpc));
-               }
+                               cpc->idle_checker == 0)
+                       __set_idle_checker_timer(cpc);
        }
 }
 
@@ -1457,6 +1489,37 @@ static int __dispatch_cmd_update_app_type(bundle *b)
        return 0;
 }
 
+static void __update_slot_state(candidate_process_context_t *cpc, int method)
+{
+       if (method == METHOD_OUT_OF_MEMORY) {
+               if ((cpc->deactivation_method & method) && __is_low_memory()) {
+                       cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
+                       __dispose_candidate_process(cpc);
+               } else {
+                       cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
+                       if (!cpc->touched && !cpc->on_boot)
+                               return;
+                       if (!cpc->app_exists || cpc->pid > CANDIDATE_NONE)
+                               return;
+                       if (cpc->detection_method & METHOD_TIMEOUT)
+                               __set_timer(cpc);
+               }
+       } else if (cpc->activation_method & method) {
+               __update_slot_state(cpc, METHOD_OUT_OF_MEMORY);
+       } else if (cpc->deactivation_method & method) {
+               cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
+               __dispose_candidate_process(cpc);
+       } else {
+               cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
+               if (!cpc->touched && !cpc->on_boot)
+                       return;
+               if (!cpc->app_exists || cpc->pid > CANDIDATE_NONE)
+                       return;
+               if (cpc->detection_method & METHOD_TIMEOUT)
+                       __set_timer(cpc);
+       }
+}
+
 static gboolean __handle_launch_event(gpointer data)
 {
        loader_context_t *lc = (loader_context_t *) data;
@@ -1609,6 +1672,7 @@ static gboolean __handle_launch_event(gpointer data)
                                org_cpc->idle_checker = 0;
                        }
 
+                       __update_slot_state(org_cpc, METHOD_REQUEST);
                        __set_timer(org_cpc);
                }
        } else {
@@ -1644,7 +1708,9 @@ end:
 static candidate_process_context_t *__add_slot(int type, int loader_id,
                int caller_pid, const char *loader_path,
                const char *loader_extra, int detection_method,
-               int timeout_val, int threshold_max, int threshold_min,
+               int activation_method, int deactivation_method,
+               unsigned int ttl, int timeout_val,
+               int threshold_max, int threshold_min,
                bool on_boot, bool app_exists)
 {
        candidate_process_context_t *cpc;
@@ -1682,6 +1748,16 @@ static candidate_process_context_t *__add_slot(int type, int loader_id,
        cpc->app_exists = app_exists;
        cpc->touched = false;
        cpc->cur_event = 0;
+       cpc->activation_method = activation_method;
+       cpc->deactivation_method = deactivation_method;
+       cpc->ttl = ttl;
+       cpc->live_timer = 0;
+
+       if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) &&
+                       __is_low_memory())
+               cpc->state = CANDIDATE_PROCESS_STATE_PAUSED;
+       else
+               cpc->state = CANDIDATE_PROCESS_STATE_RUNNING;
 
        fd = __listen_candidate_process(cpc->type, cpc->loader_id);
        if (fd == -1) {
@@ -1714,15 +1790,7 @@ static int __remove_slot(int type, int loader_id)
        while (iter) {
                cpc = (candidate_process_context_t *)iter->data;
                if (type == cpc->type && loader_id == cpc->loader_id) {
-                       if (cpc->pid > 0)
-                               __kill_process(cpc->pid);
-                       if (cpc->timer > 0)
-                               g_source_remove(cpc->timer);
-                       if (cpc->source > 0)
-                               g_source_remove(cpc->source);
-                       if (cpc->idle_checker > 0)
-                               g_source_remove(cpc->idle_checker);
-
+                       __dispose_candidate_process(cpc);
                        candidate_slot_list = g_list_delete_link(
                                        candidate_slot_list, iter);
                        free(cpc->loader_path);
@@ -1875,7 +1943,8 @@ static void __add_slot_from_info(gpointer data, gpointer user_data)
        if (!strcmp(info->exe, "null")) {
                cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset,
                                PAD_LOADER_ID_DIRECT,
-                               0, info->exe, NULL, 0, 0,
+                               0, info->exe, NULL,
+                               0, 0, 0, 0, 0,
                                info->cpu_threshold_max,
                                info->cpu_threshold_min,
                                false,
@@ -1898,7 +1967,11 @@ static void __add_slot_from_info(gpointer data, gpointer user_data)
                cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset,
                                PAD_LOADER_ID_STATIC,
                                0, info->exe, (char *)extra,
-                               info->detection_method, info->timeout_val,
+                               info->detection_method,
+                               info->activation_method,
+                               info->deactivation_method,
+                               info->ttl,
+                               info->timeout_val,
                                info->cpu_threshold_max,
                                info->cpu_threshold_min,
                                info->on_boot,
@@ -1927,15 +2000,17 @@ static int __add_default_slots(void)
        return 0;
 }
 
-static void __vconf_cb(keynode_t *key, void *data)
+static bool __is_low_memory(void)
 {
-       const char *name;
+       if (__memory_status >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
+               return true;
+       return false;
+}
 
-       name = vconf_keynode_get_name(key);
-       if (name && strcmp(name, VCONFKEY_SETAPPL_APP_HW_ACCELERATION) == 0) {
-               __sys_hwacc = vconf_keynode_get_int(key);
-               _D("sys hwacc: %d", __sys_hwacc);
-       }
+static void __hw_acceleration_changed_cb(keynode_t *key, void *data)
+{
+       __sys_hwacc = vconf_keynode_get_int(key);
+       _D("sys hwacc: %d", __sys_hwacc);
 }
 
 static void __update_lang(keynode_t *node, void *user_data)
@@ -1946,10 +2021,80 @@ static void __update_lang(keynode_t *node, void *user_data)
                setenv("LANG", lang, 1);
 }
 
+static void __memory_status_changed_cb(keynode_t *node, void *data)
+{
+       candidate_process_context_t *cpc;
+       GList *iter = candidate_slot_list;
+
+       __memory_status = vconf_keynode_get_int(node);
+       if (__memory_status >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
+               _W("Low memory");
+               while (iter) {
+                       cpc = (candidate_process_context_t *)iter->data;
+                       __update_slot_state(cpc, METHOD_OUT_OF_MEMORY);
+                       iter = g_list_next(iter);
+               }
+       } else {
+               _W("Normal");
+               while (iter) {
+                       cpc = (candidate_process_context_t *)iter->data;
+                       __update_slot_state(cpc, METHOD_AVAILABLE_MEMORY);
+                       iter = g_list_next(iter);
+               }
+       }
+}
+
+static void __unregister_vconf_events(void)
+{
+       vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
+                       __memory_status_changed_cb);
+       vconf_ignore_key_changed(VCONFKEY_LANGSET,
+                       __update_lang);
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
+                       __hw_acceleration_changed_cb);
+}
+
+static int __register_vconf_events(void)
+{
+       int r;
+       char *lang;
+
+       r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
+       if (r != VCONF_OK)
+               _E("Failed to get vconf hw acceleration. err = %d", r);
+
+       r = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
+                       __hw_acceleration_changed_cb, NULL);
+       if (r != VCONF_OK) {
+               _E("Failed to register callback for hw acceleration. err = %d",
+                               r);
+       }
+
+       lang = vconf_get_str(VCONFKEY_LANGSET);
+       if (lang) {
+               setenv("LANG", lang, 1);
+               free(lang);
+       }
+
+       r = vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, NULL);
+       if (r != VCONF_OK)
+               _E("Failed to register callback for langset. err = %d", r);
+
+       r = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &__memory_status);
+       if (r != VCONF_OK)
+               _E("Failed to get vconf low memory. err = %d", r);
+
+       r = vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY,
+                       __memory_status_changed_cb, NULL);
+       if (r != 0)
+               _E("Failed to register callback for low memory. err = %d", r);
+
+       return 0;
+}
+
 static int __before_loop(int argc, char **argv)
 {
        int ret;
-       char *lang;
 
        ret = __init_sigchild_fd();
        if (ret != 0) {
@@ -1963,29 +2108,6 @@ static int __before_loop(int argc, char **argv)
                return -1;
        }
 
-       ret = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
-       if (ret != VCONF_OK) {
-               _E("Failed to get vconf int: %s",
-                               VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
-       }
-
-       ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION,
-                       __vconf_cb, NULL);
-       if (ret != 0) {
-               _E("Failed to register callback for %s",
-                               VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
-       }
-
-       lang = vconf_get_str(VCONFKEY_LANGSET);
-       if (lang) {
-               setenv("LANG", lang, 1);
-               free(lang);
-       }
-
-       ret = vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, NULL);
-       if (ret != 0)
-               _E("Failed to register callback for %s", VCONFKEY_LANGSET);
-
        ret = __init_label_monitor_fd();
        if (ret != 0)
                _W("Failed to initialize label monitor");
@@ -2004,11 +2126,14 @@ static int __before_loop(int argc, char **argv)
                return -1;
        }
 
+       __register_vconf_events();
+
        return 0;
 }
 
 static void __after_loop(void)
 {
+       __unregister_vconf_events();
        if (__pid_table)
                g_hash_table_destroy(__pid_table);
 
index e48ffef..2150119 100644 (file)
 #include "loader_info.h"
 #include "launchpad_common.h"
 
-#define TAG_LOADER     "[LOADER]"
-#define TAG_NAME       "NAME"
-#define TAG_EXE                "EXE"
-#define TAG_APP_TYPE   "APP_TYPE"
-#define TAG_DETECTION_METHOD   "DETECTION_METHOD"
-#define TAG_TIMEOUT    "TIMEOUT"
-#define TAG_EXTRA      "EXTRA"
-#define TAG_EXTRA_ARRAY                "EXTRA_ARRAY"
-#define TAG_EXTRA_ARRAY_VAL    "EXTRA_ARRAY_VAL"
-#define TAG_ALTERNATIVE_LOADER "ALTERNATIVE_LOADER"
-#define TAG_HW_ACC             "HW_ACC"
-#define TAG_CPU_THRESHOLD_MAX  "CPU_THRESHOLD_MAX"
-#define TAG_CPU_THRESHOLD_MIN  "CPU_THRESHOLD_MIN"
-#define TAG_ON_BOOT            "ON_BOOT"
-#define VAL_ON                 "ON"
-#define VAL_OFF                        "OFF"
-#define VAL_METHOD_TIMEOUT     "TIMEOUT"
-#define VAL_METHOD_DEMAND      "DEMAND"
-#define VAL_METHOD_VISIBILITY  "VISIBILITY"
-
+#define TAG_LOADER                     "[LOADER]"
+#define TAG_NAME                       "NAME"
+#define TAG_EXE                                "EXE"
+#define TAG_APP_TYPE                   "APP_TYPE"
+#define TAG_DETECTION_METHOD           "DETECTION_METHOD"
+#define TAG_ACTIVATION_METHOD          "ACTIVATION_METHOD"
+#define TAG_DEACTIVATION_METHOD                "DEACTIVATION_METHOD"
+#define TAG_TTL                                "TTL"
+#define TAG_TIMEOUT                    "TIMEOUT"
+#define TAG_EXTRA                      "EXTRA"
+#define TAG_EXTRA_ARRAY                        "EXTRA_ARRAY"
+#define TAG_EXTRA_ARRAY_VAL            "EXTRA_ARRAY_VAL"
+#define TAG_ALTERNATIVE_LOADER         "ALTERNATIVE_LOADER"
+#define TAG_HW_ACC                     "HW_ACC"
+#define TAG_CPU_THRESHOLD_MAX          "CPU_THRESHOLD_MAX"
+#define TAG_CPU_THRESHOLD_MIN          "CPU_THRESHOLD_MIN"
+#define TAG_ON_BOOT                    "ON_BOOT"
+
+#define VAL_ON                         "ON"
+#define VAL_OFF                                "OFF"
+#define VAL_METHOD_TIMEOUT             "TIMEOUT"
+#define VAL_METHOD_DEMAND              "DEMAND"
+#define VAL_METHOD_VISIBILITY          "VISIBILITY"
+#define VAL_METHOD_REQUEST             "REQUEST"
+#define VAL_METHOD_AVAILABLE_MEMORY    "AVAILABLE_MEMORY"
+#define VAL_METHOD_TTL                 "TTL"
+#define VAL_METHOD_OUT_OF_MEMORY       "OUT_OF_MEMORY"
 
 static loader_info_t *__create_loader_info()
 {
@@ -68,6 +75,9 @@ static loader_info_t *__create_loader_info()
        info->cpu_threshold_min = DEFAULT_CPU_THRESHOLD_MIN;
        info->on_boot = true;
        info->app_exists = false;
+       info->activation_method = 0;
+       info->deactivation_method = 0;
+       info->ttl = 600; /* 10 minutes */
 
        return info;
 }
@@ -93,6 +103,44 @@ static void __parse_detection_method(loader_info_t *info, char *line)
        _D("detection_method:%d", info->detection_method);
 }
 
+static void __parse_activation_method(loader_info_t *info, char *line)
+{
+       char *token;
+       char *savedptr;
+
+       token = strtok_r(line, " |\t\r\n", &savedptr);
+       info->activation_method = 0;
+       while (token) {
+               if (!strcmp(token, VAL_METHOD_REQUEST))
+                       info->activation_method |= METHOD_REQUEST;
+               else if (!strcmp(token, VAL_METHOD_AVAILABLE_MEMORY))
+                       info->activation_method |= METHOD_AVAILABLE_MEMORY;
+
+               token = strtok_r(NULL, " |\t\r\n", &savedptr);
+       }
+
+       _D("activation_method:%d", info->activation_method);
+}
+
+static void __parse_deactivation_method(loader_info_t *info, char *line)
+{
+       char *token;
+       char *savedptr;
+
+       token = strtok_r(line, " |\t\r\n", &savedptr);
+       info->deactivation_method = 0;
+       while (token) {
+               if (!strcmp(token, VAL_METHOD_TTL))
+                       info->deactivation_method |= METHOD_TTL;
+               else if (!strcmp(token, VAL_METHOD_OUT_OF_MEMORY))
+                       info->deactivation_method |= METHOD_OUT_OF_MEMORY;
+
+               token = strtok_r(NULL, " |\t\r\n", &savedptr);
+       }
+
+       _D("deactivation_method:%d", info->deactivation_method);
+}
+
 static void __parse_app_types(loader_info_t *info, char *line)
 {
        char *token;
@@ -211,6 +259,14 @@ static GList *__parse_file(GList *list, const char *path)
                        __parse_app_types(cur_info, &buf[strlen(tok1)]);
                } else if (strcasecmp(TAG_DETECTION_METHOD, tok1) == 0) {
                        __parse_detection_method(cur_info, &buf[strlen(tok1)]);
+               } else if (strcasecmp(TAG_ACTIVATION_METHOD, tok1) == 0) {
+                       __parse_activation_method(cur_info,
+                                       &buf[strlen(tok1)]);
+               } else if (strcasecmp(TAG_DEACTIVATION_METHOD, tok1) == 0) {
+                       __parse_deactivation_method(cur_info,
+                                       &buf[strlen(tok1)]);
+               } else if (strcasecmp(TAG_TTL, tok1) == 0) {
+                       cur_info->ttl = strtoul(tok2, NULL, 10);
                } else if (strcasecmp(TAG_TIMEOUT, tok1) == 0) {
                        cur_info->timeout_val = atoi(tok2);
                } else if (strcasecmp(TAG_EXTRA, tok1) == 0) {