sensor: rename SensorProxy::start() and stop() to listen() and unlisten()
[platform/core/context/context-provider.git] / src / sensor / pedometer / PedometerLogger.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 <sqlite3.h>
18 #include <SensorRecorderTypes.h>
19 #include "../TypesInternal.h"
20 #include "../ClientInfo.h"
21 #include "../TimeUtil.h"
22 #include "PedometerLogger.h"
23
24 using namespace ctx;
25
26 PedometerLogger::PedometerLogger() :
27         __firstEvent(true)
28 {
29         setSensor(HUMAN_PEDOMETER_SENSOR);
30         setPowerSave(false);
31
32         /* Create the log table */
33         executeQuery(
34                         "CREATE TABLE IF NOT EXISTS " PEDOMETER_RECORD " (" \
35                                 KEY_START_TIME " INTEGER NOT NULL, " \
36                                 KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \
37                                 KEY_WALK_STEPS " INTEGER NOT NULL, " \
38                                 KEY_RUN_STEPS " INTEGER NOT NULL, " \
39                                 KEY_DISTANCE " REAL NOT NULL, " \
40                                 KEY_CALORIES " REAL NOT NULL" \
41                         ")");
42
43         ClientInfo clientInfo;
44         if (clientInfo.exist(SUBJ_SENSOR_PEDOMETER))
45                 start();
46 }
47
48 PedometerLogger::~PedometerLogger()
49 {
50         stop();
51 }
52
53 bool PedometerLogger::start()
54 {
55         IF_FAIL_RETURN_TAG(!isRunning(), true, _D, "Started already");
56         _I(GREEN("Start to record"));
57
58         if (listen()) {
59                 flush();
60                 return true;
61         }
62
63         return false;
64 }
65
66 void PedometerLogger::stop()
67 {
68         IF_FAIL_VOID_TAG(isRunning(), _D, "Stopped already");
69         _I(GREEN("Stop recording"));
70
71         unlisten();
72         __firstEvent = true;
73 }
74
75 void PedometerLogger::onEvent(sensor_data_t *eventData)
76 {
77         sensor_pedometer_data_t *pedometerData = reinterpret_cast<sensor_pedometer_data_t*>(eventData);
78         uint64_t timestamp = TimeUtil::getTime();
79
80         if (__firstEvent) {
81                 _D("Baseline event");
82                 __firstEvent = false;
83         } else if (pedometerData->diffs_count == 0) {
84                 _D("Single event");
85                 __recordSingle(pedometerData, timestamp);
86         } else {
87                 _D("Batch event");
88                 __recordBatch(pedometerData, timestamp);
89         }
90
91         __baseline.timestamp = timestamp;
92         __baseline.walkSteps = eventData->values[1];
93         __baseline.runSteps  = eventData->values[2];
94         __baseline.distance  = eventData->values[3];
95         __baseline.calories  = eventData->values[4];
96
97         _D("Baseline: %u, %u, %.3f, %.3f",
98                         __baseline.walkSteps, __baseline.runSteps, __baseline.distance, __baseline.calories);
99
100         removeExpired(SUBJ_SENSOR_PEDOMETER, PEDOMETER_RECORD, KEY_END_TIME);
101 }
102
103 void PedometerLogger::__recordSingle(sensor_pedometer_data_t *eventData, uint64_t timestamp)
104 {
105         DataRecord record;
106         record.walkSteps = static_cast<unsigned int>(eventData->values[1]) - __baseline.walkSteps;
107         record.runSteps  = static_cast<unsigned int>(eventData->values[2]) - __baseline.runSteps;
108         record.distance  = eventData->values[3] - __baseline.distance;
109         record.calories  = eventData->values[4] - __baseline.calories;
110
111         IF_FAIL_VOID_TAG(record.walkSteps + record.runSteps > 0, _D, "Skipping zero-count event");
112
113         char *query = sqlite3_mprintf(
114                         "INSERT INTO " PEDOMETER_RECORD "(" \
115                                 KEY_START_TIME ", " \
116                                 KEY_END_TIME ", " \
117                                 KEY_WALK_STEPS ", " \
118                                 KEY_RUN_STEPS ", " \
119                                 KEY_DISTANCE ", " \
120                                 KEY_CALORIES ") " \
121                                 "VALUES (%llu, %llu, %u, %u, %.3f, %.3f)",
122                         __baseline.timestamp, timestamp, record.walkSteps, record.runSteps, record.distance, record.calories);
123         executeQuery(query);
124         sqlite3_free(query);
125 }
126
127 void PedometerLogger::__recordBatch(sensor_pedometer_data_t *eventData, uint64_t timestamp)
128 {
129         std::string query("INSERT INTO " PEDOMETER_RECORD "(" \
130                                 KEY_START_TIME ", " \
131                                 KEY_END_TIME ", " \
132                                 KEY_WALK_STEPS ", " \
133                                 KEY_RUN_STEPS ", " \
134                                 KEY_DISTANCE ", " \
135                                 KEY_CALORIES ") VALUES ");
136         char buffer[256];
137
138         for (int i = 0; i < eventData->diffs_count; ++i) {
139                 if (eventData->diffs[i].walk_steps + eventData->diffs[i].run_steps == 0) {
140                         _D("Skipping zero-count event");
141                         continue;
142                 }
143
144                 /* TODO: check the timestamps.. they look strange.. */
145                 g_snprintf(buffer, sizeof(buffer), "(%llu, %llu, %d, %d, %.3f, %.3f),",
146                                 i == 0 ? __baseline.timestamp : SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i-1].timestamp)),
147                                 SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i].timestamp)),
148                                 eventData->diffs[i].walk_steps,
149                                 eventData->diffs[i].run_steps,
150                                 eventData->diffs[i].distance,
151                                 eventData->diffs[i].calories);
152                 query += buffer;
153         }
154
155         query.resize(query.size() - 1);
156         IF_FAIL_VOID_TAG(query.at(query.size() - 1) == ')', _D, "No records");
157
158         executeQuery(query.c_str());
159 }