#define JIFFY_TO_MS_FACTOR 10 // 1000 / 100
#define JIFFY_TO_MS(x) ((x) >= UINT_MAX / JIFFY_TO_MS_FACTOR ? UINT_MAX : (x) * JIFFY_TO_MS_FACTOR)
+#define DATA_FROM_2ND_TOKEN "SUBSTR(data, INSTR(data, ' ') + 1)"
+#define SQLITE_QUERY \
+"SELECT" \
+" appid, data," \
+" SUBSTR(data, len_utime + len_stime + 1, len_pid - 1) AS pid" \
+" FROM (SELECT *," \
+" INSTR(data, ' ') AS len_utime," \
+" INSTR(" DATA_FROM_2ND_TOKEN ", ' ') AS len_stime," \
+" INSTR(SUBSTR(" DATA_FROM_2ND_TOKEN ", INSTR(" DATA_FROM_2ND_TOKEN ", ' ') + 1), ' ') AS len_pid" \
+" FROM cpu" \
+" )" \
+" WHERE time BETWEEN %ld AND %ld" \
+" GROUP BY appid, pid" \
+" HAVING MAX(time)"
+
+#define BUF_SIZE 512
+
struct app_status {
- pid_t pid;
- time_t used_time; // utime + stime
+ uint last_used_time; // used_time = utime + stime
+ uint cur_used_time;
};
struct cpu_time {
ENTER;
int ret;
+ char buf[BUF_SIZE];
bm_cpu_st *usage_head = NULL;
bm_cpu_st *usage = NULL;
/* Sqlite */
sqlite3 *db;
sqlite3_stmt *stmt;
- char query[128];
/* DB row */
const char *appid;
unsigned int utime, stime, pid, status;
/* App status */
- struct app_status *app_status, *new_app_status;
+ struct app_status *app_status;
int elapsed;
process_cpu_usage_s *cpu_usage;
GHashTableIter iter;
gpointer g_key, g_val;
+ char *cur_appid;
+ int is_terminated;
/* App time map */
+ GSList *atm_elem;
app_time_map_st1 *app_time_map;
-
/* Check argument */
if (!handle || type != BM_DATA_TYPE_CPU) {
_E("Invalid argument");
_W("g_dbus_connection_send_message_with_reply_sync failed");
}
+ g_object_unref(msg_req);
+
/* Open HEART-CPU DB */
ret = sqlite3_open("/opt/usr/home/owner/.applications/dbspace/.resourced-heart-default.db", &db);
if (ret != SQLITE_OK) {
/* Read data from HEART-CPU DB */
_I("Gather CPU usage : %ld ~ %ld", last_requested_time, current_time);
- snprintf(query, 128, "SELECT appid,data FROM cpu WHERE (time >= %ld AND time < %ld)", last_requested_time, current_time);
- ret = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
+ snprintf(buf, BUF_SIZE, SQLITE_QUERY, last_requested_time, current_time);
+ ret = sqlite3_prepare_v2(db, buf, -1, &stmt, 0);
while (sqlite3_step(stmt) == SQLITE_ROW) {
appid = (const char *)sqlite3_column_text(stmt, 0);
data = (const char *)sqlite3_column_text(stmt, 1);
//_D("appid(%s), utime(%u), stime(%u), pid(%u), status(%u)", appid, utime, stime, pid, status);
- /* Ignore terminated app */
- if (!is_running_app(appid)) {
- _D("%s is already terminated", appid);
- g_hash_table_remove(running_app_list, appid);
- continue;
- }
-
- app_status = g_hash_table_lookup(running_app_list, appid);
+ snprintf(buf, BUF_SIZE, "%s %u", appid, pid);
+ app_status = g_hash_table_lookup(running_app_list, buf);
/* Insert newly launched app in the running app list */
if (!app_status) {
- _D("%s is newly launched", appid);
- new_app_status = malloc(sizeof(struct app_status));
- if (!new_app_status) {
+ _D("%s(PID=%u) is newly launched", appid, pid);
+ app_status = malloc(sizeof(struct app_status));
+ if (!app_status) {
_E("malloc failed");
ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
goto clean_atm;
}
- new_app_status->pid = pid;
- new_app_status->used_time = JIFFY_TO_MS(utime + stime);
- g_hash_table_insert(running_app_list, g_strdup(appid), new_app_status);
+ app_status->last_used_time = 0;
+ app_status->cur_used_time = JIFFY_TO_MS(utime + stime);
+ g_hash_table_insert(running_app_list, g_strdup(buf), app_status);
continue;
}
- /* Initialize restarted app */
- if (app_status->pid != pid) {
- _D("%s is restarted", appid);
- app_status->pid = pid;
- app_status->used_time = JIFFY_TO_MS(utime + stime);
- continue;
- }
-
- /* Ignore CPU unused app */
- elapsed = JIFFY_TO_MS(utime + stime) - app_status->used_time;
- if (elapsed <= 0) {
- _D("%s doesn't use CPU. Ignore it", appid);
- continue;
- }
-
- _D("%s uses CPU (+%d ms)", appid, elapsed);
-
- /* Insert the app using CPU in the ATM list */
- if (!g_slist_find_custom(usage->atm_list, appid, find_app_time)) {
- app_time_map = malloc(sizeof(app_time_map_st1));
- if (!app_time_map) {
- _E("malloc failed");
- ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
- goto clean_atm;
- }
- app_time_map->app_id = g_strdup(appid);
- if (!app_time_map->app_id) {
- _E("g_strdup failed");
- ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
- goto clean_atm;
- }
- app_time_map->time = elapsed;
- usage->atm_list = g_slist_append(usage->atm_list, app_time_map);
- }
-
/* Update app status */
- app_status->used_time += elapsed;
+ app_status->cur_used_time = JIFFY_TO_MS(utime + stime);
}
/* Update all running apps with current value */
g_hash_table_iter_init(&iter, running_app_list);
while (g_hash_table_iter_next(&iter, &g_key, &g_val)) {
- appid = (const char *)g_key;
+ data = (const char *)g_key;
app_status = (struct app_status *)g_val;
-
- /* Ignore terminated app */
- if (!is_running_app(appid)) {
- _D("%s is already terminated", appid);
- g_hash_table_iter_remove(&iter);
- continue;
+ is_terminated = 0;
+ sscanf(data, "%s %u", buf, &pid);
+
+ /* Check whether app is running */
+ ret = app_manager_get_app_id(pid, &cur_appid);
+ switch (ret) {
+ case APP_MANAGER_ERROR_NONE:
+ if (strncmp(buf, cur_appid, strlen(cur_appid) + 1))
+ is_terminated = 1;
+ free(cur_appid);
+ break;
+ default:
+ is_terminated = 1;
+ break;
}
- /* Get latest CPU time */
- ret = runtime_info_get_process_cpu_usage(&app_status->pid, 1, &cpu_usage);
- if (ret != RUNTIME_INFO_ERROR_NONE) {
- _E("runtime_info_get_process_cpu_usage for %u failed(%d)", app_status->pid, ret);
- continue;
+ if (!is_terminated) {
+ /* Get latest CPU time */
+ ret = runtime_info_get_process_cpu_usage((int *)&pid, 1, &cpu_usage);
+ if (ret == RUNTIME_INFO_ERROR_NONE) {
+ app_status->cur_used_time = JIFFY_TO_MS(cpu_usage->utime + cpu_usage->stime);
+ free(cpu_usage);
+ } else
+ _W("runtime_info_get_process_cpu_usage for %u failed(%d)", pid, ret);
}
/* Ignore CPU unused app */
- elapsed = JIFFY_TO_MS(cpu_usage->utime + cpu_usage->stime) - app_status->used_time;
- free(cpu_usage);
+ elapsed = app_status->cur_used_time - app_status->last_used_time;
if (elapsed <= 0) {
- _D("%s doesn't use CPU. Ignore it", appid);
+ _D("%s(PID=%u) doesn't use CPU. Ignore it", buf, pid);
continue;
}
- _D("%s uses CPU (+%d ms)", appid, elapsed);
+ _I("%s(PID=%u) uses CPU (+%d ms)", buf, pid, elapsed);
/* Insert the app using CPU in the ATM list */
- if (!g_slist_find_custom(usage->atm_list, appid, find_app_time)) {
+ atm_elem = g_slist_find_custom(usage->atm_list, buf, find_app_time);
+ if (atm_elem)
+ app_time_map = atm_elem->data;
+ else {
app_time_map = malloc(sizeof(app_time_map_st1));
if (!app_time_map) {
_E("malloc failed");
ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
goto clean_atm;
}
- app_time_map->app_id = g_strdup(appid);
+ app_time_map->app_id = g_strdup(buf);
if (!app_time_map->app_id) {
_E("g_strdup failed");
ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
goto clean_atm;
}
- app_time_map->time = elapsed;
+ app_time_map->time = 0;
usage->atm_list = g_slist_append(usage->atm_list, app_time_map);
}
- app_status->used_time += elapsed;
+ app_time_map->time += elapsed;
+
+ /* Remove terminated app's status */
+ if (is_terminated) {
+ _D("%s(PID=%u) is already terminated", buf, pid);
+ g_hash_table_iter_remove(&iter);
+ } else
+ app_status->last_used_time = app_status->cur_used_time;
}
/* Update last requested time */
#define BATTERY_WIFI_TIME_LEVEL_2 "time_level_2"
#define BATTERY_WIFI_TIME_LEVEL_3 "time_level_3"
#define BATTERY_WIFI_TIME_LEVEL_4 "time_level_4"
+#define BATTERY_WIFI_RX_TIME "rx_time"
+#define BATTERY_WIFI_TX_TIME "tx_time"
#define BATTERY_WIFI_START_TIME "start_time"
#define BATTERY_WIFI_END_TIME "end_time"
#define BATTERY_WIFI_SCAN_TIME "scan_time"
wifi_data->time_level_3 = g_variant_get_uint32(value);
} else if (!g_strcmp0(key, BATTERY_WIFI_TIME_LEVEL_4)) {
wifi_data->time_level_4 = g_variant_get_uint32(value);
+ } else if (!g_strcmp0(key, BATTERY_WIFI_RX_TIME)) {
+ wifi_data->rxTime = g_variant_get_uint32(value);
+ } else if (!g_strcmp0(key, BATTERY_WIFI_TX_TIME)) {
+ wifi_data->txTime = g_variant_get_uint32(value);
} else if (!g_strcmp0(key, BATTERY_WIFI_START_TIME)) {
wifi_data->startTime = g_variant_get_uint32(value);
} else if (!g_strcmp0(key, BATTERY_WIFI_END_TIME)) {
GSList *atm_list = NULL;
GSList *data_list = NULL;
- _D("wifi start[%ld] end[%ld] scan[%d] rssi[%d/%d/%d/%d/%d]",
+ _D("wifi start[%ld] end[%ld] scan[%d] rssi[%d/%d/%d/%d/%d] rx[%d] tx[%d]",
wifi_data->startTime, wifi_data->endTime, wifi_data->scanTime,
wifi_data->time_level_0, wifi_data->time_level_1, wifi_data->time_level_2,
- wifi_data->time_level_3, wifi_data->time_level_4);
+ wifi_data->time_level_3, wifi_data->time_level_4, wifi_data->rxTime, wifi_data->txTime);
for (atm_list = wifi_data->atm_list; atm_list != NULL; atm_list = atm_list->next) {
app_time_map_st2 *app_data = (app_time_map_st2 *)atm_list->data;