} subjectLibraryList[] = {
{SUBJ_ACTIVITY, "activity"},
{SUBJ_APP_STATS, "app-stats"},
+ {SUBJ_BATTERY_STATS, "battery-stats"},
{SUBJ_STATE_CALL, "call"},
{SUBJ_STATE_CONTACTS, "contacts"},
{SUBJ_CUSTOM, "custom"},
IF("${PROFILE}" STREQUAL "mobile")
ADD_SUBDIRECTORY(app-stats)
+ADD_SUBDIRECTORY(battery-stats)
ADD_SUBDIRECTORY(call)
ADD_SUBDIRECTORY(contacts)
ADD_SUBDIRECTORY(email)
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <sqlite3.h>
+#include <time.h>
+#include <glib.h>
+#include <Types.h>
+#include <Json.h>
+#include "BatteryStatisticsTypes.h"
+#include "HeartDbReader.h"
+#include "BatteryMonitor.h"
+
+#define DEFAULT_ROW_ID_STR "1"
+
+using namespace ctx;
+
+static int __lastResetTime = 0;
+static int __lastPercent = -1;
+static int __lastPercentTime = 0;
+static bool __isCharging = 0;
+static std::vector<Json> __batteryTimeInfoVec;
+
+
+BatteryMonitor::BatteryMonitor()
+{
+ __initialize();
+}
+
+BatteryMonitor::~BatteryMonitor()
+{
+}
+
+void BatteryMonitor::__initialize()
+{
+ std::vector<Json> records;
+ __dbMgr.executeSync(
+ "CREATE TABLE IF NOT EXISTS " BATTERY_USAGE_TABLE \
+ " (" BATTERY_USAGE_TABLE_COLUMNS ")", &records);
+
+ __dbMgr.executeSync(
+ "CREATE TABLE IF NOT EXISTS " BATTERY_LAST_INFO_TABLE \
+ " (" BATTERY_LAST_INFO_TABLE_COLUMNS ")", &records);
+
+ __dbMgr.createTableSync(BATTERY_TEMP_TIME_INFO, BATTERY_TEMP_TIME_INFO_COLUMNS, NULL);
+}
+
+bool BatteryMonitor::__loadLastInfo()
+{
+ device_battery_is_charging(&__isCharging);
+
+ std::vector<Json> records;
+ bool ret = __dbMgr.executeSync(
+ "SELECT * FROM " BATTERY_LAST_INFO_TABLE \
+ " WHERE " BATTERY_ROW_ID " = " DEFAULT_ROW_ID_STR, &records);
+ 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.clear();
+
+ __batteryTimeInfoVec.clear();
+ ret = __dbMgr.executeSync("SELECT * FROM " BATTERY_TEMP_TIME_INFO , &__batteryTimeInfoVec);
+
+ ret = __dbMgr.executeSync("DELETE FROM " BATTERY_TEMP_TIME_INFO, &records);
+
+ return true;
+}
+
+bool BatteryMonitor::__updateLastInfo()
+{
+ if (__batteryTimeInfoVec.size() > 0) {
+ for (unsigned int i = 0; i < __batteryTimeInfoVec.size(); i++) {
+ int64_t rowId;
+ __dbMgr.insertSync(BATTERY_TEMP_TIME_INFO, __batteryTimeInfoVec.at(i), &rowId);
+ }
+ }
+
+ IF_FAIL_RETURN_TAG(__lastResetTime != 0 || __lastPercentTime != 0, false, _W, "Last info doesn't exist");
+
+ char *query = sqlite3_mprintf(
+ "INSERT OR REPLACE INTO " BATTERY_LAST_INFO_TABLE " (" \
+ BATTERY_ROW_ID ", " BATTERY_LAST_RESET_TIME ", " \
+ BATTERY_LAST_PERCENT ", " BATTERY_LAST_PERCENT_TIME ") VALUES (%s, %d, %d, %d)",
+ DEFAULT_ROW_ID_STR, __lastResetTime, __lastPercent, __lastPercentTime);
+
+ std::vector<Json> records;
+ bool ret = __dbMgr.executeSync(query, &records);
+ sqlite3_free(query);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update battery stat last info");
+
+ return true;
+}
+
+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);
+ __batteryTimeInfoVec.push_back(battTimeInfo);
+
+ instance->processBatteryUsage();
+ }
+
+ __lastPercentTime = currentTime;
+ __lastPercent = percent;
+}
+
+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);
+
+ 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;
+ }
+
+ // 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);
+ }
+}
+
+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);
+ IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to set battery charging change cb");
+
+ return ERR_NONE;
+}
+
+int BatteryMonitor::stop()
+{
+ __updateLastInfo();
+
+ 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);
+ IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Failed to remove callback for charger status");
+
+ return ERR_NONE;
+}
+
+bool BatteryMonitor::processBatteryUsage()
+{
+ IF_FAIL_RETURN_TAG(__batteryTimeInfoVec.size() > 0, true, _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
+ HeartDbReader heartReader;
+ bool ret = heartReader.open();
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to open heart db");
+
+ std::vector<Json> appLog;
+ ret = heartReader.readAppLaunchLog(totalStartTime, totalEndTime, &appLog);
+ heartReader.close();
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Cannot read from heart cpu table");
+ IF_FAIL_RETURN_TAG(appLog.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", appLog.size(), totalStartTime, totalEndTime);
+
+ // Get the last timestamp of HEART cpu data
+ int lastHeartTimestamp;
+ appLog.back().get(NULL, BATTERY_TIMESTAMP, &lastHeartTimestamp);
+
+ 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, appLog, &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 = __insertUsageLog(usage);
+ if (!ret) {
+ _E("Failed to insert per app battery usage");
+ }
+ }
+
+ // Remove completed time info
+ _D("Total %d time intervals, %d intervals are calculated", __batteryTimeInfoVec.size(), i);
+ __batteryTimeInfoVec.erase(__batteryTimeInfoVec.begin(), __batteryTimeInfoVec.begin() + i);
+
+ return true;
+}
+
+bool BatteryMonitor::__insertUsageLog(std::vector<Json>& usage)
+{
+ IF_FAIL_RETURN_TAG(usage.size(), true, _W, "No data");
+ std::string query = std::string("INSERT INTO " BATTERY_USAGE_TABLE \
+ "(" BATTERY_APP_ID ", " BATTERY_START_TIME ", " BATTERY_END_TIME "," BATTERY_AMOUNT ") VALUES");
+
+ std::string appId;
+ int startTime;
+ int endTime;
+ double amount;
+
+ for (unsigned int i = 0; i < usage.size(); i++) {
+ usage[i].get(NULL, BATTERY_APP_ID, &appId);
+ usage[i].get(NULL, BATTERY_START_TIME, &startTime);
+ usage[i].get(NULL, BATTERY_END_TIME, &endTime);
+ usage[i].get(NULL, BATTERY_AMOUNT, &amount);
+
+ query += std::string(" ('" + appId + "', " + std::to_string(startTime) + ", " +
+ std::to_string(endTime) + ", " + std::to_string((int) (amount * 10000)) + ")");
+
+ if (i != usage.size() - 1 ) {
+ query += ", ";
+ }
+ }
+
+ _D("Insert %d rows of per app battery usage", usage.size());
+ std::vector<Json> records;
+ return __dbMgr.executeSync(query.c_str(), &records);
+}
+
+int BatteryMonitor::getLastResetTime()
+{
+ IF_FAIL_RETURN_TAG(__lastResetTime != 0, CURRENT_TIME, _D, "Last reset time doesn't exist");
+ return __lastResetTime;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_MONITOR_H_
+#define _CONTEXT_BATTERY_MONITOR_H_
+
+#include <device/callback.h>
+#include <device/battery.h>
+#include <DatabaseManager.h>
+#include "BatteryUsageAnalyzer.h"
+
+namespace ctx {
+
+ class BatteryMonitor {
+ public:
+ BatteryMonitor();
+ ~BatteryMonitor();
+
+ int start();
+ int stop();
+
+ static int getLastResetTime();
+ bool processBatteryUsage();
+
+ 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 __insertUsageLog(std::vector<Json>& usage);
+
+ DatabaseManager __dbMgr;
+ BatteryUsageAnalyzer __analyzer;
+
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_BATTERY_MONITOR_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_STATS_BATTERY_TYPES_H_
+#define _CONTEXT_STATS_BATTERY_TYPES_H_
+
+#include <ProviderTypes.h>
+
+#define BATTERY_HISTORY_PRIV PRIV_APP_HISTORY
+
+#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"
+
+#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"
+
+#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"
+
+#define BATTERY_APP_ID "AppId"
+#define BATTERY_TIMESTAMP "Timestamp"
+#define BATTERY_TYPE "Type"
+#define BATTERY_START_TIME "StartTime"
+#define BATTERY_END_TIME "EndTime"
+#define BATTERY_AMOUNT "Amount"
+#define BATTERY_LAST_RESET_TIME "LastResetTime"
+#define BATTERY_LAST_PERCENT "LastPercent"
+#define BATTERY_LAST_PERCENT_TIME "LastPercentTime"
+#define BATTERY_ROW_ID "RowId"
+
+#define CURRENT_TIME (int)(time(0))
+
+enum AppLaunchType {
+ TYPE_SERVICE = 0,
+ TYPE_FOREGROUND,
+ TYPE_BACKGROUND
+};
+
+#endif /* End of _CONTEXT_STATS_BATTERY_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BatteryStatisticsTypes.h"
+#include "BatteryMonitor.h"
+#include "BatteryStatsLogger.h"
+
+using namespace ctx;
+
+BatteryStatsLogger::BatteryStatsLogger() :
+ ContextProvider(SUBJ_BATTERY_LOGGER),
+ __monitor(NULL)
+{
+ __monitor = new(std::nothrow) BatteryMonitor();
+ IF_FAIL_VOID_TAG(__monitor, _E, "Memory allocation failed");
+}
+
+BatteryStatsLogger::~BatteryStatsLogger()
+{
+ delete __monitor;
+}
+
+void BatteryStatsLogger::getPrivilege(std::vector<const char*> &privilege)
+{
+ privilege.push_back(BATTERY_HISTORY_PRIV);
+}
+
+int BatteryStatsLogger::subscribe(Json option, Json* requestResult)
+{
+ return __monitor->start();
+}
+
+int BatteryStatsLogger::unsubscribe(Json option)
+{
+ return __monitor->stop();
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_STATS_LOGGER_H_
+#define _CONTEXT_BATTERY_STATS_LOGGER_H_
+
+#include <ContextProvider.h>
+
+namespace ctx {
+
+ class BatteryMonitor;
+
+ class BatteryStatsLogger : public ContextProvider {
+ public:
+ BatteryStatsLogger();
+ ~BatteryStatsLogger();
+
+ int subscribe(Json option, Json *requestResult);
+ int unsubscribe(Json option);
+
+ void getPrivilege(std::vector<const char*> &privilege);
+
+ private:
+ BatteryMonitor *__monitor;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_BATTERY_STATS_LOGGER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BatteryStatsProvider.h"
+
+using namespace ctx;
+
+BatteryStatsProvider::BatteryStatsProvider(const char *subject) :
+ ContextProvider(subject)
+{
+}
+
+BatteryStatsProvider::~BatteryStatsProvider()
+{
+}
+
+void BatteryStatsProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+ privilege.push_back(BATTERY_HISTORY_PRIV);
+}
+
+BatteryStatsQuerier* BatteryStatsProvider::getQuerier(Json option)
+{
+ BatteryStatsQuerier *querier = new(std::nothrow) BatteryStatsQuerier(this, option);
+ IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+ return querier;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_STATS_PROVIDER_H_
+#define _CONTEXT_BATTERY_STATS_PROVIDER_H_
+
+#include <ContextProvider.h>
+#include "BatteryStatisticsTypes.h"
+#include "Querier.h"
+
+namespace ctx {
+
+ class BatteryStatsProvider : public ContextProvider {
+ public:
+ virtual int read(Json option, Json *requestResult) = 0;
+ void getPrivilege(std::vector<const char*> &privilege);
+
+ protected:
+ BatteryStatsProvider(const char *subject);
+ virtual ~BatteryStatsProvider();
+
+ BatteryStatsQuerier* getQuerier(Json option);
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_BATTERY_STATS_PROVIDER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BatteryUsage.h"
+
+#define SECONDS_IN_A_DAY 86400
+
+using namespace ctx;
+
+BatteryUsageProvider::BatteryUsageProvider() :
+ BatteryStatsProvider(SUBJ_BATTERY_USAGE)
+{
+}
+
+BatteryUsageProvider::~BatteryUsageProvider()
+{
+}
+
+int BatteryUsageProvider::read(Json option, Json *requestResult)
+{
+ int startTime;
+ int endTime;
+ int timeSpan = DEFAULT_TIME_SPAN;
+ int timeSpanPoint;
+
+ option.get(NULL, KEY_TIME_SPAN, &timeSpan);
+ timeSpanPoint = CURRENT_TIME - timeSpan * SECONDS_IN_A_DAY;
+
+ if (!option.get(NULL, KEY_START_TIME, &startTime)) {
+ startTime = timeSpanPoint;
+ }
+
+ if (!option.get(NULL, KEY_END_TIME, &endTime)) {
+ endTime = CURRENT_TIME;
+ }
+
+ int resultSize;
+ bool hasLimit = option.get(NULL, KEY_RESULT_SIZE, &resultSize);
+
+ BatteryStatsQuerier *querier = getQuerier(option);
+ IF_FAIL_RETURN(querier, ERR_OPERATION_FAILED);
+
+ int error;
+ if (hasLimit) {
+ error = querier->queryRangeLimit((startTime > timeSpanPoint)? startTime : timeSpanPoint, endTime, resultSize);
+ } else {
+ error = querier->queryRange((startTime > timeSpanPoint)? startTime : timeSpanPoint, endTime);
+ }
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to get app battery usage");
+
+ return ERR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_USAGE_PROVIDER_H_
+#define _CONTEXT_BATTERY_USAGE_PROVIDER_H_
+
+#include "BatteryStatsProvider.h"
+
+namespace ctx {
+
+ class BatteryUsageProvider : public BatteryStatsProvider {
+
+ public:
+ BatteryUsageProvider();
+ ~BatteryUsageProvider();
+
+ int read(Json option, Json *requestResult);
+ };
+}
+
+#endif /* _CONTEXT_BATTERY_USAGE_PROVIDER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <Types.h>
+#include "BatteryStatisticsTypes.h"
+#include "BatteryUsageAnalyzer.h"
+
+using namespace ctx;
+
+bool BatteryUsageAnalyzer::calculateBatteryUsage(int lastTime, int currTime, std::vector<Json>& appLog, std::vector<Json>* usage)
+{
+ int timeInterval = currTime - lastTime;
+ IF_FAIL_RETURN(timeInterval > 0, false);
+
+ std::map<std::string, int> lastAppTimeMap;
+ std::string appId;
+ int timestamp;
+ int type;
+
+ for (unsigned int i = 0; i < appLog.size(); i++) {
+ appLog[i].get(NULL, BATTERY_APP_ID, &appId);
+ appLog[i].get(NULL, BATTERY_TIMESTAMP, ×tamp);
+ appLog[i].get(NULL, BATTERY_TYPE, &type);
+
+ if (timestamp < lastTime) {
+ continue;
+ }
+
+ if (timestamp > currTime) {
+ break;
+ }
+
+ if (type == TYPE_FOREGROUND) { // Mark timestamp of foreground
+ lastAppTimeMap[appId] = timestamp;
+ } else if (type == TYPE_BACKGROUND) { // Foreground duration calculation (Foreground->Background)
+ Json row;
+ if (lastAppTimeMap.find(appId) == lastAppTimeMap.end() || lastAppTimeMap[appId] == 0) {
+ __createBatteryUsage(appId, lastTime, timestamp, timeInterval, &row);
+ } else {
+ __createBatteryUsage(appId, lastAppTimeMap[appId], timestamp, timeInterval, &row);
+ lastAppTimeMap[appId] = 0;
+ }
+ usage->push_back(row);
+ }
+ }
+
+ // Not closed app
+ for (auto it = lastAppTimeMap.begin(); it != lastAppTimeMap.end(); it++) {
+ if (it->second == 0) {
+ continue;
+ }
+
+ Json row;
+ __createBatteryUsage(it->first, it->second, currTime, timeInterval, &row);
+ usage->push_back(row);
+ }
+
+ return true;
+}
+
+void BatteryUsageAnalyzer::__createBatteryUsage(std::string appId, int startTime, int endTime, int timeInterval, Json* record)
+{
+ record->set(NULL, BATTERY_APP_ID, appId);
+ record->set(NULL, BATTERY_START_TIME, startTime);
+ record->set(NULL, BATTERY_END_TIME, endTime);
+ record->set(NULL, BATTERY_AMOUNT, (double)(endTime - startTime) / (double)timeInterval);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_USAGE_ANALYZER_H_
+#define _CONTEXT_BATTERY_USAGE_ANALYZER_H_
+
+#include <vector>
+#include <Json.h>
+
+namespace ctx {
+
+ class BatteryUsageAnalyzer {
+
+ public:
+ BatteryUsageAnalyzer() {};
+ ~BatteryUsageAnalyzer() {};
+
+ bool calculateBatteryUsage(int lastTime, int currTime, std::vector<Json>& appLog, std::vector<Json>* usage);
+
+ private:
+ void __createBatteryUsage(std::string appId, int startTime, int endTime, int timeInterval, Json* record);
+
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_BATTERY_USAGE_ANALYZER_H_ */
--- /dev/null
+SET(target "${target_prefix}-battery-stats")
+
+SET(DEPS ${DEPS}
+ capi-system-device
+)
+
+FILE(GLOB SRCS *.cpp)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PKG_BATTERY_STATS REQUIRED ${DEPS})
+
+FOREACH(flag ${PKG_BATTERY_STATS_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${PKG_BATTERY_LDFLAGS} ${target_shared})
+
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir})
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <CreateProvider.h>
+#include "BatteryStatsLogger.h"
+#include "BatteryUsage.h"
+#include "RecentBatteryUsage.h"
+
+using namespace ctx;
+
+extern "C" SO_EXPORT ContextProvider* CreateProvider(const char *subject)
+{
+ ADD_PROVIDER(SUBJ_BATTERY_LOGGER, BatteryStatsLogger);
+ ADD_PROVIDER(SUBJ_BATTERY_USAGE, BatteryUsageProvider);
+ ADD_PROVIDER(SUBJ_BATTERY_RECENT_USAGE, RecentBatteryUsageProvider);
+
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#include <sstream>
+#include <Json.h>
+#include "BatteryStatisticsTypes.h"
+#include "HeartDbReader.h"
+
+#define HEART_CPU_TABLE "cpu"
+#define HEART_APP_ID "appid"
+#define HEART_TIME "time"
+#define HEART_DATA "data"
+
+#ifdef LEGACY_FILE_PATH
+#define HEART_DB_PATH "/opt/usr/dbspace/.resourced-logging.db"
+#else
+#include <tzplatform_config.h>
+#define HEART_DB_PATH tzplatform_mkpath(TZ_USER_DB, ".resourced-heart-default.db")
+#endif
+
+using namespace ctx;
+
+HeartDbReader::HeartDbReader() :
+ __heartDb(NULL)
+{
+}
+
+HeartDbReader::~HeartDbReader()
+{
+ if (__heartDb) {
+ close();
+ }
+}
+
+bool HeartDbReader::open()
+{
+ 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;
+
+ return true;
+}
+
+void HeartDbReader::close()
+{
+ sqlite3_close(__heartDb);
+ __heartDb = NULL;
+}
+
+bool HeartDbReader::readAppLaunchLog(int startTime, int endTime, std::vector<Json>* appLog)
+{
+ IF_FAIL_RETURN(__heartDb, false);
+
+ char* sql = sqlite3_mprintf(
+ "SELECT " HEART_APP_ID ", " HEART_TIME ", " HEART_DATA " FROM " HEART_CPU_TABLE \
+ " WHERE " HEART_TIME " >= %d AND " HEART_TIME " < %d", startTime, endTime);
+
+ char* err = NULL;
+ int ret = sqlite3_exec(__heartDb, sql, __appLaunchLogCb, appLog, &err);
+ sqlite3_free(sql);
+ if (ret != SQLITE_OK) {
+ _E("Failed to read heart DB: Error(%s)", err);
+ sqlite3_free(err);
+ return false;
+ }
+
+ return true;
+}
+
+int HeartDbReader::__appLaunchLogCb(void *userData, int dim, char **value, char **column)
+{
+ IF_FAIL_RETURN(userData, 0);
+
+ std::vector<Json> *records = static_cast<std::vector<Json>*>(userData);
+ Json row;
+ Json newRow;
+ bool columnNull = false;
+
+ for (int i = 0; i < dim; ++i) {
+ if (!value[i]) {
+ columnNull = true;
+ _W(RED("Null columns exist"));
+ break;
+ }
+
+ row.set(NULL, column[i], value[i]);
+ }
+
+ if (!columnNull) {
+ __convertAppLaunchLog(row, &newRow);
+ records->push_back(newRow);
+ }
+
+ return 0;
+}
+
+void HeartDbReader::__convertAppLaunchLog(Json& row, Json* newRow)
+{
+ std::string appId;
+ std::string timestamp;
+ std::string data;
+/* int utime;
+ int stime;
+ int pid;
+ int type;
+*/
+ row.get(NULL, HEART_APP_ID, &appId);
+ row.get(NULL, HEART_TIME, ×tamp);
+ row.get(NULL, HEART_DATA, &data);
+/*
+ std::stringstream buf = data; // TODO use utim & stime
+ buf >> utime >> stime >> pid >> type;
+*/
+ std::string type = data.substr(data.length() - 2, 1);
+
+ newRow->set(NULL, BATTERY_APP_ID, appId);
+ newRow->set(NULL, BATTERY_TIMESTAMP, atoi(timestamp.c_str()));
+ newRow->set(NULL, BATTERY_TYPE, atoi(type.c_str()));
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_HEART_DB_READER_H_
+#define _CONTEXT_HEART_DB_READER_H_
+
+#include <Types.h>
+#include <vector>
+#include <sqlite3.h>
+
+namespace ctx {
+
+ class HeartDbReader {
+
+ public:
+ HeartDbReader();
+ ~HeartDbReader();
+
+ bool open();
+ void close();
+
+ bool readAppLaunchLog(int startTime, int endTime, std::vector<Json>* appLog);
+
+ private:
+ static int __appLaunchLogCb(void *userData, int dim, char **value, char **column);
+ static void __convertAppLaunchLog(Json& row, Json* newRow);
+
+ sqlite3 *__heartDb;
+ };
+
+} /* namespace ctx */
+
+#endif /* _CONTEXT_HEART_DB_READER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sqlite3.h>
+#include <Types.h>
+#include "BatteryStatisticsTypes.h"
+#include "Querier.h"
+
+#define BATTERY_USAGE_DEFAULT_QUERY \
+ "SELECT " BATTERY_APP_ID " AS " KEY_APP_ID ", ROUND(SUM(" BATTERY_AMOUNT ")/10000.0, 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"
+
+using namespace ctx;
+
+BatteryStatsQuerier::BatteryStatsQuerier(ContextProvider *provider, Json option) :
+ __provider(provider),
+ __option(option)
+{
+}
+
+BatteryStatsQuerier::~BatteryStatsQuerier()
+{
+}
+
+int BatteryStatsQuerier::query(const char *sql)
+{
+ return __dbMgr.execute(0, sql, this) ? ERR_NONE : ERR_OPERATION_FAILED;
+}
+
+int BatteryStatsQuerier::queryRange(int startTime, int endTime)
+{
+ char *sql = sqlite3_mprintf(BATTERY_USAGE_DEFAULT_QUERY, startTime, endTime);
+
+ int error = query(sql);
+ sqlite3_free(sql);
+
+ return error;
+}
+
+int BatteryStatsQuerier::queryRangeLimit(int startTime, int endTime, int resultSize)
+{
+ char *sql = sqlite3_mprintf(BATTERY_USAGE_DEFAULT_QUERY " LIMIT %d", startTime, endTime, resultSize);
+
+ int error = query(sql);
+ sqlite3_free(sql);
+
+ return error;
+}
+
+void BatteryStatsQuerier::onTableCreated(unsigned int queryId, int error)
+{
+}
+
+void BatteryStatsQuerier::onInserted(unsigned int queryId, int error, int64_t rowId)
+{
+}
+
+void BatteryStatsQuerier::onExecuted(unsigned int queryId, int error, std::vector<Json>& records)
+{
+ Json response;
+ __convertToResponse(records, response);
+ __provider->replyToRead(__option, error, response);
+
+ delete this;
+}
+
+void BatteryStatsQuerier::__convertToResponse(std::vector<Json> &sqlResult, Json &response)
+{
+ response = "{\"" KEY_QUERY_RESULT "\":[]}";
+
+ for (Json& tuple : sqlResult) {
+ response.append(NULL, KEY_QUERY_RESULT, tuple);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_BATTERY_STATS_QUERIER_H_
+#define _CONTEXT_BATTERY_STATS_QUERIER_H_
+
+#include <ContextProvider.h>
+#include <DatabaseManager.h>
+
+namespace ctx {
+
+ class BatteryStatsQuerier : public IDatabaseListener {
+ public:
+ BatteryStatsQuerier(ContextProvider *provider, Json option);
+ ~BatteryStatsQuerier();
+
+ // For now, Default result size(10) isn't applied, unlike other history type.
+ int queryRange(int startTime, int endTime);
+ int queryRangeLimit(int startTime, int endTime, int resultSize);
+
+ protected:
+ int query(const char *sql);
+
+ void onTableCreated(unsigned int queryId, int error);
+ void onInserted(unsigned int queryId, int error, int64_t rowId);
+ void onExecuted(unsigned int queryId, int error, std::vector<Json>& records);
+
+ private:
+ void __convertToResponse(std::vector<Json> &sqlResult, Json& response);
+
+ DatabaseManager __dbMgr;
+ ContextProvider *__provider;
+ Json __option;
+ };
+}
+
+#endif /* _CONTEXT_BATTERY_STATS_QUERIER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BatteryMonitor.h"
+#include "RecentBatteryUsage.h"
+
+using namespace ctx;
+
+RecentBatteryUsageProvider::RecentBatteryUsageProvider() :
+ BatteryStatsProvider(SUBJ_BATTERY_RECENT_USAGE)
+{
+}
+
+RecentBatteryUsageProvider::~RecentBatteryUsageProvider()
+{
+}
+
+int RecentBatteryUsageProvider::read(Json option, Json *requestResult)
+{
+ int resultSize;
+ bool hasLimit = option.get(NULL, KEY_RESULT_SIZE, &resultSize);
+
+ BatteryStatsQuerier *querier = getQuerier(option);
+ IF_FAIL_RETURN(querier, ERR_OPERATION_FAILED);
+
+ int error;
+ if (hasLimit) {
+ error = querier->queryRangeLimit(BatteryMonitor::getLastResetTime(), CURRENT_TIME, resultSize);
+ } else {
+ error = querier->queryRange(BatteryMonitor::getLastResetTime(), CURRENT_TIME);
+ }
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, ERR_OPERATION_FAILED, _E, "Failed to get recent app battery usage");
+
+ return ERR_NONE;
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CONTEXT_RECENT_BATTERY_USAGE_PROVIDER_H_
+#define _CONTEXT_RECENT_BATTERY_USAGE_PROVIDER_H_
+
+#include "BatteryStatsProvider.h"
+
+namespace ctx {
+
+ class RecentBatteryUsageProvider : public BatteryStatsProvider {
+ public:
+ RecentBatteryUsageProvider();
+ ~RecentBatteryUsageProvider();
+
+ int read(Json option, Json *requestResult);
+ };
+}
+
+#endif /* _CONTEXT_RECENT_BATTERY_USAGE_PROVIDER_H_ */