From ff13ab088da23745b48825037e92fae637f03427 Mon Sep 17 00:00:00 2001 From: hyunuktak Date: Wed, 12 Jul 2017 13:53:50 +0900 Subject: [PATCH] Added background restriction for data saver Change-Id: I8bb5ae5c54affe6cf1c6bd35e4952b45cac04173 Signed-off-by: hyunuktak --- include/stc-manager.h | 1 + include/stc-restriction.h | 2 +- interfaces/stcmanager-iface-restriction.xml | 2 +- src/helper/helper-cgroup.c | 5 ++ src/helper/helper-cgroup.h | 8 +- src/helper/helper-net-cls.c | 7 +- src/monitor/include/stc-monitor.h | 1 + src/monitor/stc-application-lifecycle.c | 4 +- src/monitor/stc-monitor.c | 110 +++++++++++++++++++++++++--- src/stc-manager-gdbus.c | 4 +- src/stc-restriction.c | 2 +- 11 files changed, 126 insertions(+), 20 deletions(-) diff --git a/include/stc-manager.h b/include/stc-manager.h index ac8ecb4..c82c3af 100755 --- a/include/stc-manager.h +++ b/include/stc-manager.h @@ -24,6 +24,7 @@ #define NET_CLS_SUBSYS "net_cls" #define STC_BACKGROUND_APP_SUFFIX "_BACKGROUND" +#define STC_BACKGROUND_APP_ID "BACKGROUND" #define STC_TOTAL_DATACALL "TOTAL_DATACALL" #define STC_TOTAL_WIFI "TOTAL_WIFI" #define STC_TOTAL_BLUETOOTH "TOTAL_BLUETOOTH" diff --git a/include/stc-restriction.h b/include/stc-restriction.h index 219dad8..acd4eab 100755 --- a/include/stc-restriction.h +++ b/include/stc-restriction.h @@ -67,7 +67,7 @@ gboolean handle_restriction_get_state(StcRestriction *object, int iftype, void *user_data); -gboolean handle_restriction_remove(StcRestriction *object, +gboolean handle_restriction_unset(StcRestriction *object, GDBusMethodInvocation *invocation, GVariant *parameters, void *user_data); diff --git a/interfaces/stcmanager-iface-restriction.xml b/interfaces/stcmanager-iface-restriction.xml index 6ccc381..f4baf76 100644 --- a/interfaces/stcmanager-iface-restriction.xml +++ b/interfaces/stcmanager-iface-restriction.xml @@ -28,7 +28,7 @@ - + diff --git a/src/helper/helper-cgroup.c b/src/helper/helper-cgroup.c index a725dcc..af9f1f1 100755 --- a/src/helper/helper-cgroup.c +++ b/src/helper/helper-cgroup.c @@ -20,6 +20,8 @@ #define NOTIFY_ON_RELEASE "notify_on_release" #define CGROUP_FILE_NAME "cgroup.procs" +#define CLASSID_FILE_NAME "net_cls.classid" + #define MAX_PATH_LENGTH 512 static int read_uint(FILE *handler, uint32_t *out) @@ -283,6 +285,9 @@ void cgroup_init(void) cgroup_make_subdir(STC_CGROUP_NETWORK, STC_BACKGROUND_CGROUP_NAME, NULL); + cgroup_write_node_uint32(BACKGROUND_CGROUP_NETWORK, + CLASSID_FILE_NAME, STC_BACKGROUND_APP_CLASSID); + /* create foreground cgroup directory */ cgroup_make_subdir(STC_CGROUP_NETWORK, STC_FOREGROUND_CGROUP_NAME, NULL); diff --git a/src/helper/helper-cgroup.h b/src/helper/helper-cgroup.h index a358066..273036c 100755 --- a/src/helper/helper-cgroup.h +++ b/src/helper/helper-cgroup.h @@ -31,12 +31,12 @@ #define DEFAULT_CGROUP "/sys/fs/cgroup" #define CGROUP_NETWORK DEFAULT_CGROUP "/net_cls" #define STC_CGROUP_NETWORK CGROUP_NETWORK "/stc" -#define BACKGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/background" -#define FOREGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/foreground" +#define BACKGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/BACKGROUND" +#define FOREGROUND_CGROUP_NETWORK STC_CGROUP_NETWORK "/FOREGROUND" #define PROC_TASK_CHILDREN "/proc/%d/task/%d/children" #define STC_CGROUP_NAME "stc" -#define STC_BACKGROUND_CGROUP_NAME "background" -#define STC_FOREGROUND_CGROUP_NAME "foreground" +#define STC_BACKGROUND_CGROUP_NAME "BACKGROUND" +#define STC_FOREGROUND_CGROUP_NAME "FOREGROUND" /** * @desc Get one unsigned int32 value from cgroup diff --git a/src/helper/helper-net-cls.c b/src/helper/helper-net-cls.c index 5f653fc..1c22608 100755 --- a/src/helper/helper-net-cls.c +++ b/src/helper/helper-net-cls.c @@ -94,6 +94,9 @@ uint32_t get_classid_by_app_id(const char *app_id, int create) return STC_UNKNOWN_CLASSID; } + if (!strcmp(app_id, STC_BACKGROUND_APP_ID)) + return STC_BACKGROUND_APP_CLASSID; + if (!strcmp(app_id, STC_TOTAL_DATACALL)) return STC_TOTAL_DATACALL_CLASSID; @@ -150,7 +153,9 @@ stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id) return STC_ERROR_INVALID_PARAMETER; } - if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) + if (!strcmp(app_id, STC_BACKGROUND_APP_ID)) + path_to_net_cgroup_dir = STC_CGROUP_NETWORK; + else if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX)) path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK; else path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; diff --git a/src/monitor/include/stc-monitor.h b/src/monitor/include/stc-monitor.h index 09871d5..56d87e2 100755 --- a/src/monitor/include/stc-monitor.h +++ b/src/monitor/include/stc-monitor.h @@ -100,6 +100,7 @@ typedef struct { gboolean rstns_tree_updated; GTree *apps; /**< monitored applications */ gboolean apps_tree_updated; + guint background_state; } stc_system_s; /** diff --git a/src/monitor/stc-application-lifecycle.c b/src/monitor/stc-application-lifecycle.c index a0fb931..ee82320 100755 --- a/src/monitor/stc-application-lifecycle.c +++ b/src/monitor/stc-application-lifecycle.c @@ -91,6 +91,7 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd, stc_monitor_process_add(app_key, proc_key, proc_value); stc_monitor_process_update_ground(app_key, proc_key, STC_APP_STATE_FOREGROUND); + FREE(app_key.pkg_id); FREE(app_key.app_id); break; @@ -108,7 +109,8 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd, memset(&proc_value, 0, sizeof(stc_process_value_s)); app_key.pkg_id = g_strdup(pkg_id); - app_key.app_id = g_strdup(app_id); + app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX, + NULL); app_value.type = app_type; app_value.processes = NULL; diff --git a/src/monitor/stc-monitor.c b/src/monitor/stc-monitor.c index a65f6d2..2bb1777 100755 --- a/src/monitor/stc-monitor.c +++ b/src/monitor/stc-monitor.c @@ -15,6 +15,8 @@ */ #include +#include +#include #include "stc-default-connection.h" #include "helper-nl.h" @@ -28,6 +30,7 @@ #include "stc-manager-plugin.h" #define MAX_INT_LENGTH 128 +#define VCONFKEY_STC_BACKGROUND_STATE "db/stc/background_state" typedef struct { stc_app_key_s *app_key; @@ -1259,7 +1262,7 @@ static void __add_rstns_for_application(gchar *app_id) app_id); } -static void __stc_monitor_add_application_by_interface(const char *app_id) +static void __add_application_by_interface(const char *app_id) { stc_app_key_s app_key; stc_app_value_s app_value; @@ -1284,6 +1287,78 @@ static void __stc_monitor_add_application_by_interface(const char *app_id) FREE(app_key.app_id); } +static int __vconf_get_int(const char *key, int *value) +{ + int ret = 0; + + ret = vconf_get_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to get vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +static int __vconf_set_int(const char *key, int value) +{ + int ret = 0; + + ret = vconf_set_int(key, value); + if (ret != VCONF_OK) { + STC_LOGE("Failed to set vconfkey [%s] value", key); + return -1; + } + + return 0; +} + +static guint __get_background_state(void) +{ + return g_system->background_state;; +} + +static void __set_background_state(guint state) +{ + g_system->background_state = state; +} + +static gboolean __processes_tree_foreach_background(gpointer key, gpointer value, + gpointer data) +{ + stc_process_key_s *proc_key = (stc_process_key_s *)key; + stc_process_value_s *proc_value = (stc_process_value_s *)value; + stc_app_key_s *app_key = (stc_app_key_s *)data; + + if (g_system->background_state) + place_pids_to_net_cgroup(proc_key->pid, STC_BACKGROUND_APP_ID); + else + place_pids_to_net_cgroup(proc_key->pid, app_key->app_id); + + return FALSE; +} + +static gboolean __apps_tree_foreach_background(gpointer key, gpointer value, + gpointer data) +{ + stc_app_key_s *app_key = (stc_app_key_s *)key; + stc_app_value_s *app_value = (stc_app_value_s *)value; + + if (strstr(app_key->app_id, STC_BACKGROUND_APP_SUFFIX)) + g_tree_foreach(app_value->processes, __processes_tree_foreach_background, app_key); + + return FALSE; +} + +static stc_error_e __process_update_background(void) +{ + ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!"); + + g_tree_foreach(g_system->apps, __apps_tree_foreach_background, NULL); + + return STC_ERROR_NONE; +} + stc_error_e stc_monitor_init(void) { stc_system_s *system = MALLOC0(stc_system_s, 1); @@ -1320,9 +1395,9 @@ stc_error_e stc_monitor_init(void) g_system = system; - __stc_monitor_add_application_by_interface(STC_TOTAL_DATACALL); - __stc_monitor_add_application_by_interface(STC_TOTAL_WIFI); - __stc_monitor_add_application_by_interface(STC_TOTAL_BLUETOOTH); + __add_application_by_interface(STC_TOTAL_DATACALL); + __add_application_by_interface(STC_TOTAL_WIFI); + __add_application_by_interface(STC_TOTAL_BLUETOOTH); /* creating restriction rules tree */ __update_contr_cb(NULL); @@ -1337,6 +1412,8 @@ stc_error_e stc_monitor_init(void) return STC_ERROR_FAIL; } + __vconf_get_int(VCONFKEY_STC_BACKGROUND_STATE, &g_system->background_state); + __fill_restritions_list(); return STC_ERROR_NONE; @@ -1519,11 +1596,14 @@ stc_error_e stc_monitor_process_update_ground(const stc_app_key_s app_key, proc_lookup->ground = ground; if (ground == STC_APP_STATE_BACKGROUND) { - char *background_app_id = g_strconcat(app_key.app_id, - STC_BACKGROUND_APP_SUFFIX, - NULL); - place_pids_to_net_cgroup(proc_key.pid, background_app_id); - g_free(background_app_id); + if (__get_background_state()) { + place_pids_to_net_cgroup(proc_key.pid, STC_BACKGROUND_APP_ID); + } else { + char *background_app_id = g_strconcat(app_key.app_id, + STC_BACKGROUND_APP_SUFFIX, NULL); + place_pids_to_net_cgroup(proc_key.pid, background_app_id); + g_free(background_app_id); + } } else { place_pids_to_net_cgroup(proc_key.pid, app_key.app_id); } @@ -1594,6 +1674,12 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info) else value.classid = STC_UNKNOWN_CLASSID; + if (value.classid == STC_BACKGROUND_APP_CLASSID) { + __set_background_state(TRUE); + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); + __process_update_background(); + } + value.data_limit = info->data_limit; value.data_warn_limit = info->data_warn_limit; @@ -1617,6 +1703,12 @@ stc_error_e stc_monitor_rstns_tree_remove(const table_restrictions_info *info) .roaming = info->roaming, }; + if (!strcmp(key.app_id, STC_BACKGROUND_APP_ID)) { + __set_background_state(FALSE); + __vconf_set_int(VCONFKEY_STC_BACKGROUND_STATE, g_system->background_state); + __process_update_background(); + } + ret = __rstn_tree_remove(&key); FREE(key.app_id); diff --git a/src/stc-manager-gdbus.c b/src/stc-manager-gdbus.c index 5b3cc71..3bd6659 100755 --- a/src/stc-manager-gdbus.c +++ b/src/stc-manager-gdbus.c @@ -113,8 +113,8 @@ static gboolean __stc_manager_gdbus_restriction_init(stc_s *stc) G_CALLBACK(handle_restriction_get_state), stc); - g_signal_connect(restriction, "handle-remove", - G_CALLBACK(handle_restriction_remove), stc); + g_signal_connect(restriction, "handle-unset", + G_CALLBACK(handle_restriction_unset), stc); /* Export the object (@manager takes its own reference to @object) */ g_dbus_object_manager_server_export(stc->obj_mgr, diff --git a/src/stc-restriction.c b/src/stc-restriction.c index aa8ed4e..8550e41 100755 --- a/src/stc-restriction.c +++ b/src/stc-restriction.c @@ -295,7 +295,7 @@ gboolean handle_restriction_exclude(StcRestriction *object, return TRUE; } -gboolean handle_restriction_remove(StcRestriction *object, +gboolean handle_restriction_unset(StcRestriction *object, GDBusMethodInvocation *invocation, GVariant *parameters, void *user_data) -- 2.7.4