From 4835b1cb670b14d1ac95d6c45e46fe6ef023238a Mon Sep 17 00:00:00 2001 From: Somin Kim Date: Wed, 21 Dec 2016 21:30:46 +0900 Subject: [PATCH] [battery-stats] modified to provide data while charging Change-Id: Ib3c0e62bdda97bec3dc7960da376bd1dc235d9d9 Signed-off-by: Somin Kim --- src/battery-stats/BatteryMonitor.cpp | 312 +++++++++-------------------- src/battery-stats/BatteryMonitor.h | 25 ++- src/battery-stats/BatteryStatisticsTypes.h | 29 +-- src/battery-stats/BatteryStatsLogger.cpp | 12 +- src/battery-stats/BatteryStatsLogger.h | 3 - src/battery-stats/BatteryUsage.h | 1 - src/battery-stats/BatteryUsageAnalyzer.cpp | 170 ++++------------ src/battery-stats/BatteryUsageAnalyzer.h | 10 +- src/battery-stats/HeartDbReader.cpp | 4 +- src/battery-stats/HeartDbReader.h | 3 +- src/battery-stats/Querier.cpp | 8 +- src/battery-stats/RecentBatteryUsage.cpp | 7 +- 12 files changed, 164 insertions(+), 420 deletions(-) diff --git a/src/battery-stats/BatteryMonitor.cpp b/src/battery-stats/BatteryMonitor.cpp index 57fc261..e196338 100644 --- a/src/battery-stats/BatteryMonitor.cpp +++ b/src/battery-stats/BatteryMonitor.cpp @@ -18,40 +18,49 @@ #include #include #include +#include #include #include #include "HeartDbReader.h" #include "BatteryMonitor.h" #define DEFAULT_ROW_ID_STR "1" +#define HEART_DB_QUERY_INTERVAL 10 * 60 * 1000 using namespace ctx; -static int __bootingTime = 0; -static int __lastResetTime = 0; -static int __lastPercent = -1; -static int __lastPercentTime = 0; -static int __lastBatteryTimeInfoDeleteTime = 0; -static bool __isCharging = 0; -static bool __timerRunning = false; -static std::vector __batteryTimeInfoVec; +BatteryMonitor* BatteryMonitor::__instance = NULL; -#define HEART_DB_QUERY_DELAY 600000 -#define BATTERY_TIME_INFO_DELETE_DELAY 10 * 3600 +BatteryMonitor::BatteryMonitor() : + __bootingTime(0), + __lastFullTime(0), + __lastHeartAccessTime(0) +{ +} -#define UPDATE_BATTERY_LOGS_QUERY \ - "UPDATE " BATTERY_TEMP_TIME_INFO " SET " BATTERY_TO_BE_PROCESSED " = 0 WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d" +BatteryMonitor::~BatteryMonitor() +{ +} -BatteryMonitor::BatteryMonitor() +BatteryMonitor* BatteryMonitor::getInstance() { - __initialize(); + IF_FAIL_RETURN(!__instance, __instance); + + __instance = new(std::nothrow) BatteryMonitor(); + IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory allocation failed"); + + return __instance; } -BatteryMonitor::~BatteryMonitor() +void BatteryMonitor::destroy() { + IF_FAIL_VOID(__instance); + + delete __instance; + __instance = NULL; } -void BatteryMonitor::__initialize() +void BatteryMonitor::initialize() { std::vector records; __dbMgr.executeSync( @@ -65,16 +74,12 @@ void BatteryMonitor::__initialize() __dbMgr.executeSync( "CREATE TABLE IF NOT EXISTS " BATTERY_LAST_CPU_USAGE_TABLE \ " (" BATTERY_LAST_CPU_USAGE_TABLE_COLUMNS ")", &records); - - __dbMgr.createTableSync(BATTERY_TEMP_TIME_INFO, BATTERY_TEMP_TIME_INFO_COLUMNS, NULL); } bool BatteryMonitor::__loadLastInfo() { __bootingTime = CURRENT_TIME; - device_battery_is_charging(&__isCharging); - std::vector records; bool ret = __dbMgr.executeSync( "SELECT * FROM " BATTERY_LAST_INFO_TABLE \ @@ -82,86 +87,39 @@ bool BatteryMonitor::__loadLastInfo() IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to load last info"); if (records.size() == 1) { - records[0].get(NULL, BATTERY_LAST_RESET_TIME, &__lastResetTime); - records[0].get(NULL, BATTERY_LAST_PERCENT, &__lastPercent); - records[0].get(NULL, BATTERY_LAST_PERCENT_TIME, &__lastPercentTime); - records[0].get(NULL, BATTERY_TIME_INFO_LAST_DELETE_TIME, &__lastBatteryTimeInfoDeleteTime); + records[0].get(NULL, BATTERY_LAST_FULL_TIME, &__lastFullTime); + records[0].get(NULL, BATTERY_LAST_HEART_ACCESS_TIME, &__lastHeartAccessTime); } - records.clear(); - __batteryTimeInfoVec.clear(); - ret = __dbMgr.executeSync("SELECT * FROM " BATTERY_TEMP_TIME_INFO " WHERE " BATTERY_TO_BE_PROCESSED " = 1", &__batteryTimeInfoVec); return true; } bool BatteryMonitor::__updateLastInfo() { char *query = sqlite3_mprintf("INSERT OR REPLACE INTO " BATTERY_LAST_INFO_TABLE " (" \ - BATTERY_ROW_ID ", " BATTERY_LAST_PERCENT ", " BATTERY_LAST_PERCENT_TIME \ - ", " BATTERY_TIME_INFO_LAST_DELETE_TIME ", " BATTERY_LAST_RESET_TIME ") VALUES (%s, %d, %d, %d, %d)", - DEFAULT_ROW_ID_STR, __lastPercent, __lastPercentTime, __lastBatteryTimeInfoDeleteTime, __lastResetTime); + BATTERY_ROW_ID ", " BATTERY_LAST_FULL_TIME ", " BATTERY_LAST_HEART_ACCESS_TIME ") VALUES (%s, %d, %d)", + DEFAULT_ROW_ID_STR, __lastFullTime, __lastHeartAccessTime); bool ret = __dbMgr.executeSync(query, NULL); sqlite3_free(query); return ret; } -void BatteryMonitor::__batteryChangeCb(device_callback_e type, void* value, void* userData) -{ - IF_FAIL_VOID(type == DEVICE_CALLBACK_BATTERY_CAPACITY); - - int percent = intptr_t(value); - int currentTime = CURRENT_TIME; - BatteryMonitor* instance = static_cast(userData); - - if (!__isCharging && percent == (__lastPercent - 1) && __lastPercentTime != 0) { - _D("Battery capacity decreased: %d% -> %d%", __lastPercent, percent); - - Json battTimeInfo; - battTimeInfo.set(NULL, BATTERY_AMOUNT, percent); - battTimeInfo.set(NULL, BATTERY_START_TIME, __lastPercentTime); - battTimeInfo.set(NULL, BATTERY_END_TIME, currentTime); - battTimeInfo.set(NULL, BATTERY_TO_BE_PROCESSED, 1); - __batteryTimeInfoVec.push_back(battTimeInfo); - - int64_t rowId; - (instance->__dbMgr).insertSync(BATTERY_TEMP_TIME_INFO, battTimeInfo, &rowId); - - bool dataRemaining = instance->processBatteryUsage(); - if (dataRemaining && !__timerRunning) { - __timerRunning = true; - _D("Start timer to request HEART data"); - g_timeout_add(HEART_DB_QUERY_DELAY, __timeoutCb, instance); - } - } - - __lastPercentTime = currentTime; - __lastPercent = percent; - - bool ret = instance->__updateLastInfo(); - IF_FAIL_VOID_TAG(ret, _E, "Failed to update last percent and last percent times"); -} - void BatteryMonitor::__chargerChangeCb(device_callback_e type, void* value, void* userData) { IF_FAIL_VOID(type == DEVICE_CALLBACK_BATTERY_CHARGING); - __isCharging = intptr_t(value); - IF_FAIL_VOID(!__isCharging); + bool isCharging = intptr_t(value); + IF_FAIL_VOID(!isCharging); BatteryMonitor* instance = static_cast(userData); int percent; - if (__lastPercent < 0) { - int error = device_battery_get_percent(&percent); - IF_FAIL_VOID_TAG(error == DEVICE_ERROR_NONE, _E, "Failed to get battery capacity"); - } else { - percent = __lastPercent; - } + int error = device_battery_get_percent(&percent); + IF_FAIL_VOID_TAG(error == DEVICE_ERROR_NONE, _E, "Failed to get battery capacity"); // If charger is disconnected after 100% charged if (percent == 100) { - __lastResetTime = CURRENT_TIME; - __lastPercentTime = __lastResetTime; - _D("Charger is disconnected after fully charged. ResetTime: %d", __lastResetTime); + instance->__lastFullTime = CURRENT_TIME; + _D("Charger is disconnected after fully charged. Last fully charged time: %d", instance->__lastFullTime); bool ret = instance->__updateLastInfo(); IF_FAIL_VOID_TAG(ret, _E, "Failed to update last reset time and last percent time"); @@ -171,50 +129,37 @@ void BatteryMonitor::__chargerChangeCb(device_callback_e type, void* value, void gboolean BatteryMonitor::__timeoutCb(gpointer data) { BatteryMonitor* instance = static_cast(data); + instance->__processBatteryUsage(); - bool dataRemaining = instance->processBatteryUsage(); - if (!dataRemaining) { - _D("Stop timer, no more data to process"); - __timerRunning = false; - } - - return dataRemaining ? TRUE : FALSE; + return TRUE; } int BatteryMonitor::start() { __loadLastInfo(); - int error = device_add_callback(DEVICE_CALLBACK_BATTERY_CAPACITY, __batteryChangeCb, this); - IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to set battery capacity change cb"); - - error = device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb, NULL); + int error = device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb, this); IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to set battery charging change cb"); - __timerRunning = true; _D("Start timer to request HEART data"); - g_timeout_add(HEART_DB_QUERY_DELAY, __timeoutCb, this); + g_timeout_add(HEART_DB_QUERY_INTERVAL, __timeoutCb, this); + return ERR_NONE; } int BatteryMonitor::stop() { - int error = device_remove_callback(DEVICE_CALLBACK_BATTERY_CAPACITY, __batteryChangeCb); - IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to remove callback for battery capacity"); - - error = device_remove_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb); + int error = device_remove_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb); IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to remove callback for charger status"); return ERR_NONE; } -bool BatteryMonitor::__getLastCpuUsageTable(CpuUsageMap* lastCpuUsage) +bool BatteryMonitor::__getLastCpuUsageTable(CpuUsageMap* lastHeartCpuLog) { - std::vector lastCpuUsageLog; - bool ret = __dbMgr.executeSync( - "SELECT * FROM " BATTERY_LAST_CPU_USAGE_TABLE, - &lastCpuUsageLog); - IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to load last Cpu Times of Apps"); + std::vector cpuLog; + bool ret = __dbMgr.executeSync("SELECT * FROM " BATTERY_LAST_CPU_USAGE_TABLE, &cpuLog); + IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to load last cpu times of apps"); unsigned int k = 0; std::string appId; @@ -223,125 +168,71 @@ bool BatteryMonitor::__getLastCpuUsageTable(CpuUsageMap* lastCpuUsage) int utime; int pid; - while (k < lastCpuUsageLog.size()) { - lastCpuUsageLog[k].get(NULL, BATTERY_APP_ID, &appId); - lastCpuUsageLog[k].get(NULL, BATTERY_TIMESTAMP, ×tamp); - lastCpuUsageLog[k].get(NULL, BATTERY_UTIME, &utime); - lastCpuUsageLog[k].get(NULL, BATTERY_STIME, &stime); - lastCpuUsageLog[k].get(NULL, BATTERY_PID, &pid); + while (k < cpuLog.size()) { + cpuLog[k].get(NULL, BATTERY_APP_ID, &appId); + cpuLog[k].get(NULL, BATTERY_TIMESTAMP, ×tamp); + cpuLog[k].get(NULL, BATTERY_UTIME, &utime); + cpuLog[k].get(NULL, BATTERY_STIME, &stime); + cpuLog[k].get(NULL, BATTERY_PID, &pid); k++; - LastAppCpuUsageInfo lastAppCpuUsage; - lastAppCpuUsage.timestamp = timestamp; - lastAppCpuUsage.utime = utime; - lastAppCpuUsage.stime = stime; - lastAppCpuUsage.pid = pid; - (*lastCpuUsage)[appId] = lastAppCpuUsage; + CpuLogInfo appInfo; + appInfo.timestamp = timestamp; + appInfo.utime = utime; + appInfo.stime = stime; + appInfo.pid = pid; + (*lastHeartCpuLog)[appId] = appInfo; } return true; } -//Return false if all is processed, true otherwise -bool BatteryMonitor::processBatteryUsage() +bool BatteryMonitor::__processBatteryUsage() { - IF_FAIL_RETURN_TAG(__batteryTimeInfoVec.size() > 0, false, _D, "All per-app battery usages are already calculated"); - - int totalStartTime; - int totalEndTime; - __batteryTimeInfoVec.front().get(NULL, BATTERY_START_TIME, &totalStartTime); - __batteryTimeInfoVec.back().get(NULL, BATTERY_END_TIME, &totalEndTime); - - // Read cpu table from heart db for time span of stacked in __batteryTimeInfoVec + // Read from heart cpu table HeartDbReader heartReader; bool ret = heartReader.open(); IF_FAIL_RETURN_TAG(ret, true, _E, "Failed to open heart db"); - std::vector cpuUsageLog; - ret = heartReader.readCpuUsageLog(totalStartTime, totalEndTime, &cpuUsageLog); + std::vector heartCpuLog; + ret = heartReader.readCpuLog(__lastHeartAccessTime, &heartCpuLog); heartReader.close(); + IF_FAIL_RETURN_TAG(ret, true, _E, "Cannot read from heart cpu table"); - IF_FAIL_RETURN_TAG(cpuUsageLog.size() > 0, true, _W, "Heart cpu data is not prepared yet (%d ~ %d)", totalStartTime, totalEndTime); - _D("Read %d rows from heart cpu table from %d to %d", cpuUsageLog.size(), totalStartTime, totalEndTime); - - // Get the last timestamp of HEART cpu data and maximum app times tables in cache - int lastHeartTimestamp; - cpuUsageLog.back().get(NULL, BATTERY_TIMESTAMP, &lastHeartTimestamp); - CpuUsageMap lastCpuUsage; - ret = __getLastCpuUsageTable(&lastCpuUsage); - - unsigned int i; - for (i = 0; i < __batteryTimeInfoVec.size(); i++) { - int startTime; - int endTime; - - Json row = __batteryTimeInfoVec[i].str(); - row.get(NULL, BATTERY_START_TIME, &startTime); - row.get(NULL, BATTERY_END_TIME, &endTime); - - if (endTime > lastHeartTimestamp) { - _W("[%d] Heart cpu data is not prepared yet (%d ~ %d)", i, startTime, endTime); - break; - } - - // Calculate per app battery usage - std::vector usage; - ret = __analyzer.calculateBatteryUsage(startTime, endTime, cpuUsageLog, lastCpuUsage, &usage); - if (!ret) { - _E("[%d] Failed to calculate battery usage (%d ~ %d)", i, startTime, endTime); - continue; - } - _D("[%d] Battery usage per app calculated (%d ~ %d)", i, startTime, endTime); - - // Insert battery usage - ret = __insertBatteryUsageLog(usage); - if (!ret) { - _E("Failed to insert per app battery usage"); - } - } + IF_FAIL_RETURN_TAG(heartCpuLog.size() > 0, true, _W, "Heart cpu data is not prepared"); + _D("Read %d rows from heart cpu table from %d", heartCpuLog.size(), __lastHeartAccessTime); - // 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, processedStartTime, processedEndTime); - __dbMgr.executeSync(sql, NULL); - sqlite3_free(sql); - } + heartCpuLog.back().get(NULL, BATTERY_TIMESTAMP, &__lastHeartAccessTime); + __updateLastInfo(); - // Remove completed time info - _D("Total %d time intervals, %d intervals are calculated", __batteryTimeInfoVec.size(), i); - __batteryTimeInfoVec.erase(__batteryTimeInfoVec.begin(), __batteryTimeInfoVec.begin() + i); - __deleteBatteryTimeInfo(); + // Get last heart cpu log + CpuUsageMap lastHeartCpuLog;; + ret = __getLastCpuUsageTable(&lastHeartCpuLog); - if (__batteryTimeInfoVec.size() == 0) { - return false; - } - else { - return true; - } + // Calculate per app battery usage + std::vector usage; + __analyzer.calculateBatteryUsage(heartCpuLog, lastHeartCpuLog, &usage); + + // Insert battery usage + ret = __insertBatteryUsageLog(usage); + IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to insert per app battery usage"); + + // Update last cpu usage + ret = __updateLastCpuUsageLog(lastHeartCpuLog); + IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update last cpu log"); + + return true; } bool BatteryMonitor::__insertBatteryUsageLog(std::vector& usage) { IF_FAIL_RETURN_TAG(usage.size(), true, _W, "No data"); std::string query("INSERT INTO " BATTERY_USAGE_TABLE \ - "(" BATTERY_APP_ID ", " BATTERY_START_TIME ", " \ - BATTERY_END_TIME ", " BATTERY_UTIME ", " \ - BATTERY_STIME ", " BATTERY_AMOUNT ") VALUES"); + "(" BATTERY_APP_ID ", " BATTERY_START_TIME ", " BATTERY_END_TIME ", " \ + BATTERY_UTIME ", " BATTERY_STIME "," BATTERY_TOTAL_TIME ") VALUES"); std::string appId; - int startTime; + int startTime, endTime; int stime, utime; - int endTime; - double amount; for (unsigned int i = 0; i < usage.size(); i++) { usage[i].get(NULL, BATTERY_APP_ID, &appId); @@ -349,14 +240,13 @@ bool BatteryMonitor::__insertBatteryUsageLog(std::vector& usage) usage[i].get(NULL, BATTERY_END_TIME, &endTime); usage[i].get(NULL, BATTERY_UTIME, &utime); usage[i].get(NULL, BATTERY_STIME, &stime); - usage[i].get(NULL, BATTERY_AMOUNT, &amount); query += " ('" + appId + "', " + std::to_string(startTime) + ", " + std::to_string(endTime) + ", " + std::to_string(utime) + ", " + std::to_string(stime) + ", " - + std::to_string((int) (amount * 10000)) + ")"; + + std::to_string(utime + stime) + ")"; query += ", "; } @@ -366,10 +256,9 @@ bool BatteryMonitor::__insertBatteryUsageLog(std::vector& usage) return __dbMgr.executeSync(query.c_str(), NULL); } -bool BatteryMonitor::__insertLastCpuUsageLog(CpuUsageMap& usage) +bool BatteryMonitor::__updateLastCpuUsageLog(CpuUsageMap& usage) { IF_FAIL_RETURN_TAG(usage.size(), true, _W, "No data"); - _D("Delete all rows from app last times table"); __dbMgr.executeSync("DELETE FROM " BATTERY_LAST_CPU_USAGE_TABLE, NULL); std::string query("INSERT INTO " BATTERY_LAST_CPU_USAGE_TABLE "(" BATTERY_APP_ID ", " BATTERY_UTIME ", " BATTERY_STIME ", " BATTERY_TIMESTAMP ", " BATTERY_PID ") VALUES"); @@ -400,31 +289,12 @@ bool BatteryMonitor::__insertLastCpuUsageLog(CpuUsageMap& usage) } // Used for Recent Battery Usage -int BatteryMonitor::getLastResetTime() +int BatteryMonitor::getLastFullTime() { - if (__lastResetTime == 0) { - _I("Device has not fully charged until now. Start time of recent battery usage will be booting time"); + if (__lastFullTime == 0) { + _I("Device has not fully charged until now. Start time of recent battery usage will be booting time: %d", __bootingTime); return __bootingTime; } - return __lastResetTime; -} - -void BatteryMonitor::__deleteBatteryTimeInfo() -{ - int batteryTimeInfoDeleteTime = CURRENT_TIME - BATTERY_TIME_INFO_DELETE_DELAY; - if (__lastBatteryTimeInfoDeleteTime > batteryTimeInfoDeleteTime) { - _D("Old battery time info already deleted"); - return; - } - - std::string query("DELETE FROM " BATTERY_TEMP_TIME_INFO " WHERE StartTime <= "); - query += std::to_string(batteryTimeInfoDeleteTime); - - __dbMgr.executeSync(query.c_str(), NULL); - __lastBatteryTimeInfoDeleteTime = CURRENT_TIME; - - bool ret = __updateLastInfo(); - IF_FAIL_VOID_TAG(ret, _E, "Failed to update last battery time info deletion time"); - _D("Old battery time info deleted"); + return __lastFullTime; } diff --git a/src/battery-stats/BatteryMonitor.h b/src/battery-stats/BatteryMonitor.h index 08b9202..c6c10a8 100644 --- a/src/battery-stats/BatteryMonitor.h +++ b/src/battery-stats/BatteryMonitor.h @@ -18,7 +18,7 @@ #define _CONTEXT_BATTERY_MONITOR_H_ #include -#include +#include #include "BatteryUsageAnalyzer.h" namespace ctx { @@ -28,30 +28,33 @@ namespace ctx { BatteryMonitor(); ~BatteryMonitor(); + static BatteryMonitor* getInstance(); + static void destroy(); + + void initialize(); int start(); int stop(); - - static int getLastResetTime(); - bool processBatteryUsage(); + int getLastFullTime(); private: - void __initialize(); bool __loadLastInfo(); bool __updateLastInfo(); - static void __batteryChangeCb(device_callback_e type, void* value, void* userData); - static void __chargerChangeCb(device_callback_e type, void* value, void* userData); - + bool __processBatteryUsage(); bool __insertBatteryUsageLog(std::vector& usage); - bool __insertLastCpuUsageLog(CpuUsageMap& usage); + bool __updateLastCpuUsageLog(CpuUsageMap& usage); bool __getLastCpuUsageTable(CpuUsageMap* lastCpuUsage); - void __deleteBatteryTimeInfo(); + static void __chargerChangeCb(device_callback_e type, void* value, void* userData); static int __timeoutCb(void* data); + static BatteryMonitor* __instance; + int __bootingTime; + int __lastFullTime; + int __lastHeartAccessTime; + DatabaseManager __dbMgr; BatteryUsageAnalyzer __analyzer; - }; } /* namespace ctx */ diff --git a/src/battery-stats/BatteryStatisticsTypes.h b/src/battery-stats/BatteryStatisticsTypes.h index d9bead6..11dd915 100644 --- a/src/battery-stats/BatteryStatisticsTypes.h +++ b/src/battery-stats/BatteryStatisticsTypes.h @@ -24,22 +24,14 @@ #define BATTERY_USAGE_TABLE "Log_BatteryUsagePerApp" #define BATTERY_USAGE_TABLE_COLUMNS \ - "AppId TEXT NOT NULL, StartTime INTEGER NOT NULL DEFAULT 0, " \ - "EndTime INTEGER NOT NULL DEFAULT 0, Amount INTEGER NOT NULL DEFAULT 0, " \ - "Utime INTEGER NOT NULL DEFAULT 0, Stime INTEGER NOT NULL DEFAULT 0" + "AppId TEXT NOT NULL, StartTime INTEGER NOT NULL DEFAULT 0, EndTime INTEGER NOT NULL DEFAULT 0, " \ + "Utime INTEGER NOT NULL DEFAULT 0, Stime INTEGER NOT NULL DEFAULT 0, TotalTime INTEGER NOT NULL DEFAULT 0" #define BATTERY_LAST_INFO_TABLE "Battery_LastInfo" #define BATTERY_LAST_INFO_TABLE_COLUMNS \ "RowId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " \ - "LastResetTime UNSIGNED INT NOT NULL DEFAULT 0, " \ - "LastPercent UNSIGNED INT NOT NULL DEFAULT 0, " \ - "LastPercentTime UNSIGNED INT NOT NULL DEFAULT 0, " \ - "LastBatteryTimeInfoDeleteTime UNSIGNED INT NOT NULL DEFAULT 0" - -#define BATTERY_TEMP_TIME_INFO "Temp_BatteryTimeInfo" -#define BATTERY_TEMP_TIME_INFO_COLUMNS \ - "Amount INTEGER NOT NULL DEFAULT 0, StartTime INTEGER NOT NULL DEFAULT 0, " \ - "EndTime INTEGER NOT NULL DEFAULT 0, ToBeProcessed BOOLEAN DEFAULT 1" + "LastFullTime UNSIGNED INT NOT NULL DEFAULT 0, " \ + "LastHeartAccessTime UNSIGNED INT NOT NULL DEFAULT 0" #define BATTERY_LAST_CPU_USAGE_TABLE "Temp_LastCpuUsagePerApp" #define BATTERY_LAST_CPU_USAGE_TABLE_COLUMNS \ @@ -55,26 +47,23 @@ #define BATTERY_END_TIME "EndTime" #define BATTERY_UTIME "Utime" #define BATTERY_STIME "Stime" -#define BATTERY_AMOUNT "Amount" -#define BATTERY_LAST_RESET_TIME "LastResetTime" -#define BATTERY_LAST_PERCENT "LastPercent" -#define BATTERY_LAST_PERCENT_TIME "LastPercentTime" -#define BATTERY_TIME_INFO_LAST_DELETE_TIME "LastBatteryTimeInfoDeleteTime" +#define BATTERY_TOTAL_TIME "TotalTime" +#define BATTERY_LAST_FULL_TIME "LastFullTime" +#define BATTERY_LAST_HEART_ACCESS_TIME "LastHeartAccessTime" #define BATTERY_ROW_ID "RowId" -#define BATTERY_TO_BE_PROCESSED "ToBeProcessed" #define BATTERY_PID "Pid" #define CURRENT_TIME (int)(time(0)) /* Typedefs */ namespace ctx { - struct LastAppCpuUsageInfo { + struct CpuLogInfo { int timestamp; int utime; int stime; int pid; }; - typedef std::map CpuUsageMap; + typedef std::map CpuUsageMap; } enum AppLaunchType { diff --git a/src/battery-stats/BatteryStatsLogger.cpp b/src/battery-stats/BatteryStatsLogger.cpp index 89e0309..3b7af49 100644 --- a/src/battery-stats/BatteryStatsLogger.cpp +++ b/src/battery-stats/BatteryStatsLogger.cpp @@ -21,16 +21,14 @@ using namespace ctx; BatteryStatsLogger::BatteryStatsLogger() : - ContextProvider(SUBJ_BATTERY_LOGGER), - __monitor(NULL) + ContextProvider(SUBJ_BATTERY_LOGGER) { - __monitor = new(std::nothrow) BatteryMonitor(); - IF_FAIL_VOID_TAG(__monitor, _E, "Memory allocation failed"); + BatteryMonitor::getInstance()->initialize(); } BatteryStatsLogger::~BatteryStatsLogger() { - delete __monitor; + BatteryMonitor::destroy(); } void BatteryStatsLogger::getPrivilege(std::vector &privilege) @@ -40,10 +38,10 @@ void BatteryStatsLogger::getPrivilege(std::vector &privilege) int BatteryStatsLogger::subscribe(Json option, Json* requestResult) { - return __monitor->start(); + return BatteryMonitor::getInstance()->start(); } int BatteryStatsLogger::unsubscribe(Json option) { - return __monitor->stop(); + return BatteryMonitor::getInstance()->stop(); } diff --git a/src/battery-stats/BatteryStatsLogger.h b/src/battery-stats/BatteryStatsLogger.h index 026b72e..ef02bb1 100644 --- a/src/battery-stats/BatteryStatsLogger.h +++ b/src/battery-stats/BatteryStatsLogger.h @@ -32,9 +32,6 @@ namespace ctx { int unsubscribe(Json option); void getPrivilege(std::vector &privilege); - - private: - BatteryMonitor *__monitor; }; } /* namespace ctx */ diff --git a/src/battery-stats/BatteryUsage.h b/src/battery-stats/BatteryUsage.h index f446dd3..bc748ba 100644 --- a/src/battery-stats/BatteryUsage.h +++ b/src/battery-stats/BatteryUsage.h @@ -22,7 +22,6 @@ namespace ctx { class BatteryUsageProvider : public BatteryStatsProvider { - public: BatteryUsageProvider(); ~BatteryUsageProvider(); diff --git a/src/battery-stats/BatteryUsageAnalyzer.cpp b/src/battery-stats/BatteryUsageAnalyzer.cpp index 61fe0c5..bb08d8b 100644 --- a/src/battery-stats/BatteryUsageAnalyzer.cpp +++ b/src/battery-stats/BatteryUsageAnalyzer.cpp @@ -15,21 +15,11 @@ */ #include -#include #include #include "BatteryUsageAnalyzer.h" using namespace ctx; -static int __timestampToNormalizeFrom = INT_MAX; - -#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" - BatteryUsageAnalyzer::BatteryUsageAnalyzer() { } @@ -38,154 +28,62 @@ BatteryUsageAnalyzer::~BatteryUsageAnalyzer() { } -bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std::vector& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector* usage) +void BatteryUsageAnalyzer::calculateBatteryUsage(std::vector& cpuLog, CpuUsageMap& recentCpuUsageMap, std::vector* usage) { - int timeInterval = currTime - lastTime; - IF_FAIL_RETURN(timeInterval > 0, false); - std::string appId; int timestamp; int stime; int utime; int idx; int pid; - int leastTimeLogInserted = __timestampToNormalizeFrom; - - for (unsigned int i = 0; i < cpuUsageLog.size(); i++) { - cpuUsageLog[i].get(NULL, BATTERY_APP_ID, &appId); - cpuUsageLog[i].get(NULL, BATTERY_TIMESTAMP, ×tamp); - cpuUsageLog[i].get(NULL, BATTERY_UTIME, &utime); - cpuUsageLog[i].get(NULL, BATTERY_STIME, &stime); - cpuUsageLog[i].get(NULL, BATTERY_INDEX, &idx); - cpuUsageLog[i].get(NULL, BATTERY_PID, &pid); - if (timestamp < lastTime) { - continue; - } - if (timestamp > currTime) { - break; - } + for (unsigned int i = 0; i < cpuLog.size(); i++) { + cpuLog[i].get(NULL, BATTERY_APP_ID, &appId); + cpuLog[i].get(NULL, BATTERY_TIMESTAMP, ×tamp); + cpuLog[i].get(NULL, BATTERY_UTIME, &utime); + cpuLog[i].get(NULL, BATTERY_STIME, &stime); + cpuLog[i].get(NULL, BATTERY_INDEX, &idx); + cpuLog[i].get(NULL, BATTERY_PID, &pid); - //If CPU table is reset, clear last app times and make lastTime as the timestamp + //If CPU table is reset, clear last cpu usage if (idx == 0) { - lastCpuUsage.clear(); - lastTime = timestamp; + recentCpuUsageMap.clear(); } - auto lastAppCpuUsage = lastCpuUsage.find(appId); + int prevTimestamp = timestamp; int prevUtime = 0; int prevStime = 0; - int prevTimestamp = INT_MAX; - int prevPid = 0; - - if (lastAppCpuUsage != lastCpuUsage.end()) { - prevTimestamp = (lastAppCpuUsage->second).timestamp; - prevUtime = (lastAppCpuUsage->second).utime; - prevStime = (lastAppCpuUsage->second).stime; - prevPid = (lastAppCpuUsage->second).pid; - // If the app is killed and launched again - if (pid != prevPid) { - prevUtime = 0; - prevStime = 0; - prevTimestamp = lastTime; + auto lastAppCpuUsage = recentCpuUsageMap.find(appId); + if (lastAppCpuUsage != recentCpuUsageMap.end()) { + // If the last info of the app exists + if ((lastAppCpuUsage->second).pid == pid) { + prevTimestamp = (lastAppCpuUsage->second).timestamp; + prevUtime = (lastAppCpuUsage->second).utime; + prevStime = (lastAppCpuUsage->second).stime; } - - 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, lastTime); - row.set(NULL, BATTERY_END_TIME, timestamp); - row.set(NULL, BATTERY_AMOUNT, 0); - row.set(NULL, BATTERY_UTIME, (int)(utimePerUnitTime * timeCurrPercent + 0.5)); - row.set(NULL, BATTERY_STIME, (int)(stimePerUnitTime * timeCurrPercent + 0.5)); - - usage->push_back(row); - - } else { - Json row; - row.set(NULL, BATTERY_APP_ID, appId); - 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); - row.set(NULL, BATTERY_STIME, stime); - - usage->push_back(row); } - LastAppCpuUsageInfo lastAppUsage; - lastAppUsage.timestamp = timestamp; - lastAppUsage.utime = utime; - 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* usage) -{ - std::vector 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++; + if (utime - prevUtime == 0 && stime - prevStime == 0) { + recentCpuUsageMap[appId].timestamp = timestamp; + continue; + } 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); - } - return true; -} - -bool BatteryUsageAnalyzer::normalize() -{ - _D("Normalizing battery usage data from time %d ", __timestampToNormalizeFrom); - std::vector batteryChanges; - char *sql = sqlite3_mprintf(BATTERY_INTERVALS_QUERY, __timestampToNormalizeFrom, CURRENT_TIME); - __dbMgr.executeSync(sql, &batteryChanges); - - unsigned int k = 0; - int batteryStartTime; - int batteryEndTime; + row.set(NULL, BATTERY_START_TIME, prevTimestamp); + row.set(NULL, BATTERY_END_TIME, timestamp); + row.set(NULL, BATTERY_UTIME, utime - prevUtime); + row.set(NULL, BATTERY_STIME, stime - prevStime); - while (k < batteryChanges.size()) { - batteryChanges[k].get(NULL, BATTERY_START_TIME, &batteryStartTime); - batteryChanges[k].get(NULL, BATTERY_END_TIME, &batteryEndTime); - k++; + usage->push_back(row); - sql = sqlite3_mprintf(NORMALIZE_QUERY, batteryStartTime, batteryEndTime, batteryStartTime, batteryEndTime, batteryStartTime, batteryEndTime); - __dbMgr.executeSync(sql, NULL); + // Store recent cpu usage info of the app + CpuLogInfo currentAppInfo; + currentAppInfo.timestamp = timestamp; + currentAppInfo.utime = utime; + currentAppInfo.stime = stime; + currentAppInfo.pid = pid; + recentCpuUsageMap[appId] = currentAppInfo; } - - __timestampToNormalizeFrom = INT_MAX; - sqlite3_free(sql); - return true; } diff --git a/src/battery-stats/BatteryUsageAnalyzer.h b/src/battery-stats/BatteryUsageAnalyzer.h index afea9f5..1e4ec73 100644 --- a/src/battery-stats/BatteryUsageAnalyzer.h +++ b/src/battery-stats/BatteryUsageAnalyzer.h @@ -19,24 +19,16 @@ #include #include -#include #include "BatteryStatisticsTypes.h" namespace ctx { class BatteryUsageAnalyzer { - public: BatteryUsageAnalyzer(); ~BatteryUsageAnalyzer(); - bool calculateBatteryUsage(int lastTime, int currTime, std::vector& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector* usage); - bool normalize(); - - private: - bool __addPreviousBatteryUsageLogs(int startTime, int endTime, std::string appId, double utimePerUnitTime, double stimePerUnitTime, std::vector* usage); - - DatabaseManager __dbMgr; + void calculateBatteryUsage(std::vector& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector* usage); }; } /* namespace ctx */ diff --git a/src/battery-stats/HeartDbReader.cpp b/src/battery-stats/HeartDbReader.cpp index b19a5a0..5d8126a 100644 --- a/src/battery-stats/HeartDbReader.cpp +++ b/src/battery-stats/HeartDbReader.cpp @@ -60,13 +60,13 @@ void HeartDbReader::close() __heartDb = NULL; } -bool HeartDbReader::readCpuUsageLog(int startTime, int endTime, std::vector* cpuUsageLog) +bool HeartDbReader::readCpuLog(int lastHeartAccessTime, std::vector* cpuUsageLog) { IF_FAIL_RETURN(__heartDb, false); char* sql = sqlite3_mprintf( "SELECT " HEART_APP_ID ", " HEART_TIME ", " HEART_DATA ", " HEART_INDEX " FROM " HEART_CPU_TABLE \ - " WHERE " HEART_TIME " >= %d AND " HEART_TIME " < %d", startTime, endTime); + " WHERE " HEART_TIME " > %d", lastHeartAccessTime); char* err = NULL; int ret = sqlite3_exec(__heartDb, sql, __cpuUsageLogCb, cpuUsageLog, &err); diff --git a/src/battery-stats/HeartDbReader.h b/src/battery-stats/HeartDbReader.h index 4c72902..ddf600e 100644 --- a/src/battery-stats/HeartDbReader.h +++ b/src/battery-stats/HeartDbReader.h @@ -24,7 +24,6 @@ namespace ctx { class HeartDbReader { - public: HeartDbReader(); ~HeartDbReader(); @@ -32,7 +31,7 @@ namespace ctx { bool open(); void close(); - bool readCpuUsageLog(int startTime, int endTime, std::vector* cpuUsageLog); + bool readCpuLog(int __lastHeartAccessTime, std::vector* cpuUsageLog); private: static int __cpuUsageLogCb(void *userData, int dim, char **value, char **column); diff --git a/src/battery-stats/Querier.cpp b/src/battery-stats/Querier.cpp index 15c8f95..f5ce03f 100644 --- a/src/battery-stats/Querier.cpp +++ b/src/battery-stats/Querier.cpp @@ -20,15 +20,15 @@ #include "Querier.h" #define BATTERY_USAGE_QUERY \ - "SELECT " BATTERY_APP_ID " AS " KEY_APP_ID ", ROUND(100.0 * SUM(" BATTERY_AMOUNT ") / " \ - "(SELECT SUM(" BATTERY_AMOUNT ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d)" \ + "SELECT " BATTERY_APP_ID " AS " KEY_APP_ID ", ROUND(100.0 * SUM(" BATTERY_TOTAL_TIME ") / " \ + "(SELECT SUM(" BATTERY_TOTAL_TIME ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d)" \ ", 2) AS " KEY_TOTAL_AMOUNT \ " FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d" \ " GROUP BY " KEY_APP_ID " ORDER BY " KEY_TOTAL_AMOUNT " DESC" #define RECENT_BATTERY_USAGE_QUERY \ - "SELECT " BATTERY_APP_ID " AS " KEY_APP_ID ", ROUND(100.0 * SUM(" BATTERY_AMOUNT ") / " \ - "(SELECT SUM(" BATTERY_AMOUNT ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d)" \ + "SELECT " BATTERY_APP_ID " AS " KEY_APP_ID ", ROUND(100.0 * SUM(" BATTERY_TOTAL_TIME ") / " \ + "(SELECT SUM(" BATTERY_TOTAL_TIME ") FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d)" \ ", 2) AS " KEY_TOTAL_AMOUNT \ ", %d AS " KEY_USED_TIME \ " FROM " BATTERY_USAGE_TABLE " WHERE " BATTERY_START_TIME " >= %d AND " BATTERY_END_TIME " <= %d" \ diff --git a/src/battery-stats/RecentBatteryUsage.cpp b/src/battery-stats/RecentBatteryUsage.cpp index 511b55b..f6954c7 100644 --- a/src/battery-stats/RecentBatteryUsage.cpp +++ b/src/battery-stats/RecentBatteryUsage.cpp @@ -37,14 +37,13 @@ int RecentBatteryUsageProvider::read(Json option, Json *requestResult) IF_FAIL_RETURN(querier, ERR_OPERATION_FAILED); int error; + int lastFullTime = BatteryMonitor::getInstance()->getLastFullTime(); if (hasLimit) { - error = querier->queryRecent(BatteryMonitor::getLastResetTime(), CURRENT_TIME, resultSize); + error = querier->queryRecent(lastFullTime, CURRENT_TIME, resultSize); } else { - error = querier->queryRecent(BatteryMonitor::getLastResetTime(), CURRENT_TIME); + error = querier->queryRecent(lastFullTime, CURRENT_TIME); } IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to get recent app battery usage"); return ERR_NONE; } - - -- 2.7.4