[battery-stats] modified to provide data while charging 08/106408/7
authorSomin Kim <somin926.kim@samsung.com>
Wed, 21 Dec 2016 12:30:46 +0000 (21:30 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Thu, 22 Dec 2016 04:16:26 +0000 (13:16 +0900)
Change-Id: Ib3c0e62bdda97bec3dc7960da376bd1dc235d9d9
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
12 files changed:
src/battery-stats/BatteryMonitor.cpp
src/battery-stats/BatteryMonitor.h
src/battery-stats/BatteryStatisticsTypes.h
src/battery-stats/BatteryStatsLogger.cpp
src/battery-stats/BatteryStatsLogger.h
src/battery-stats/BatteryUsage.h
src/battery-stats/BatteryUsageAnalyzer.cpp
src/battery-stats/BatteryUsageAnalyzer.h
src/battery-stats/HeartDbReader.cpp
src/battery-stats/HeartDbReader.h
src/battery-stats/Querier.cpp
src/battery-stats/RecentBatteryUsage.cpp

index 57fc261f417982a8763cf16f50abf748fc3dfa8b..e19633887184f956528b87922ac2a95b5c716092 100644 (file)
 #include <sqlite3.h>
 #include <time.h>
 #include <glib.h>
+#include <device/battery.h>
 #include <Types.h>
 #include <Json.h>
 #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<Json> __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<Json> 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<Json> 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<BatteryMonitor*>(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<BatteryMonitor*>(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<BatteryMonitor*>(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<Json> 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<Json> 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, &timestamp);
-               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, &timestamp);
+               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<Json> cpuUsageLog;
-       ret = heartReader.readCpuUsageLog(totalStartTime, totalEndTime, &cpuUsageLog);
+       std::vector<Json> 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<Json> 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<Json> 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<Json>& 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<Json>& 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<Json>& 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;
 }
index 08b9202c465be0c3cd63502196b8605c870d9065..c6c10a8ea2fb229c7c02e0160912ed7cd87faefe 100644 (file)
@@ -18,7 +18,7 @@
 #define _CONTEXT_BATTERY_MONITOR_H_
 
 #include <device/callback.h>
-#include <device/battery.h>
+#include <DatabaseManager.h>
 #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<Json>& 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 */
index d9bead6cb9e3600191cc4a77c417020442dc5576..11dd915dedd061da74b13586fab8a653c6d92010 100644 (file)
 
 #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 \
 #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<std::string, LastAppCpuUsageInfo> CpuUsageMap;
+       typedef std::map<std::string, CpuLogInfo> CpuUsageMap;
 }
 
 enum AppLaunchType {
index 89e0309d430ec33490cb3487d8f3014e3ddb7a8f..3b7af4991e1851f2f04678354916e319604252ab 100644 (file)
 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<const char*> &privilege)
@@ -40,10 +38,10 @@ void BatteryStatsLogger::getPrivilege(std::vector<const char*> &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();
 }
index 026b72e7337f15cdd3620df0f59fcff8e11aa0d6..ef02bb1850c993b2af1d202f2e0c9e52566d2cd1 100644 (file)
@@ -32,9 +32,6 @@ namespace ctx {
                int unsubscribe(Json option);
 
                void getPrivilege(std::vector<const char*> &privilege);
-
-       private:
-               BatteryMonitor *__monitor;
        };
 
 }      /* namespace ctx */
index f446dd31e71a0708734d88700b0e96a5f33c22f5..bc748baf3661f6df9d935ed5dffd156fd4897eca 100644 (file)
@@ -22,7 +22,6 @@
 namespace ctx {
 
        class BatteryUsageProvider : public BatteryStatsProvider {
-
        public:
                BatteryUsageProvider();
                ~BatteryUsageProvider();
index 61fe0c5c3e460518d39412297883d53b96cb6f88..bb08d8b34f1b6635cac999892aa90ee04cf5998a 100644 (file)
  */
 
 #include <map>
-#include <sqlite3.h>
 #include <Types.h>
 #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<Json>& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector<Json>* usage)
+void BatteryUsageAnalyzer::calculateBatteryUsage(std::vector<Json>& cpuLog, CpuUsageMap& recentCpuUsageMap, std::vector<Json>* 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, &timestamp);
-               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, &timestamp);
+               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<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++;
+               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<Json> 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;
 }
index afea9f5a8f9652e4bbdad8865da5ff6bcc701fde..1e4ec73eafadb1d79ef801195426d440330d0f7c 100644 (file)
 
 #include <vector>
 #include <Json.h>
-#include <DatabaseManager.h>
 #include "BatteryStatisticsTypes.h"
 
 namespace ctx {
 
        class BatteryUsageAnalyzer {
-
        public:
                BatteryUsageAnalyzer();
                ~BatteryUsageAnalyzer();
 
-               bool calculateBatteryUsage(int lastTime, int currTime, std::vector<Json>& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector<Json>* usage);
-               bool normalize();
-
-       private:
-               bool __addPreviousBatteryUsageLogs(int startTime, int endTime, std::string appId, double utimePerUnitTime, double stimePerUnitTime, std::vector<Json>* usage);
-
-               DatabaseManager __dbMgr;
+               void calculateBatteryUsage(std::vector<Json>& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector<Json>* usage);
        };
 
 }      /* namespace ctx */
index b19a5a05be52384bae4e08f4bde702fcaa6ae0cf..5d8126a368efe93e16fb03e9593a4657cd4aed04 100644 (file)
@@ -60,13 +60,13 @@ void HeartDbReader::close()
        __heartDb = NULL;
 }
 
-bool HeartDbReader::readCpuUsageLog(int startTime, int endTime, std::vector<Json>* cpuUsageLog)
+bool HeartDbReader::readCpuLog(int lastHeartAccessTime, std::vector<Json>* 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);
index 4c72902f1828f578ba9fab11816e6a9e6ac9b783..ddf600e12a296169188478a9172bd3905d87c720 100644 (file)
@@ -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<Json>* cpuUsageLog);
+               bool readCpuLog(int __lastHeartAccessTime, std::vector<Json>* cpuUsageLog);
 
        private:
                static int __cpuUsageLogCb(void *userData, int dim, char **value, char **column);
index 15c8f95adb53830918adab1c8cefa6ae66ca985e..f5ce03f79f74124cb00d434733e492aabdeaaf85 100644 (file)
 #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" \
index 511b55b11fc88b4969769bcab29db5b344ea193e..f6954c793f889d1fbe9bea5509cb9531ce604391 100644 (file)
@@ -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;
 }
-
-