13 static sqlite3_stmt *load_mostused_apps_stmt;
14 static sqlite3_stmt *get_enabled_devices_stmt;
15 static sqlite3_stmt *load_dev_working_time_stmt;
19 struct logd_device_ratio {
20 enum logd_object device;
24 static struct logd_device_ratio ratio[] = {
26 {LOGD_ACCELEROMETER, 0},
29 {LOGD_DISPLAY, 1.86}, /* brightness 80% */
30 {LOGD_GEOMAGNETIC, 0},
36 {LOGD_THERMOMETER, 0},
40 {LOGD_BATTERY_SOC, 0},
43 {LOGD_FOREGRD_APP, 0},
50 STATIC_ASSERT(sizeof(ratio)/sizeof(ratio[0]) == LOGD_OBJECT_MAX, number_of_ratio_\
51 elements_must_be_equal_LOGD_OBJECT_MAX);
53 #define GET_ENABLED_DEVICES_SQL "SELECT object, MAX(time_stamp) \
54 FROM events GROUP BY object HAVING action!=%d"
56 #define LOAD_DEV_WORKING_TIME_SQL "SELECT device, SUM(time) AS time \
57 FROM device_working_time WHERE time_stamp>=? AND time_stamp<=? \
63 char *get_enabled_devices;
67 ret = asprintf(&get_enabled_devices, GET_ENABLED_DEVICES_SQL, LOGD_OFF);
69 fprintf(stderr, "Cannot create statement\n");
73 PREPARE_STMT(load_dev_working_time_stmt, LOAD_DEV_WORKING_TIME_SQL);
74 PREPARE_STMT(get_enabled_devices_stmt, get_enabled_devices);
76 free(get_enabled_devices);
81 int padvisor_finalize()
83 FINALIZE_STMT(load_dev_working_time_stmt);
84 FINALIZE_STMT(load_mostused_apps_stmt);
85 FINALIZE_STMT(get_enabled_devices_stmt);
90 static int compare_device_power_cons(const void *dev1, const void *dev2)
92 float coeff1 = ratio[((struct logd_idle_device*)dev1)->device].coefficient;
93 float coeff2 = ratio[((struct logd_idle_device*)dev2)->device].coefficient;
97 else if (coeff1 > coeff2)
103 static enum logd_db_query mostused_apps_cb(const struct logd_proc_stat *proc_stat, void *user_data)
106 struct logd_power_advisor *lpa = (struct logd_power_advisor*) user_data;
108 lpa->procs[i].application = strdup(proc_stat->application);
109 lpa->procs[i].utime = proc_stat->utime;
110 lpa->procs[i].stime = proc_stat->stime;
111 lpa->procs[i].utime_power_cons = proc_stat->utime_power_cons;
112 lpa->procs[i].stime_power_cons = proc_stat->stime_power_cons;
113 lpa->proc_stat_used_num++;
115 if (++i < LOGD_ADVISOR_MAX)
116 return LOGD_DB_QUERY_CONTINUE;
119 return LOGD_DB_QUERY_STOP;
122 API struct logd_power_advisor *logd_get_power_advisor(void)
126 struct logd_power_advisor *lpa;
127 int total_power_cons = 0;
129 lpa = calloc(1, sizeof(struct logd_power_advisor));
131 _E("Can't calloc logd_power_advisor");
135 for (i = 0; i < LOGD_ADVISOR_MAX; i++) {
136 if (sqlite3_step(get_enabled_devices_stmt) != SQLITE_ROW) {
140 lpa->idle_devices[i].device =
141 sqlite3_column_int(get_enabled_devices_stmt, 0);
142 lpa->idle_devices[i].idle_time =
143 sqlite3_column_int64(get_enabled_devices_stmt, 1);
144 lpa->idle_devices_used_num++;
146 qsort(lpa->idle_devices, lpa->idle_devices_used_num,
147 sizeof(struct logd_idle_device), compare_device_power_cons);
149 ret = sqlite3_reset(get_enabled_devices_stmt);
150 if (ret != SQLITE_OK) {
151 _E("cannot reset statement: %s", sqlite3_errmsg(db));
156 logd_foreach_proc_stat(&mostused_apps_cb, lpa);
158 for (i = 0; i < lpa->proc_stat_used_num; i++) {
159 total_power_cons += lpa->procs[i].utime_power_cons + lpa->procs[i].stime_power_cons;
162 for (i = 0; i < lpa->proc_stat_used_num; ++i)
163 lpa->procs[i].percentage =
164 (float)(lpa->procs[i].utime_power_cons + lpa->procs[i].stime_power_cons) /
170 API void logd_free_power_advisor(struct logd_power_advisor *lpa)
177 for (i = 0; i < lpa->proc_stat_used_num; i++) {
178 free(lpa->procs[i].application);
184 API struct device_power_consumption *
185 logd_get_device_power_cons(time_t from, time_t to)
187 struct device_power_consumption *pcons;
188 float scaled_time = 0;
190 if (sqlite3_bind_int(load_dev_working_time_stmt, 1, from) !=
192 _E("Can't bind argument: %s", sqlite3_errmsg(db));
195 if (sqlite3_bind_int(load_dev_working_time_stmt, 2, to) !=
197 _E("Can't bind argument: %s", sqlite3_errmsg(db));
201 pcons = calloc(1, sizeof(struct device_power_consumption));
203 _E("Can't calloc device_power_consumption");
207 while (sqlite3_step(load_dev_working_time_stmt) == SQLITE_ROW)
209 int devid = sqlite3_column_int(load_dev_working_time_stmt, 0);
210 int dev_time = sqlite3_column_int(load_dev_working_time_stmt, 1);
212 if (devid < 0 || LOGD_OBJECT_MAX <= devid) {
213 _E("wrong device id: %d", devid);
217 pcons->device_cons[devid].time = dev_time;
218 pcons->total_time += dev_time;
219 scaled_time += ratio[devid].coefficient * dev_time;
222 if (pcons->total_time) {
223 for (int i = 0; i < LOGD_OBJECT_MAX; ++i) {
224 pcons->device_cons[i].percentage = ratio[i].coefficient *
225 pcons->device_cons[i].time / scaled_time;
228 if (sqlite3_reset(load_dev_working_time_stmt) != SQLITE_OK) {
229 _E("Can't reset statement: %s", sqlite3_errmsg(db));
237 API void logd_free_device_power_cons(struct device_power_consumption *pcons)