Improvement in battery statistics algorithm 04/105204/3
authorKunal <kunal.chawla@samsung.com>
Fri, 16 Dec 2016 03:41:44 +0000 (12:41 +0900)
committerKunal <kunal.chawla@samsung.com>
Fri, 16 Dec 2016 08:16:46 +0000 (17:16 +0900)
Spread battery consumption of an open app across all the battery percentages it was open.

Change-Id: Iff189f4968154d480fc46ab5fcc311507c86e99b
Signed-off-by: Kunal <kunal.chawla@samsung.com>
src/battery-stats/BatteryMonitor.cpp
src/battery-stats/BatteryMonitor.h
src/battery-stats/BatteryUsageAnalyzer.cpp
src/battery-stats/BatteryUsageAnalyzer.h

index 2a71946..57fc261 100644 (file)
@@ -40,7 +40,7 @@ static std::vector<Json> __batteryTimeInfoVec;
 #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()
 {
@@ -168,7 +168,8 @@ void BatteryMonitor::__chargerChangeCb(device_callback_e type, void* value, void
        }
 }
 
-gboolean BatteryMonitor::__timeoutCb(gpointer data) {
+gboolean BatteryMonitor::__timeoutCb(gpointer data)
+{
        BatteryMonitor* instance = static_cast<BatteryMonitor*>(data);
 
        bool dataRemaining = instance->processBatteryUsage();
@@ -298,8 +299,10 @@ bool BatteryMonitor::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");
@@ -308,7 +311,7 @@ bool BatteryMonitor::processBatteryUsage()
                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);
        }
index c97a2bc..08b9202 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <device/callback.h>
 #include <device/battery.h>
-#include <DatabaseManager.h>
 #include "BatteryUsageAnalyzer.h"
 
 namespace ctx {
index 9a01f02..61fe0c5 100644 (file)
  */
 
 #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)
@@ -49,8 +49,7 @@ bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std
        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);
@@ -76,7 +75,7 @@ bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std
                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()) {
@@ -92,16 +91,23 @@ bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std
                                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 {
@@ -113,8 +119,6 @@ bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std
                        row.set(NULL, BATTERY_UTIME, utime);
                        row.set(NULL, BATTERY_STIME, stime);
 
-                       totalStime += stime;
-                       totalUtime += utime;
                        usage->push_back(row);
                }
 
@@ -124,7 +128,64 @@ bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std
                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;
 }
index f5c8333..afea9f5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <vector>
 #include <Json.h>
+#include <DatabaseManager.h>
 #include "BatteryStatisticsTypes.h"
 
 namespace ctx {
@@ -26,14 +27,16 @@ namespace ctx {
        class BatteryUsageAnalyzer {
 
        public:
-               BatteryUsageAnalyzer() {};
-               ~BatteryUsageAnalyzer() {};
+               BatteryUsageAnalyzer();
+               ~BatteryUsageAnalyzer();
 
                bool calculateBatteryUsage(int lastTime, int currTime, std::vector<Json>& cpuUsageLog, CpuUsageMap& lastCpuUsage, std::vector<Json>* usage);
+               bool normalize();
 
        private:
-               void __normalizeBatteryUsage(std::vector<Json>* usage, int totalUtime, int totalStime);
+               bool __addPreviousBatteryUsageLogs(int startTime, int endTime, std::string appId, double utimePerUnitTime, double stimePerUnitTime, std::vector<Json>* usage);
 
+               DatabaseManager __dbMgr;
        };
 
 }      /* namespace ctx */