#define BATTERY_TIME_INFO_DELETE_DELAY 10 * 3600
#define UPDATE_BATTERY_LOGS_QUERY \
- "UPDATE " BATTERY_TEMP_TIME_INFO " SET " BATTERY_TO_BE_PROCESSED " = %d WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d"
+ "UPDATE " BATTERY_TEMP_TIME_INFO " SET " BATTERY_TO_BE_PROCESSED " = 0 WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d"
BatteryMonitor::BatteryMonitor()
{
}
}
-gboolean BatteryMonitor::__timeoutCb(gpointer data) {
+gboolean BatteryMonitor::__timeoutCb(gpointer data)
+{
BatteryMonitor* instance = static_cast<BatteryMonitor*>(data);
bool dataRemaining = instance->processBatteryUsage();
}
}
- // Insert log of last times of apps, and update battery infos ToBeProcessed field
+ // Normalize the percentages data, insert log of last times of apps, and update battery infos ToBeProcessed field
if (i != 0) {
+ __analyzer.normalize();
+
ret = __insertLastCpuUsageLog(lastCpuUsage);
if (!ret) {
_E("Failed to insert last Cpu Usage of apps");
int processedStartTime = totalStartTime;
int processedEndTime;
__batteryTimeInfoVec[i-1].get(NULL, BATTERY_END_TIME, &processedEndTime);
- char *sql = sqlite3_mprintf(UPDATE_BATTERY_LOGS_QUERY, 0, processedStartTime, processedEndTime);
+ char *sql = sqlite3_mprintf(UPDATE_BATTERY_LOGS_QUERY, processedStartTime, processedEndTime);
__dbMgr.executeSync(sql, NULL);
sqlite3_free(sql);
}
*/
#include <map>
+#include <sqlite3.h>
#include <Types.h>
#include "BatteryUsageAnalyzer.h"
using namespace ctx;
-void BatteryUsageAnalyzer::__normalizeBatteryUsage(std::vector<Json>* usage, int totalUtime, int totalStime)
-{
- if (totalStime + totalUtime == 0) {
- return;
- }
+static int __timestampToNormalizeFrom = INT_MAX;
- int utime;
- int stime;
- double batteryUsage;
+#define BATTERY_INTERVALS_QUERY \
+ "SELECT " BATTERY_START_TIME " , " BATTERY_END_TIME " FROM " BATTERY_TEMP_TIME_INFO " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d"
+#define NORMALIZE_QUERY \
+ "UPDATE " BATTERY_USAGE_TABLE " SET " BATTERY_AMOUNT " = 10000 * (" BATTERY_UTIME " + " BATTERY_STIME ") /((" \
+ "SELECT SUM(" BATTERY_UTIME ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d) + (" \
+ "SELECT SUM(" BATTERY_STIME ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d )) WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d"
- for (unsigned int i= 0; i < usage->size(); i++) {
- (*usage)[i].get(NULL, BATTERY_UTIME, &utime);
- (*usage)[i].get(NULL, BATTERY_STIME, &stime);
- batteryUsage = ((double)(utime + stime)) / ((double)(totalUtime + totalStime));
- (*usage)[i].set(NULL, BATTERY_AMOUNT, batteryUsage);
- }
+BatteryUsageAnalyzer::BatteryUsageAnalyzer()
+{
+}
+
+BatteryUsageAnalyzer::~BatteryUsageAnalyzer()
+{
}
bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std::vector<Json>& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector<Json>* usage)
int utime;
int idx;
int pid;
- int totalUtime = 0;
- int totalStime = 0;
+ int leastTimeLogInserted = __timestampToNormalizeFrom;
for (unsigned int i = 0; i < cpuUsageLog.size(); i++) {
cpuUsageLog[i].get(NULL, BATTERY_APP_ID, &appId);
auto lastAppCpuUsage = lastCpuUsage.find(appId);
int prevUtime = 0;
int prevStime = 0;
- int prevTimestamp = 0;
+ int prevTimestamp = INT_MAX;
int prevPid = 0;
if (lastAppCpuUsage != lastCpuUsage.end()) {
prevTimestamp = lastTime;
}
+ double timeCurrPercent = (double)(timestamp - lastTime);
+ double utimePerUnitTime = (((double)(utime - prevUtime)) / ((double)(timestamp - prevTimestamp)));
+ double stimePerUnitTime = (((double)(stime - prevStime)) / ((double)(timestamp - prevTimestamp)));
+ __addPreviousBatteryUsageLogs(prevTimestamp, lastTime, appId, utimePerUnitTime, stimePerUnitTime, usage);
+
+ if (leastTimeLogInserted > prevTimestamp) {
+ leastTimeLogInserted = prevTimestamp;
+ }
+
Json row;
row.set(NULL, BATTERY_APP_ID, appId);
- row.set(NULL, BATTERY_START_TIME, prevTimestamp);
+ row.set(NULL, BATTERY_START_TIME, lastTime);
row.set(NULL, BATTERY_END_TIME, timestamp);
row.set(NULL, BATTERY_AMOUNT, 0);
- row.set(NULL, BATTERY_UTIME, utime - prevUtime);
- row.set(NULL, BATTERY_STIME, stime - prevStime);
+ row.set(NULL, BATTERY_UTIME, (int)(utimePerUnitTime * timeCurrPercent + 0.5));
+ row.set(NULL, BATTERY_STIME, (int)(stimePerUnitTime * timeCurrPercent + 0.5));
- totalUtime += utime - prevUtime;
- totalStime += stime - prevStime;
usage->push_back(row);
} else {
row.set(NULL, BATTERY_UTIME, utime);
row.set(NULL, BATTERY_STIME, stime);
- totalStime += stime;
- totalUtime += utime;
usage->push_back(row);
}
lastAppUsage.stime = stime;
lastAppUsage.pid = pid;
lastCpuUsage[appId] = lastAppUsage;
+
+ __timestampToNormalizeFrom = leastTimeLogInserted;
+ }
+ return true;
+}
+
+// When an app is open across multiple percentage drops without any app event, this function is called on the next app event to distribute the battery drain among the percentages it was open
+bool BatteryUsageAnalyzer::__addPreviousBatteryUsageLogs(int startTime, int endTime, std::string appId, double utimePerUnitTime, double stimePerUnitTime, std::vector<Json>* usage)
+{
+ std::vector<Json> batteryChanges;
+ char *sql = sqlite3_mprintf(BATTERY_INTERVALS_QUERY, startTime, endTime);
+ __dbMgr.executeSync(sql, &batteryChanges);
+ sqlite3_free(sql);
+
+ unsigned int k = 0;
+ int batteryStartTime;
+ int batteryEndTime;
+ int batteryTimeDiff;
+
+ while (k < batteryChanges.size()) {
+ batteryChanges[k].get(NULL, BATTERY_START_TIME, &batteryStartTime);
+ batteryChanges[k].get(NULL, BATTERY_END_TIME, &batteryEndTime);
+ batteryTimeDiff = batteryEndTime - batteryStartTime;
+ k++;
+
+ Json row;
+ row.set(NULL, BATTERY_APP_ID, appId);
+ row.set(NULL, BATTERY_START_TIME, batteryStartTime);
+ row.set(NULL, BATTERY_END_TIME, batteryEndTime);
+ row.set(NULL, BATTERY_AMOUNT, 0);
+ row.set(NULL, BATTERY_UTIME, (int)(utimePerUnitTime * batteryTimeDiff + 0.5));
+ row.set(NULL, BATTERY_STIME, (int)(stimePerUnitTime * batteryTimeDiff + 0.5));
+ usage->push_back(row);
}
- __normalizeBatteryUsage(usage, totalUtime, totalStime);
+ return true;
+}
+
+bool BatteryUsageAnalyzer::normalize()
+{
+ _D("Normalizing battery usage data from time %d ", __timestampToNormalizeFrom);
+ std::vector<Json> batteryChanges;
+ char *sql = sqlite3_mprintf(BATTERY_INTERVALS_QUERY, __timestampToNormalizeFrom, CURRENT_TIME);
+ __dbMgr.executeSync(sql, &batteryChanges);
+
+ unsigned int k = 0;
+ int batteryStartTime;
+ int batteryEndTime;
+
+ while (k < batteryChanges.size()) {
+ batteryChanges[k].get(NULL, BATTERY_START_TIME, &batteryStartTime);
+ batteryChanges[k].get(NULL, BATTERY_END_TIME, &batteryEndTime);
+ k++;
+
+ sql = sqlite3_mprintf(NORMALIZE_QUERY, batteryStartTime, batteryEndTime, batteryStartTime, batteryEndTime, batteryStartTime, batteryEndTime);
+ __dbMgr.executeSync(sql, NULL);
+ }
+
+ __timestampToNormalizeFrom = INT_MAX;
+ sqlite3_free(sql);
return true;
}