tizen 2.3 release
[framework/system/deviced.git] / src / logd / src / liblogd-db / proc-stat.c
1 #include <errno.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "db.h"
6 #include "proc-stat.h"
7 #include "macro.h"
8 #include "socket-helper.h"
9
10 #define UPDATE_PROC_STAT_SQL "REPLACE INTO proc_power_cons \
11         (appid, power_cons, duration, day) VALUES(?, ?, ?, ?)"
12 #define LOAD_PROC_STAT_SQL "SELECT * FROM proc_power_cons WHERE day=?"
13 #define DELETE_OLD_POWER_CONS "DELETE FROM proc_power_cons WHERE day=?"
14
15 static sqlite3 *db;
16 static sqlite3_stmt *update_proc_stat_stmt;
17 static sqlite3_stmt *load_proc_stat_stmt;
18 static sqlite3_stmt *delete_old_power_cons_stmt;
19
20 API int proc_stat_init(void)
21 {
22         db = logd_get_db();
23
24         PREPARE_STMT(update_proc_stat_stmt, UPDATE_PROC_STAT_SQL);
25         PREPARE_STMT(load_proc_stat_stmt, LOAD_PROC_STAT_SQL);
26         PREPARE_STMT(delete_old_power_cons_stmt, DELETE_OLD_POWER_CONS);
27
28         return 0;
29 }
30
31 API int proc_stat_finalize(void)
32 {
33         FINALIZE_STMT(load_proc_stat_stmt);
34         FINALIZE_STMT(update_proc_stat_stmt);
35         FINALIZE_STMT(delete_old_power_cons_stmt);
36
37         return 0;
38 }
39
40 API int foreach_proc_power_cons(enum logd_db_query (*cb)
41         (const struct proc_power_cons *pc, void *user_data), int day, void *user_data)
42 {
43         enum logd_db_query res;
44
45         DB_CHECK(sqlite3_reset(load_proc_stat_stmt));
46         DB_CHECK(sqlite3_bind_int(load_proc_stat_stmt, 1, day));
47         while (sqlite3_step(load_proc_stat_stmt) == SQLITE_ROW) {
48                 struct proc_power_cons pc;
49
50                 pc.appid = strdup((const char*)
51                         sqlite3_column_text(load_proc_stat_stmt, 0));
52                 if (!pc.appid) {
53                         _E("strdup failed");
54                         return -ENOMEM;
55                 }
56                 pc.power_cons = sqlite3_column_int64(load_proc_stat_stmt, 1);
57                 pc.duration = sqlite3_column_int(load_proc_stat_stmt, 2);
58                 res = cb(&pc, user_data);
59                 free((void*)pc.appid);
60                 if (res == LOGD_DB_QUERY_STOP)
61                         break;
62         }
63
64         return 0;
65 }
66
67
68 API int logd_foreach_apps_energy_efficiency(enum logd_db_query (*cb)
69         (const char *application, float efficiency, void *user_data), void *user_data)
70 {
71         enum logd_db_query res;
72
73         DB_CHECK(sqlite3_reset(load_proc_stat_stmt));
74         while (sqlite3_step(load_proc_stat_stmt) == SQLITE_ROW) {
75                 struct proc_power_cons pc;
76                 float efficiency = -1;
77
78                 pc.appid = strdup((const char*)
79                         sqlite3_column_text(load_proc_stat_stmt, 0));
80                 if (!pc.appid) {
81                         _E("strdup failed");
82                         return -ENOMEM;
83                 }
84                 pc.power_cons = sqlite3_column_int64(load_proc_stat_stmt, 1);
85                 pc.duration = sqlite3_column_int(load_proc_stat_stmt, 2);
86                 if (pc.duration >= 2 * 60 * 60) /* 2 hours */
87                         efficiency = ((float)pc.power_cons) / pc.duration;
88                 res = cb(pc.appid, efficiency * 60 * 60, user_data);
89                 free((void*)pc.appid);
90                 if (res == LOGD_DB_QUERY_STOP)
91                         break;
92         }
93
94         return 0;
95 }
96
97
98 API int update_proc_power_cons(struct proc_power_cons *pc, int day)
99 {
100         DB_CHECK(sqlite3_reset(update_proc_stat_stmt));
101         DB_CHECK(sqlite3_bind_text(update_proc_stat_stmt, 1, pc->appid, -1,
102                 SQLITE_STATIC));
103         DB_CHECK(sqlite3_bind_int64(update_proc_stat_stmt, 2, pc->power_cons));
104         DB_CHECK(sqlite3_bind_int(update_proc_stat_stmt, 3, pc->duration));
105         DB_CHECK(sqlite3_bind_int(update_proc_stat_stmt, 4, day));
106
107         if (sqlite3_step(update_proc_stat_stmt) != SQLITE_DONE) {
108                 _E("Failed to record to proc_stat table");
109                 return -1;
110         }
111
112         return 0;
113 }
114
115 API int logd_foreach_proc_stat(enum logd_db_query (*cb)
116         (const struct logd_proc_stat *, void *), void *user_data)
117 {
118         int ret = 0;
119         int count;
120         int sock;
121         struct logd_proc_stat proc_stat;
122         enum logd_socket_req_type req_type = LOGD_PROC_STAT_REQ;
123
124         if ((sock = connect_to_logd_socket()) < 0) {
125                 return sock;
126         }
127
128         if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
129                 ret = -errno;
130                 _E("Can'r write req_type");
131                 goto out;
132         }
133
134         if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
135                 ret = -errno;
136                 _E("Can't read count");
137                 goto out;
138         }
139
140         for (int i = 0; i < count; ++i) {
141                 int length;
142                 char buf[FILENAME_MAX] = { 0, };
143                 if (read_from_socket(sock, &length, sizeof(length)) != sizeof(length)) {
144                         ret = -errno;
145                         _E("Can't read len");
146                         goto out;
147                 }
148
149                 if (read_from_socket(sock, buf, length) != length) {
150                         ret = -errno;
151                         _E("recv failed");
152                         goto out;
153                 }
154                 proc_stat.application = strdup(buf);
155                 if (read_from_socket(sock, &proc_stat.utime, sizeof(proc_stat.utime)) !=
156                         sizeof(proc_stat.utime)) {
157                         ret = -errno;
158                         _E("recv failed");
159                         goto out;
160                 }
161
162                 if (read_from_socket(sock, &proc_stat.stime, sizeof(proc_stat.stime)) !=
163                         sizeof(proc_stat.stime)) {
164                         ret = -errno;
165                         _E("recv failed");
166                 }
167
168                 if (read_from_socket(sock, &proc_stat.utime_power_cons, sizeof(proc_stat.utime_power_cons)) !=
169                         sizeof(proc_stat.utime_power_cons)) {
170                         ret = -errno;
171                         _E("recv failed");
172                         goto out;
173                 }
174
175                 if (read_from_socket(sock, &proc_stat.stime_power_cons, sizeof(proc_stat.stime_power_cons)) !=
176                         sizeof(proc_stat.stime_power_cons)) {
177                         ret = -errno;
178                         _E("recv failed");
179                         goto out;
180                 }
181
182                 if (read_from_socket(sock, &proc_stat.is_active, sizeof(proc_stat.is_active)) !=
183                         sizeof(proc_stat.is_active)) {
184                         ret = -errno;
185                         _E("recv failed");
186                         goto out;
187                 }
188
189                 ret = cb(&proc_stat, user_data);
190                 free(proc_stat.application);
191                 if (ret == LOGD_DB_QUERY_STOP) {
192                         break;
193                 }
194         }
195
196 out:
197         close(sock);
198         return ret;
199 }
200
201 API int delete_old_power_cons(int day)
202 {
203         DB_CHECK(sqlite3_reset(delete_old_power_cons_stmt));
204         DB_CHECK(sqlite3_bind_int(delete_old_power_cons_stmt, 1, day));
205
206         if (sqlite3_step(delete_old_power_cons_stmt) != SQLITE_DONE) {
207                 _E("Failed to record to proc_stat table");
208                 return -1;
209         }
210
211         return 0;
212 }