10 #include "socket-helper.h"
12 #define STORE_POWER_CONS_SQL "INSERT INTO device_working_time \
13 (time_stamp, device, time) VALUES(?, ?, ?); "
15 #define STORE_POWER_MODE_SQL "INSERT INTO power_mode \
16 (time_stamp, old_mode_number, new_mode_number, duration, battery_level_change) \
17 VALUES (?, ?, ?, ?, ?); "
19 #define LOAD_POWER_MODE_STAT_SQL "SELECT * FROM power_mode WHERE \
20 old_mode_number=? order by id DESC;"
22 #define MIN_BATTERY_LEVEL 0
23 #define MAX_BATTERY_LEVEL 10000
25 static int device_state[LOGD_OBJECT_MAX] = { 0, };
28 static sqlite3_stmt *store_power_cons_stmt;
29 static sqlite3_stmt *store_power_mode_stmt;
30 static sqlite3_stmt *load_power_mode_stat_stmt;
32 int devices_init(void)
36 PREPARE_STMT(store_power_cons_stmt, STORE_POWER_CONS_SQL);
37 PREPARE_STMT(store_power_mode_stmt, STORE_POWER_MODE_SQL);
38 PREPARE_STMT(load_power_mode_stat_stmt, LOAD_POWER_MODE_STAT_SQL);
43 int devices_finalize(void)
45 FINALIZE_STMT(store_power_cons_stmt);
46 FINALIZE_STMT(store_power_mode_stmt);
47 FINALIZE_STMT(load_power_mode_stat_stmt);
52 int logd_store_device_wt(uint64_t time_stamp, enum logd_object device, time_t _time)
54 DB_CHECK(sqlite3_reset(store_power_cons_stmt));
55 DB_CHECK(sqlite3_bind_int64(store_power_cons_stmt, 1, time_stamp));
56 DB_CHECK(sqlite3_bind_int(store_power_cons_stmt, 2, device));
57 DB_CHECK(sqlite3_bind_int(store_power_cons_stmt, 3, _time));
59 if (sqlite3_step(store_power_cons_stmt) != SQLITE_DONE) {
60 _E("Can't store device workingtime: %s", sqlite3_errmsg(db));
67 API int store_devices_workingtime(enum logd_object device, int state)
69 static time_t last_time = 0;
70 time_t current_time = time(NULL);
73 for (size_t i = 0; i < ARRAY_SIZE(device_state); ++i) {
75 logd_store_device_wt(current_time, i, current_time - last_time);
79 device_state[device] = state;
80 last_time = current_time;
85 API int logd_foreach_devices_stat(enum logd_db_query (*cb)
86 (const struct logd_device_stat *, void *), void *user_data)
92 struct logd_device_stat dev_stat;
93 enum logd_socket_req_type req_type = LOGD_DEV_STAT_REQ;
95 if ((sock = connect_to_logd_socket()) < 0) {
96 _E("Failed connect_to_logd_socket");
100 if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
102 _E("can't write to socket");
106 if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
108 _E("can't read from socket");
112 for (i = 0; i < count; ++i) {
113 if (read_from_socket(sock, &dev_stat, sizeof(dev_stat)) != sizeof(dev_stat)) {
115 _E("can't read from socket");
118 if (cb(&dev_stat, user_data) == LOGD_DB_QUERY_STOP)
127 API int logd_get_estimate_battery_lifetime(int **estimate_times)
131 enum logd_socket_req_type req_type = LOGD_EST_TIME_REQ;
134 (*estimate_times) = (int*)calloc(LOGD_POWER_MODE_MAX, sizeof(int));
135 if (!(*estimate_times)) {
136 _E("can't alloc memory");
140 if ((sock = connect_to_logd_socket()) < 0) {
141 _E("Failed connect_to_logd_socket");
142 free((*estimate_times));
146 if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
148 _E("can't write to socket");
149 free((*estimate_times));
153 for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
156 if (read_from_socket(sock, &est_time, sizeof(est_time)) != sizeof(est_time)) {
158 _E("can't read from socket");
159 free((*estimate_times));
162 (*estimate_times)[i] = est_time;
171 API struct logd_battery_info* logd_get_battery_info(void)
176 enum logd_socket_req_type req_type = LOGD_BATTERY_LVL_REQ;
178 struct logd_battery_info *info = NULL;
180 if ((sock = connect_to_logd_socket()) < 0) {
181 _E("Failed connect_to_logd_socket");
185 if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
186 _E("can't write to socket");
190 if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
191 _E("can't read from socket");
196 _E("wrong count value");
200 info = (struct logd_battery_info*) calloc(1, sizeof(struct logd_battery_info));
202 info->levels = (struct logd_battery_level*)
203 malloc(sizeof(struct logd_battery_level) * count);
205 for (i = 0; i < count; ++i) {
206 if (read_from_socket(
207 sock, info->levels + i, sizeof(struct logd_battery_level)) !=
208 sizeof(struct logd_battery_level)) {
209 _E("can't read from socket");
220 logd_free_battery_info(info);
224 API int logd_seek_battery_level(struct logd_battery_info *info, int level)
228 if (level < MIN_BATTERY_LEVEL || level > MAX_BATTERY_LEVEL
232 for (i = info->n - 1; i >= 0; --i) {
233 if (info->levels[i].level == level)
240 API void logd_free_battery_info(struct logd_battery_info *info)
250 API float logd_battery_level_at(const struct logd_battery_info *info, time_t date)
253 struct logd_battery_level *bl = NULL;
255 if (!info || !info->levels)
258 if (date < info->levels[0].date) {
259 _E("logd_battery_info not contains info at %ld", date);
263 for (i = 0; i < info->n; ++i) {
264 bl = &info->levels[i];
266 if (i == info->n - 1)
268 if (date >= bl->date && date < info->levels[i + 1].date)
272 return bl->level + (date - bl->date) * bl->k;
275 API float logd_battery_charging_speed_at(const struct logd_battery_info *info, time_t date)
279 if (!info || !info->levels)
282 if (date < info->levels[0].date) {
283 _E("logd_battery_info not contains info at %ld", date);
287 for (i = 0; i < info->n - 1; ++i) {
288 if (date >= info->levels[i].date && date < info->levels[i + 1].date)
291 if (i != 0 && i == info->n - 1)
294 return info->levels[i].k;
297 API int get_current_battery_level()
300 const char *level_file = "/sys/class/power_supply/battery/capacity";
302 FILE *fp = fopen(level_file, "r");
306 _E("can't open %s", level_file);
310 if (fscanf(fp, "%d", &level) != 1) {
313 _E("Can't read battery level");
319 return level > MAX_BATTERY_LEVEL ? MAX_BATTERY_LEVEL : level;
322 API float* load_discharging_speed(int long_period)
324 float *result = NULL;
327 if (sqlite3_reset(load_power_mode_stat_stmt) != SQLITE_OK) {
328 _E("sqlite3_reset failed");
332 result = (float*)calloc(LOGD_POWER_MODE_MAX, sizeof(float));
336 for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
337 int total_duration = 0;
338 float total_battery_level_change = 0;
340 if (sqlite3_reset(load_power_mode_stat_stmt) != SQLITE_OK) {
341 _E("load_power_mode_stat_stmt reset error");
346 if (sqlite3_bind_int(load_power_mode_stat_stmt, 1, i) != SQLITE_OK) {
347 _E("load_power_mode_stat_stmt bind error");
352 while (sqlite3_step(load_power_mode_stat_stmt) == SQLITE_ROW) {
353 int duration = sqlite3_column_int(load_power_mode_stat_stmt, 3);
354 int battery_level_change = sqlite3_column_int(load_power_mode_stat_stmt, 4);
356 if (total_duration + duration > long_period) {
357 total_battery_level_change +=
358 ((float)(long_period - total_duration)) / duration * battery_level_change;
359 total_duration = long_period;
362 total_duration += duration;
363 total_battery_level_change += battery_level_change;
365 if (total_duration < long_period || total_battery_level_change == 0)
368 result[i] = total_duration / total_battery_level_change;
375 API int store_new_power_mode(time_t time_stamp, enum logd_power_mode old_mode,
376 enum logd_power_mode new_mode, time_t duration, int battery_level_change)
378 DB_CHECK(sqlite3_reset(store_power_mode_stmt));
379 DB_CHECK(sqlite3_bind_int64(store_power_mode_stmt, 1, time_stamp));
380 DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 2, old_mode));
381 DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 3, new_mode));
382 DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 4, duration));
383 DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 5, battery_level_change));
385 if (sqlite3_step(store_power_mode_stmt) != SQLITE_DONE) {
386 _E("Can't store power mode: %s", sqlite3_errmsg(db));