#include <device/battery.h>
#include <Types.h>
#include <Json.h>
-#include "HeartDbReader.h"
#include "BatteryMonitor.h"
#define DEFAULT_ROW_ID_STR "1"
BatteryMonitor::BatteryMonitor() :
__bootingTime(0),
__lastFullTime(0),
- __lastHeartAccessTime(0)
+ __lastHeartAccessTime(0),
+ __heartReader(NULL)
{
}
int BatteryMonitor::start()
{
+ __heartReader = new(std::nothrow) HeartDbReader();
+ IF_FAIL_RETURN_TAG(__heartReader, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
__loadLastInfo();
int error = device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb, this);
int BatteryMonitor::stop()
{
+ if (__heartReader) {
+ delete __heartReader;
+ __heartReader = NULL;
+ }
+
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");
bool BatteryMonitor::__processBatteryUsage()
{
// Read from heart cpu table
- HeartDbReader heartReader;
- bool ret = heartReader.open();
+ bool ret = __heartReader->dbOpen();
IF_FAIL_RETURN_TAG(ret, true, _E, "Failed to open heart db");
std::vector<Json> heartCpuLog;
- ret = heartReader.readCpuLog(__lastHeartAccessTime, &heartCpuLog);
- heartReader.close();
+ ret = __heartReader->readCpuLog(__lastHeartAccessTime, &heartCpuLog);
+ __heartReader->dbClose();
IF_FAIL_RETURN_TAG(ret, true, _E, "Cannot read from heart cpu table");
IF_FAIL_RETURN_TAG(heartCpuLog.size() > 0, true, _W, "Heart cpu data is not prepared");
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");
return __lastFullTime;
}
+
+void BatteryMonitor::prepareData()
+{
+ int timeDiff = CURRENT_TIME - __lastHeartAccessTime;
+ IF_FAIL_VOID_TAG(timeDiff >= 5 * 60 * 1000,
+ _D, "Battery usage was updated %d minutes ago", timeDiff / 60000);
+
+ _D("Request to sync heart cpu data");
+ bool ret = __heartReader->requestSync();
+ IF_FAIL_VOID_TAG(ret, _E, "Failed to sync heart db");
+
+ __processBatteryUsage();
+}
#include <device/callback.h>
#include <DatabaseManager.h>
#include "BatteryUsageAnalyzer.h"
+#include "HeartDbReader.h"
namespace ctx {
int start();
int stop();
int getLastFullTime();
+ void prepareData();
private:
bool __loadLastInfo();
DatabaseManager __dbMgr;
BatteryUsageAnalyzer __analyzer;
+ HeartDbReader *__heartReader;
};
} /* namespace ctx */
* limitations under the License.
*/
+#include "BatteryMonitor.h"
#include "BatteryUsage.h"
#define SECONDS_IN_A_DAY 86400
int BatteryUsageProvider::read(Json option, Json *requestResult)
{
+ BatteryMonitor::getInstance()->prepareData();
+
int startTime;
int endTime;
int timeSpan = DEFAULT_TIME_SPAN;
using namespace ctx;
HeartDbReader::HeartDbReader() :
- __heartDb(NULL)
+ __heartDb(NULL),
+ __connection(NULL),
+ __dbRefCount(0)
{
+ __initializeDBusConnection();
}
HeartDbReader::~HeartDbReader()
{
if (__heartDb) {
- close();
+ dbClose();
+ }
+
+ if (__connection) {
+ __releaseDBusConnection();
}
}
-bool HeartDbReader::open()
+bool HeartDbReader::dbOpen()
{
+ if (__heartDb) {
+ __dbRefCount++;
+ return true;
+ }
+
sqlite3 *db = NULL;
int ret;
ret = sqlite3_open_v2(HEART_DB_PATH, &db, SQLITE_OPEN_READONLY, NULL);
IF_FAIL_RETURN_TAG(ret == SQLITE_OK, false, _E, "Failed to open HEART db: %s", sqlite3_errmsg(db));
__heartDb = db;
+ __dbRefCount++;
return true;
}
-void HeartDbReader::close()
+void HeartDbReader::dbClose()
{
+ if (__dbRefCount > 1) {
+ __dbRefCount--;
+ return;
+ }
+
sqlite3_close(__heartDb);
__heartDb = NULL;
+ __dbRefCount = 0;
}
bool HeartDbReader::readCpuLog(int lastHeartAccessTime, std::vector<Json>* cpuUsageLog)
newRow->set(NULL, BATTERY_INDEX, index);
newRow->set(NULL, BATTERY_PID, pid);
}
+
+bool HeartDbReader::__initializeDBusConnection()
+{
+#if !GLIB_CHECK_VERSION(2, 36, 0)
+ g_type_init();
+#endif
+ GError *error = NULL;
+
+ __connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!__connection) {
+ _E("dbus connection get failed: %s", error->message);
+ g_error_free(error);
+ return false;
+ }
+
+ return true;
+}
+
+void HeartDbReader::__releaseDBusConnection()
+{
+ if (__connection) {
+ g_object_unref(__connection);
+ __connection = NULL;
+ }
+}
+
+bool HeartDbReader::requestSync()
+{
+ IF_FAIL_RETURN_TAG(__connection, false, _E, "Dbus connection is not initialized");
+
+ GError *error = NULL;
+ GVariant* ret = NULL;
+ ret = g_dbus_connection_call_sync(__connection,
+ "org.tizen.resourced", "/Org/Tizen/ResourceD/Logging", "org.tizen.resourced.logging",
+ "SyncCpuData", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 2000, NULL, &error);
+
+ if (error) {
+ _E("Failed to dbus call: %s", error->message);
+ g_clear_error(&error);
+ return false;
+ }
+
+ int result;
+ g_variant_get(ret, "(i)", &result);
+ g_variant_unref(ret);
+ IF_FAIL_RETURN_TAG(result != -1, false, _E, "Failed to sync heart cpu data");
+
+ return true;
+}
#ifndef _CONTEXT_HEART_DB_READER_H_
#define _CONTEXT_HEART_DB_READER_H_
-#include <Types.h>
#include <vector>
+#include <glib.h>
+#include <gio/gio.h>
#include <sqlite3.h>
+#include <Types.h>
namespace ctx {
HeartDbReader();
~HeartDbReader();
- bool open();
- void close();
-
+ bool dbOpen();
+ void dbClose();
bool readCpuLog(int __lastHeartAccessTime, std::vector<Json>* cpuUsageLog);
+ bool requestSync();
private:
static int __cpuUsageLogCb(void *userData, int dim, char **value, char **column);
static void __convertCpuUsageLog(Json& row, Json* newRow);
+ bool __initializeDBusConnection();
+ void __releaseDBusConnection();
+
sqlite3 *__heartDb;
+ GDBusConnection *__connection;
+ int __dbRefCount;
};
} /* namespace ctx */
int RecentBatteryUsageProvider::read(Json option, Json *requestResult)
{
+ BatteryMonitor::getInstance()->prepareData();
+
int resultSize;
bool hasLimit = option.get(NULL, KEY_RESULT_SIZE, &resultSize);