650a11e33fb05c008487b13791f532d41198d9ce
[platform/core/context/app-history.git] / src / server / battery-stats / HeartDbReader.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sstream>
18 #include <json/json.h>
19 #include <ServerUtil.h>
20 #include "BatteryStatisticsTypes.h"
21 #include "HeartDbReader.h"
22
23 #define HEART_CPU_TABLE "cpu"
24 #define HEART_APP_ID "appid"
25 #define HEART_TIME "time"
26 #define HEART_DATA "data"
27 #define HEART_INDEX "idx"
28
29 #define HEART_DB ".resourced-heart-default.db"
30
31 using namespace ctx;
32
33 HeartDbReader::HeartDbReader(uid_t uid) :
34         __heartDb(NULL),
35         __connection(NULL),
36         __dbRefCount(0),
37         __uid(uid)
38 {
39         __initializeDBusConnection();
40 }
41
42 HeartDbReader::~HeartDbReader()
43 {
44         if (__heartDb) {
45                 dbClose();
46         }
47
48         if (__connection) {
49                 __releaseDBusConnection();
50         }
51 }
52
53 bool HeartDbReader::dbOpen()
54 {
55         if (__heartDb) {
56                 __dbRefCount++;
57                 return true;
58         }
59
60         sqlite3 *db = NULL;
61         int ret;
62         ret = sqlite3_open_v2(util::get_user_path(__uid, TZ_USER_DB, HEART_DB).c_str(), &db, SQLITE_OPEN_READONLY, NULL);
63         IF_FAIL_RETURN_TAG(ret == SQLITE_OK, false, _E, "Failed to open HEART db: %s", sqlite3_errmsg(db));
64
65         __heartDb = db;
66         __dbRefCount++;
67
68         return true;
69 }
70
71 void HeartDbReader::dbClose()
72 {
73         if (__dbRefCount > 1) {
74                 __dbRefCount--;
75                 return;
76         }
77
78         sqlite3_close(__heartDb);
79         __heartDb = NULL;
80         __dbRefCount = 0;
81 }
82
83 bool HeartDbReader::readCpuLog(int lastHeartAccessTime, std::vector<Json::Value>* cpuUsageLog)
84 {
85         IF_FAIL_RETURN(__heartDb, false);
86
87         char* sql = sqlite3_mprintf(
88                                         "SELECT " HEART_APP_ID ", " HEART_TIME ", " HEART_DATA ", " HEART_INDEX " FROM " HEART_CPU_TABLE \
89                                         " WHERE " HEART_TIME " > %d AND " HEART_TIME " <= %d", lastHeartAccessTime, CURRENT_TIME);
90
91         char* err = NULL;
92         int ret = sqlite3_exec(__heartDb, sql, __cpuUsageLogCb, cpuUsageLog, &err);
93         sqlite3_free(sql);
94         if (ret != SQLITE_OK) {
95                 _E("Failed to read heart DB: Error(%s)", err);
96                 sqlite3_free(err);
97                 return false;
98         }
99
100         return true;
101 }
102
103 int HeartDbReader::__cpuUsageLogCb(void *userData, int dim, char **value, char **column)
104 {
105         IF_FAIL_RETURN(userData, 0);
106
107         std::vector<Json::Value> *records = static_cast<std::vector<Json::Value>*>(userData);
108         std::map<std::string, std::string> row;
109
110         bool columnNull = false;
111
112         for (int i = 0; i < dim; ++i) {
113                 if (!value[i]) {
114                         columnNull = true;
115                         _W(RED("Null columns exist"));
116                         break;
117                 }
118
119                 row[column[i]] = value[i];
120         }
121
122         if (columnNull)
123                 return 0;
124
125         auto convToJson = [](std::map<std::string, std::string>& in)->Json::Value {
126                 Json::Value jval;
127                 int utime;
128                 int stime;
129                 int pid;
130                 int type;
131
132                 std::stringstream buf(in[HEART_DATA]);
133                 buf >> utime >> stime >> pid >> type;
134
135                 jval[BATTERY_APP_ID] = in[HEART_APP_ID];
136                 jval[BATTERY_TIMESTAMP] = atoi(in[HEART_TIME].c_str());
137                 jval[BATTERY_INDEX] = atoi(in[HEART_INDEX].c_str());
138
139                 jval[BATTERY_UTIME] = utime;
140                 jval[BATTERY_STIME] = stime;
141                 jval[BATTERY_TYPE] = type;
142                 jval[BATTERY_PID] = pid;
143
144                 return jval;
145         };
146
147         records->push_back(convToJson(row));
148
149         return 0;
150 }
151
152 bool HeartDbReader::__initializeDBusConnection()
153 {
154 #if !GLIB_CHECK_VERSION(2, 36, 0)
155         g_type_init();
156 #endif
157         GError *error = NULL;
158
159         __connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
160         if (!__connection) {
161                 _E("dbus connection get failed: %s", error->message);
162                 g_error_free(error);
163                 return false;
164         }
165
166         return true;
167 }
168
169 void HeartDbReader::__releaseDBusConnection()
170 {
171         if (__connection) {
172                 g_object_unref(__connection);
173                 __connection = NULL;
174         }
175 }
176
177 bool HeartDbReader::requestSync()
178 {
179         IF_FAIL_RETURN_TAG(__connection, false, _E, "Dbus connection is not initialized");
180
181         GError *error = NULL;
182         GVariant* ret = NULL;
183         ret = g_dbus_connection_call_sync(__connection,
184                         "org.tizen.resourced", "/Org/Tizen/ResourceD/Logging", "org.tizen.resourced.logging",
185                         "SyncCpuData", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, 2000, NULL, &error);
186
187         if (error) {
188                 _E("Failed to dbus call: %s", error->message);
189                 g_clear_error(&error);
190                 return false;
191         }
192
193         int result;
194         g_variant_get(ret, "(i)", &result);
195         g_variant_unref(ret);
196         IF_FAIL_RETURN_TAG(result != -1, false, _E, "Failed to sync heart cpu data");
197
198         return true;
199 }