From ae2b14435be82dc3fb51545d75846d0e8944ec8f Mon Sep 17 00:00:00 2001 From: Kichan Kwon Date: Tue, 16 Aug 2016 16:55:35 +0900 Subject: [PATCH] heart : multi-user logging : implement per-user dat file of HEART-CPU - Similar to DB, dat cache is composed of hash table (key=uid, value=cache) - To distinguish destination, some HEART-CPU dbus methods ask uid Change-Id: I9f703cf054436cf4272d5c2bac5fb95f0803e9fd Signed-off-by: Kichan Kwon --- src/common/heart-common.h | 6 +- src/common/userinfo-list.c | 1 + src/heart/heart-cpu.c | 323 ++++++++++++++++++++++++++++++------------ src/heart/include/heart.h | 1 + src/heart/include/logging.h | 1 + src/heart/logging.c | 31 +++- src/proc-stat/proc-appusage.c | 4 +- 7 files changed, 273 insertions(+), 94 deletions(-) diff --git a/src/common/heart-common.h b/src/common/heart-common.h index 6864c41..b915126 100644 --- a/src/common/heart-common.h +++ b/src/common/heart-common.h @@ -77,9 +77,9 @@ int heart_battery_get_capacity_history_latest(GArray *arrays, int charge, int ma int heart_battery_get_capacity_history(GArray *arrays, enum heart_data_period period); /* cpu */ -int heart_cpu_get_table(GArray *arrays, enum heart_data_period period); -struct heart_cpu_data *heart_cpu_get_data(char *appid, enum heart_data_period period); -int heart_cpu_get_appusage_list(GHashTable *lists, int top); +int heart_cpu_get_table(int uid, GArray *arrays, enum heart_data_period period); +struct heart_cpu_data *heart_cpu_get_data(int uid, char *appid, enum heart_data_period period); +int heart_cpu_get_appusage_list(int uid, GHashTable *lists, int top); /* memory */ int heart_memory_get_query(GArray *arrays, enum heart_data_period period); diff --git a/src/common/userinfo-list.c b/src/common/userinfo-list.c index cb7945f..27e582f 100644 --- a/src/common/userinfo-list.c +++ b/src/common/userinfo-list.c @@ -57,6 +57,7 @@ resourced_ret_c get_all_users_info(GHashTable **table) if (!users) { _E("Fail to get gum user list"); + g_object_unref(gus); return RESOURCED_ERROR_FAIL; } diff --git a/src/heart/heart-cpu.c b/src/heart/heart-cpu.c index 8752aff..c240e8d 100644 --- a/src/heart/heart-cpu.c +++ b/src/heart/heart-cpu.c @@ -40,6 +40,7 @@ #include "trace.h" #include "module.h" #include "macro.h" +#include "userinfo-list.h" #define PROC_PATH "/proc/%d" #define PROC_STAT_PATH "/proc/%d/stat" @@ -47,7 +48,7 @@ #define CPU_DATA_MAX 1024 #define CPU_ARRAY_MAX 24 #define HEART_CPU_SAVE_INTERVAL 3600 -#define HEART_CPU_DATA_FILE HEART_FILE_PATH"/.cpu.dat" +#define HEART_CPU_DATA_FILE HEART_USER_FILE_PATH"/.cpu.dat" enum { SERVICE = 0, @@ -78,9 +79,15 @@ struct heart_cpu_table { GArray *cpu_info; }; +struct heart_cpu_dat_cache { + char *path; + GHashTable *list; + time_t last_file_commit_time; +}; + static GHashTable *heart_cpu_app_list; static pthread_mutex_t heart_cpu_mutex = PTHREAD_MUTEX_INITIALIZER; -static time_t last_file_commit_time; +static GHashTable *user_table = NULL; static void heart_cpu_remove_last_pid_info_exited(struct heart_cpu_table *table) { @@ -145,6 +152,19 @@ static int heart_cpu_get_cpu_time(pid_t pid, unsigned long *utime, return RESOURCED_ERROR_NONE; } +static GHashTable* heart_cpu_get_user_app_list(int uid) +{ + struct heart_cpu_dat_cache *cache; + + cache = (struct heart_cpu_dat_cache*)g_hash_table_lookup(heart_cpu_app_list, (gconstpointer)&uid); + if (!cache) { + _E("There is no table of uid %d", uid); + return NULL; + } + + return cache->list; +} + static int heart_cpu_write_data(struct proc_status *ps, pid_t pid, int type) { int ret; @@ -279,6 +299,21 @@ static int heart_cpu_update_app_list(void *data) return RESOURCED_ERROR_NONE; } +static void heart_cpu_free_uid(gpointer data) +{ + if (data) + free(data); +} + +static void heart_cpu_free_dat_cache(gpointer data) +{ + struct heart_cpu_dat_cache *cache = (struct heart_cpu_dat_cache*)data; + if (cache) { + free(cache->path); + g_hash_table_destroy(cache->list); + } +} + static void heart_free_value(gpointer value) { struct heart_cpu_table *table = (struct heart_cpu_table *)value; @@ -309,7 +344,7 @@ static int heart_cpu_read_length(char *buf, int count) return RESOURCED_ERROR_FAIL; } -static int heart_cpu_read_from_file(GHashTable *hashtable, char *filename) +static int heart_cpu_read_from_file(struct heart_cpu_dat_cache *cache) { int i, len, ret, fg_count, state; unsigned long total_utime, total_stime; @@ -322,11 +357,35 @@ static int heart_cpu_read_from_file(GHashTable *hashtable, char *filename) char pkgid[MAX_PKGNAME_LENGTH] = {0, }; char buf[CPU_DATA_MAX] = {0, }; - fp = fopen(filename, "r"); + if (!cache) { + _E("Cache doesn't exist"); + return RESOURCED_ERROR_INVALID_PARAMETER; + } + snprintf(buf, CPU_DATA_MAX, HEART_CPU_DATA_FILE, cache->path); + fp = fopen(buf, "r"); if (!fp) { - _E("%s fopen failed %d", filename, errno); - return RESOURCED_ERROR_FAIL; + if (errno != ENOENT) { + _E("Fail to open %s (%d)", buf, errno); + return RESOURCED_ERROR_FAIL; + } + + _D("%s doesn't exist. Make new one.", buf); + snprintf(buf, CPU_DATA_MAX, HEART_USER_FILE_PATH, cache->path); + ret = mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH); + if (ret != 0 && errno != EEXIST) { + _E("Fail to create %s (%d)", buf, errno); + return RESOURCED_ERROR_FAIL; + } + + snprintf(buf, CPU_DATA_MAX, HEART_CPU_DATA_FILE, cache->path); + fp = fopen(buf, "w+"); + if (!fp) { + _E("Fail to create %s (%d)", buf, errno); + return RESOURCED_ERROR_FAIL; + } + fclose(fp); + return RESOURCED_ERROR_NONE; } while (fgets(buf, CPU_DATA_MAX, fp)) { @@ -380,6 +439,7 @@ static int heart_cpu_read_from_file(GHashTable *hashtable, char *filename) table->fg_time = fg_time; table->bg_time = bg_time; table->fg_count = fg_count; + table->last_renew_time = 0; table->cpu_info = g_array_new(FALSE, FALSE, sizeof(struct heart_cpu_info *)); @@ -415,7 +475,7 @@ static int heart_cpu_read_from_file(GHashTable *hashtable, char *filename) fclose(fp); return RESOURCED_ERROR_FAIL; } - g_hash_table_insert(hashtable, (gpointer)table->appid, (gpointer)table); + g_hash_table_insert(cache->list, (gpointer)table->appid, (gpointer)table); ret = pthread_mutex_unlock(&heart_cpu_mutex); if (ret) { _E("pthread_mutex_unlock() failed, %d", ret); @@ -429,7 +489,7 @@ static int heart_cpu_read_from_file(GHashTable *hashtable, char *filename) return RESOURCED_ERROR_NONE; } -static int heart_cpu_save_to_file(GHashTable *hashtable, char *filename) +static int heart_cpu_save_to_file(struct heart_cpu_dat_cache *cache) { int i, len, ret, array_len; gpointer value; @@ -439,19 +499,25 @@ static int heart_cpu_save_to_file(GHashTable *hashtable, char *filename) FILE *fp; char buf[CPU_DATA_MAX] = {0, }; - fp = fopen(filename, "w"); + if (!cache) { + _D("Cache is empty. Do nothing."); + return RESOURCED_ERROR_NONE; + } + + snprintf(buf, CPU_DATA_MAX, HEART_CPU_DATA_FILE, cache->path); + fp = fopen(buf, "w"); if (!fp) { - _E("%s fopen failed %d", filename, errno); + _E("%s fopen failed %d", buf, errno); return RESOURCED_ERROR_FAIL; } - if (!heart_cpu_app_list) { + if (!(cache->list)) { _E("empty app list"); fclose(fp); return RESOURCED_ERROR_FAIL; } - if (!g_hash_table_size(heart_cpu_app_list)) { + if (!g_hash_table_size(cache->list)) { _E("hash table is empty"); fclose(fp); return RESOURCED_ERROR_FAIL; @@ -464,7 +530,7 @@ static int heart_cpu_save_to_file(GHashTable *hashtable, char *filename) return RESOURCED_ERROR_FAIL; } - g_hash_table_iter_init(&iter, hashtable); + g_hash_table_iter_init(&iter, cache->list); while (g_hash_table_iter_next(&iter, &key, &value)) { table = (struct heart_cpu_table *)value; @@ -517,12 +583,12 @@ static int heart_cpu_hashtable_renew(GHashTable *hashtable, time_t now) GHashTableIter iter; struct heart_cpu_table *table; - if (!heart_cpu_app_list) { + if (!hashtable) { _E("empty app list"); return RESOURCED_ERROR_FAIL; } - if (!g_hash_table_size(heart_cpu_app_list)) { + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); return RESOURCED_ERROR_FAIL; } @@ -560,14 +626,33 @@ void heart_cpu_update(struct logging_table_form *data, void *user_data) time_t curr_time = logging_get_time(CLOCK_BOOTTIME); struct heart_cpu_table *table; struct heart_cpu_info *ci = NULL; + struct heart_cpu_dat_cache *cache; GHashTable *cpu_usage_list = NULL; + char *path; - if (user_data) - cpu_usage_list = (GHashTable *)user_data; - else - cpu_usage_list = heart_cpu_app_list; + cache = (struct heart_cpu_dat_cache*)g_hash_table_lookup( + heart_cpu_app_list, (gconstpointer)(&(data->uid))); + if (!cache) { + if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) { + _E("Fail to get user table"); + return; + } + path = (char*)g_hash_table_lookup(user_table, (gconstpointer)(&(data->uid))); + if (!path) { + _E("uid %d doesn't existed", data->uid); + return; + } + cache = (struct heart_cpu_dat_cache*)malloc(sizeof(struct heart_cpu_dat_cache)); + cache->path = strndup((char*)path, strlen((char*)path)); + cache->list = g_hash_table_new_full( + g_str_hash, + g_str_equal, + NULL, + heart_free_value); + } + cpu_usage_list = cache->list; - _D("%s %s %d %s", data->appid, data->pkgid, data->time, data->data); + _D("%d %s %s %d %s", data->uid, data->appid, data->pkgid, data->time, data->data); if (sscanf(data->data, "%lu %lu %d %d ", &utime, &stime, &pid, &state) < 0) { _E("sscanf failed"); return; @@ -683,7 +768,7 @@ void heart_cpu_update(struct logging_table_form *data, void *user_data) return; } - if (last_file_commit_time + HEART_CPU_SAVE_INTERVAL < curr_time) { + if (cache->last_file_commit_time + HEART_CPU_SAVE_INTERVAL < curr_time) { /* all hash table update and make new array */ gpointer value; gpointer key; @@ -724,13 +809,13 @@ void heart_cpu_update(struct logging_table_form *data, void *user_data) return; } /* rewrite hashtable list file */ - ret = heart_cpu_save_to_file(cpu_usage_list, HEART_CPU_DATA_FILE); + ret = heart_cpu_save_to_file(cache); if (ret) { _E("save to file failed"); goto unlock_exit; } - last_file_commit_time = curr_time; + cache->last_file_commit_time = curr_time; } return; @@ -743,11 +828,18 @@ unlock_exit: } } -struct heart_cpu_data *heart_cpu_get_data(char *appid, enum heart_data_period period) +struct heart_cpu_data *heart_cpu_get_data(int uid, char *appid, enum heart_data_period period) { int index, i, ret; struct heart_cpu_table *table; struct heart_cpu_data *data; + GHashTable *hashtable; + + hashtable = heart_cpu_get_user_app_list(uid); + if (!hashtable) { + _E("Fail to get app list"); + return NULL; + } if (!appid) { _E("Wrong arguments!"); @@ -773,12 +865,12 @@ struct heart_cpu_data *heart_cpu_get_data(char *appid, enum heart_data_period pe _E("Wrong message arguments! %d", period); return NULL; } - if (!heart_cpu_app_list) { + if (!hashtable) { _E("empty app list"); return NULL; } - if (!g_hash_table_size(heart_cpu_app_list)) { + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); return NULL; } @@ -788,7 +880,7 @@ struct heart_cpu_data *heart_cpu_get_data(char *appid, enum heart_data_period pe _E("pthread_mutex_lock() failed, %d", ret); return NULL; } - table = g_hash_table_lookup(heart_cpu_app_list, (gconstpointer)appid); + table = g_hash_table_lookup(hashtable, (gconstpointer)appid); if (!table) goto unlock_exit; data = malloc(sizeof(struct heart_cpu_data)); @@ -865,7 +957,7 @@ static double heart_cpu_get_point(int freq, int time) return point; } -int heart_cpu_get_table(GArray *arrays, enum heart_data_period period) +int heart_cpu_get_table(int uid, GArray *arrays, enum heart_data_period period) { int index, i, ret; gpointer value; @@ -873,6 +965,13 @@ int heart_cpu_get_table(GArray *arrays, enum heart_data_period period) GHashTableIter h_iter; struct heart_cpu_table *table; struct heart_cpu_data *cdata; + GHashTable *hashtable; + + hashtable = heart_cpu_get_user_app_list(uid); + if (!hashtable) { + _E("Fail to get app list"); + return RESOURCED_ERROR_FAIL; + } switch (period) { case DATA_LATEST: @@ -895,12 +994,12 @@ int heart_cpu_get_table(GArray *arrays, enum heart_data_period period) return RESOURCED_ERROR_FAIL; } - if (!heart_cpu_app_list) { + if (!hashtable) { _E("empty app list"); return RESOURCED_ERROR_FAIL; } - if (!g_hash_table_size(heart_cpu_app_list)) { + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); return RESOURCED_ERROR_FAIL; } @@ -911,7 +1010,7 @@ int heart_cpu_get_table(GArray *arrays, enum heart_data_period period) return RESOURCED_ERROR_FAIL; } - g_hash_table_iter_init(&h_iter, heart_cpu_app_list); + g_hash_table_iter_init(&h_iter, hashtable); while (g_hash_table_iter_next(&h_iter, &key, &value)) { @@ -971,7 +1070,7 @@ unlock_out_of_memory_exit: return RESOURCED_ERROR_OUT_OF_MEMORY; } -int heart_cpu_get_appusage_list(GHashTable *lists, int top) +int heart_cpu_get_appusage_list(int uid, GHashTable *lists, int top) { int index = top, i, ret; gpointer value; @@ -980,13 +1079,15 @@ int heart_cpu_get_appusage_list(GHashTable *lists, int top) struct heart_cpu_table *table; struct heart_app_usage lau; GArray *app_lists = NULL; + GHashTable *hashtable; - if (!heart_cpu_app_list) { - _E("empty app list"); + hashtable = heart_cpu_get_user_app_list(uid); + if (!hashtable) { + _E("Fail to get app list"); return RESOURCED_ERROR_FAIL; } - if (!g_hash_table_size(heart_cpu_app_list)) { + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); return RESOURCED_ERROR_FAIL; } @@ -998,7 +1099,7 @@ int heart_cpu_get_appusage_list(GHashTable *lists, int top) return RESOURCED_ERROR_FAIL; } - g_hash_table_iter_init(&h_iter, heart_cpu_app_list); + g_hash_table_iter_init(&h_iter, hashtable); while (g_hash_table_iter_next(&h_iter, &key, &value)) { @@ -1056,7 +1157,13 @@ static DBusMessage *edbus_heart_get_cpu_data(E_DBus_Object *obj, DBusMessage *ms DBusMessageIter iter; time_t utime = 0, stime = 0; - ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &appid, DBUS_TYPE_INT32, &period, DBUS_TYPE_INVALID); + int uid; + GHashTable *hashtable; + + ret = dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_STRING, &appid, + DBUS_TYPE_INT32, &period, DBUS_TYPE_INVALID); if (!ret) { _E("Wrong message arguments!"); @@ -1085,12 +1192,14 @@ static DBusMessage *edbus_heart_get_cpu_data(E_DBus_Object *obj, DBusMessage *ms return reply; } - if (!heart_cpu_app_list) { - _E("empty app list"); + hashtable = heart_cpu_get_user_app_list(uid); + if (!hashtable) { + _E("Fail to get app list"); reply = dbus_message_new_method_return(msg); return reply; } - if (!g_hash_table_size(heart_cpu_app_list)) { + + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); reply = dbus_message_new_method_return(msg); return reply; @@ -1105,7 +1214,7 @@ static DBusMessage *edbus_heart_get_cpu_data(E_DBus_Object *obj, DBusMessage *ms return reply; } - table = g_hash_table_lookup(heart_cpu_app_list, (gconstpointer)appid); + table = g_hash_table_lookup(hashtable, (gconstpointer)appid); if (!table) goto unlock_exit; if (period == DATA_LATEST) { @@ -1151,9 +1260,15 @@ static DBusMessage *edbus_heart_get_cpu_data_list(E_DBus_Object *obj, DBusMessag DBusMessageIter arr; char *appid; unsigned long utime, stime, ftime, total; + + int uid; + GHashTable *hashtable; + utime = stime = ftime = total = 0; - ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &period, DBUS_TYPE_INVALID); + ret = dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INT32, &period, DBUS_TYPE_INVALID); if (!ret) { _E("Wrong message arguments!"); @@ -1189,12 +1304,14 @@ static DBusMessage *edbus_heart_get_cpu_data_list(E_DBus_Object *obj, DBusMessag return reply; } - if (!heart_cpu_app_list) { - _E("empty app list"); + hashtable = heart_cpu_get_user_app_list(uid); + if (!hashtable) { + _E("Fail to get app list"); reply = dbus_message_new_method_return(msg); return reply; } - if (!g_hash_table_size(heart_cpu_app_list)) { + + if (!g_hash_table_size(hashtable)) { _E("hash table is empty"); reply = dbus_message_new_method_return(msg); return reply; @@ -1211,7 +1328,7 @@ static DBusMessage *edbus_heart_get_cpu_data_list(E_DBus_Object *obj, DBusMessag return reply; } - g_hash_table_iter_init(&h_iter, heart_cpu_app_list); + g_hash_table_iter_init(&h_iter, hashtable); while (g_hash_table_iter_next(&h_iter, &key, &value)) { DBusMessageIter sub; @@ -1266,31 +1383,24 @@ static DBusMessage *edbus_heart_reset_cpu_data(E_DBus_Object *obj, DBusMessage * { int ret; DBusMessage *reply; - DBusMessageIter iter; + DBusMessageIter iter_msg; - if (!heart_cpu_app_list) { - _E("empty app list"); - reply = dbus_message_new_method_return(msg); - return reply; - } - if (!g_hash_table_size(heart_cpu_app_list)) { - _E("hash table is empty"); - reply = dbus_message_new_method_return(msg); - return reply; - } + GHashTableIter iter_table; + gpointer key, value; - ret = heart_cpu_hashtable_renew(heart_cpu_app_list, time(NULL)); + g_hash_table_iter_init(&iter_table, heart_cpu_app_list); + while (g_hash_table_iter_next(&iter_table, &key, &value)) + ret = heart_cpu_hashtable_renew(((struct heart_cpu_dat_cache*)value)->list, time(NULL)); reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret); + dbus_message_iter_init_append(reply, &iter_msg); + dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_INT32, &ret); return reply; } static DBusMessage *edbus_heart_update_cpu_data(E_DBus_Object *obj, DBusMessage *msg) { - int ret = 0; DBusMessage *reply; DBusMessageIter iter; @@ -1306,25 +1416,34 @@ static DBusMessage *edbus_heart_save_to_file(E_DBus_Object *obj, DBusMessage *ms { int ret; DBusMessage *reply; - DBusMessageIter iter; + DBusMessageIter iter_msg; - ret = heart_cpu_save_to_file(heart_cpu_app_list, HEART_CPU_DATA_FILE); - if (ret) { - _E("save to file failed"); - reply = dbus_message_new_method_return(msg); - return reply; + GHashTableIter iter_table; + gpointer key, value; + struct heart_cpu_dat_cache *cache; + + g_hash_table_iter_init(&iter_table, heart_cpu_app_list); + while (g_hash_table_iter_next(&iter_table, &key, &value)) { + cache = (struct heart_cpu_dat_cache*)value; + ret = heart_cpu_save_to_file(cache); + if (ret) { + _E("save to file failed"); + reply = dbus_message_new_method_return(msg); + return reply; + } + cache->last_file_commit_time = logging_get_time(CLOCK_BOOTTIME); } + reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret); - last_file_commit_time = logging_get_time(CLOCK_BOOTTIME); + dbus_message_iter_init_append(reply, &iter_msg); + dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_INT32, &ret); return reply; } static struct edbus_method edbus_methods[] = { - { "GetCpuData", "si", "ii", edbus_heart_get_cpu_data }, - { "GetCpuDataList", "i", "a(sii)", edbus_heart_get_cpu_data_list }, + { "GetCpuData", "isi", "ii", edbus_heart_get_cpu_data }, + { "GetCpuDataList", "ii", "a(sii)", edbus_heart_get_cpu_data_list }, { "ResetCpuData", NULL, "i", edbus_heart_reset_cpu_data }, { "UpdateCpuData", NULL, "i", edbus_heart_update_cpu_data }, { "SaveCpuData", NULL, "i", edbus_heart_save_to_file }, @@ -1338,25 +1457,50 @@ static int heart_cpu_reset(void *data) static int heart_cpu_init(void *data) { int ret; + GHashTableIter iter; + gpointer key, value; + int *uid; + struct heart_cpu_dat_cache *cache; - ret = logging_module_init(CPU_NAME, ONE_DAY, ONE_MINUTE, heart_cpu_update, ONE_MINUTE, USER_DEFAULT); + ret = logging_module_init(CPU_NAME, ONE_DAY, TEN_MINUTE, heart_cpu_update, TEN_MINUTE, USER_DEFAULT); if (ret != RESOURCED_ERROR_NONE) { _E("logging module init failed"); return RESOURCED_ERROR_FAIL; } + + if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) { + _E("Fail to get user table"); + return RESOURCED_ERROR_FAIL; + } + if (!heart_cpu_app_list) { heart_cpu_app_list = g_hash_table_new_full( - g_str_hash, - g_str_equal, - NULL, - heart_free_value); + g_int_hash, + g_int_equal, + heart_cpu_free_uid, + heart_cpu_free_dat_cache); - /* make hash from file */ - ret = heart_cpu_read_from_file(heart_cpu_app_list, HEART_CPU_DATA_FILE); + g_hash_table_iter_init(&iter, user_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + uid = (int*)malloc(sizeof(int)); + *uid = *((int*)key); + cache = (struct heart_cpu_dat_cache*)malloc(sizeof(struct heart_cpu_dat_cache)); + cache->path = strndup((char*)value, strlen((char*)value)); + cache->list = g_hash_table_new_full( + g_str_hash, + g_str_equal, + NULL, + heart_free_value); + + ret = heart_cpu_read_from_file(cache); + if (ret != RESOURCED_ERROR_NONE) { + _E("heart_cpu_init failed"); + return ret; + } - if (ret == RESOURCED_ERROR_OUT_OF_MEMORY) { - _E("heart_cpu_init failed"); - return ret; + cache->last_file_commit_time = logging_get_time(CLOCK_BOOTTIME); + + g_hash_table_insert(heart_cpu_app_list, (gpointer)uid, (gpointer)cache); } } @@ -1373,14 +1517,16 @@ static int heart_cpu_init(void *data) register_notifier(RESOURCED_NOTIFIER_DATA_UPDATE, heart_cpu_update_app_list); register_notifier(RESOURCED_NOTIFIER_DATA_RESET, heart_cpu_reset); - last_file_commit_time = logging_get_time(CLOCK_BOOTTIME); - _D("heart cpu init finished"); return RESOURCED_ERROR_NONE; } static int heart_cpu_exit(void *data) { + GHashTableIter iter; + gpointer key, value; + struct heart_cpu_dat_cache *cache; + unregister_notifier(RESOURCED_NOTIFIER_SERVICE_LAUNCH, heart_cpu_service_launch); unregister_notifier(RESOURCED_NOTIFIER_APP_FOREGRD, heart_cpu_foreground_state); unregister_notifier(RESOURCED_NOTIFIER_APP_BACKGRD, heart_cpu_background_state); @@ -1388,9 +1534,12 @@ static int heart_cpu_exit(void *data) unregister_notifier(RESOURCED_NOTIFIER_DATA_RESET, heart_cpu_reset); if (heart_cpu_app_list) { - heart_cpu_save_to_file(heart_cpu_app_list, HEART_CPU_DATA_FILE); - if (heart_cpu_app_list) - g_hash_table_destroy(heart_cpu_app_list); + g_hash_table_iter_init(&iter, heart_cpu_app_list); + while (g_hash_table_iter_next(&iter, &key, &value)) { + cache = (struct heart_cpu_dat_cache*)value; + heart_cpu_save_to_file(cache); + } + g_hash_table_destroy(heart_cpu_app_list); } logging_module_exit(); diff --git a/src/heart/include/heart.h b/src/heart/include/heart.h index 2b2c114..2ccf660 100644 --- a/src/heart/include/heart.h +++ b/src/heart/include/heart.h @@ -30,6 +30,7 @@ #define HEART_CONF_FILE_PATH RD_CONFIG_FILE(heart) #define HEART_FILE_PATH RD_SYS_DATA"/heart" +#define HEART_USER_FILE_PATH "%s/data/heart" #define HEART_CONF_SECTION "HEART" struct heart_module_ops { diff --git a/src/heart/include/logging.h b/src/heart/include/logging.h index 969d055..2e269ad 100644 --- a/src/heart/include/logging.h +++ b/src/heart/include/logging.h @@ -51,6 +51,7 @@ #define PID_FOR_ROOT 1 #define UID_FOR_ROOT 0 +#define UID_FOR_OWNER 5001 /* TODO : modify using this macro to support other users */ enum logging_interval { ONE_MINUTE = 60, diff --git a/src/heart/logging.c b/src/heart/logging.c index 8fe6165..3777f29 100644 --- a/src/heart/logging.c +++ b/src/heart/logging.c @@ -1432,20 +1432,47 @@ static Eina_Bool logging_send_signal_to_update(void *data) int ret; DIR *dir_info; + GHashTableIter iter; + gpointer key, value; + char path[128]; + dir_info = opendir(LOGGING_FILE_PATH); if (dir_info) closedir(dir_info); else { - _E("There is no %s", LOGGING_FILE_PATH); + _D("There is no %s. Create new one.", LOGGING_FILE_PATH); ret = mkdir(LOGGING_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH); - if (ret) { _E("mkdir failed %s", LOGGING_FILE_PATH); return ECORE_CALLBACK_RENEW; } } + if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) { + _E("Fail to get user table"); + return ECORE_CALLBACK_RENEW; + } + + g_hash_table_iter_init(&iter, user_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + snprintf(path, 128, HEART_USER_FILE_PATH, (char*)value); + dir_info = opendir(path); + + if (dir_info) + closedir(dir_info); + else { + _D("Make directory %s", path); + ret = mkdir(path, S_IRWXU | S_IRWXG | S_IROTH); + + if (ret) { + _E("mkdir failed %s", path); + return ECORE_CALLBACK_RENEW; + } + } + } + + #ifdef LOGGING_DEBUG _D("logging timer callback function start"); #endif diff --git a/src/proc-stat/proc-appusage.c b/src/proc-stat/proc-appusage.c index 234b47a..f5c6dd9 100644 --- a/src/proc-stat/proc-appusage.c +++ b/src/proc-stat/proc-appusage.c @@ -79,7 +79,7 @@ static Eina_Bool appusage_update_cb(void *data) if (!data) return ECORE_CALLBACK_CANCEL; - ret = heart_cpu_get_appusage_list(apps_htab, favorite_count); + ret = heart_cpu_get_appusage_list(UID_FOR_OWNER, apps_htab, favorite_count); if (!ret) { _I("most_recently_used_list updated"); g_hash_table_foreach(apps_htab, print_favorite_list, NULL); @@ -123,7 +123,7 @@ static int proc_appusage_table_init(void) favorite_count = g_hash_table_size(appusage_favorite_htab); #ifdef HEART_SUPPORT - ret = heart_cpu_get_appusage_list(appusage_favorite_htab, + ret = heart_cpu_get_appusage_list(UID_FOR_OWNER, appusage_favorite_htab, favorite_count); if (!ret) _I("most_recently_used_list updated"); -- 2.7.4