f3e14706a2664572e47b2dd4f1fcf8c5596da392
[platform/core/context/context-provider.git] / src / sensor / sleep / SleepLogger.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 "SleepDetector.h"
23 #include "SleepMonitor.h"
24 #include "SleepLogger.h"
25
26 #define TIME_GAP 5000
27
28 using namespace ctx;
29
30 static SleepDetector *__sleepDetector = NULL;
31 static SleepMonitor  *__sleepMonitor  = NULL;
32
33 SleepLogger::SleepLogger() :
34         __startTime(0),
35         __endTime(0)
36 {
37         __sleepDetector = NULL;
38         __sleepMonitor = NULL;
39
40         /* Create the log table */
41         executeQuery(
42                         "CREATE TABLE IF NOT EXISTS " SLEEP_MONITOR_RECORD " (" \
43                                 KEY_START_TIME " INTEGER NOT NULL, " \
44                                 KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \
45                                 KEY_STATE " INTEGER NOT NULL DEFAULT 1" \
46                         ")");
47
48         ClientInfo clientInfo;
49         if (clientInfo.exist(SUBJ_SENSOR_SLEEP_MONITOR))
50                 start();
51 }
52
53 SleepLogger::~SleepLogger()
54 {
55         stop();
56 }
57
58 bool SleepLogger::start()
59 {
60         if (!__sleepDetector) {
61                 __sleepDetector = new(std::nothrow) SleepDetector(this);
62                 __sleepMonitor = new(std::nothrow) SleepMonitor(this);
63
64                 if (!__sleepDetector || !__sleepMonitor) {
65                         _E("Memory allocation failed");
66
67                         delete __sleepDetector;
68                         __sleepDetector = NULL;
69
70                         delete __sleepMonitor;
71                         __sleepMonitor = NULL;
72
73                         return false;
74                 }
75         }
76
77         if (__sleepDetector->isRunning()) {
78                 _D("Started already");
79                 return true;
80         }
81
82         _I(GREEN("Start to record"));
83
84         __startTime = 0;
85         __endTime = 0;
86         __resetInsertionQuery();
87
88         return __sleepDetector->start();
89 }
90
91 void SleepLogger::stop()
92 {
93         IF_FAIL_VOID_TAG(__sleepDetector, _D, "Stopped already");
94         _I(GREEN("Stop recording"));
95
96         __sleepDetector->stop();
97         __sleepMonitor->stop();
98
99         __appendQuery(__startTime, __endTime);
100         flush();
101
102         delete __sleepDetector;
103         __sleepDetector = NULL;
104
105         delete __sleepMonitor;
106         __sleepMonitor = NULL;
107 }
108
109 void SleepLogger::fallAsleep(uint64_t timestamp)
110 {
111         _D("Fall asleep");
112         record(timestamp, TimeUtil::getTime(), STATE_SLEEP);
113         __sleepMonitor->start();
114 }
115
116 void SleepLogger::wakeUp(uint64_t timestamp)
117 {
118         _D("Wake up");
119         __sleepMonitor->lazyStop();
120 }
121
122 void SleepLogger::record(uint64_t startTime, uint64_t endTime, int state)
123 {
124         IF_FAIL_VOID(state == STATE_SLEEP);     /* For now, we don't need to record the awaken state */
125         IF_FAIL_VOID_TAG(startTime < endTime, _W, "Invalid parameter");
126
127         if (__startTime == 0) {
128                 __startTime = startTime;
129                 __endTime = endTime;
130                 _D("Initial event: %llu ~ %llu", __startTime, __endTime);
131                 return;
132         }
133
134         if (startTime < __endTime + TIME_GAP) {
135                 __endTime = MAX(endTime, __endTime);
136                 _D("Merged event: %llu ~ %llu", __startTime, __endTime);
137                 return;
138         }
139
140         __appendQuery(__startTime, __endTime);
141         __startTime = startTime;
142         __endTime = endTime;
143         _D("Reset event: %llu ~ %llu", __startTime, __endTime);
144 }
145
146 void SleepLogger::flush()
147 {
148         __insertionQuery.resize(__insertionQuery.size() - 1);
149         if (__insertionQuery.at(__insertionQuery.size() - 1) == ')')
150                 executeQuery(__insertionQuery.c_str());
151
152         __resetInsertionQuery();
153 }
154
155 void SleepLogger::__resetInsertionQuery()
156 {
157         __insertionQuery =
158                 "INSERT INTO " SLEEP_MONITOR_RECORD \
159                         " (" KEY_START_TIME ", " KEY_END_TIME ") VALUES ";
160 }
161
162 void SleepLogger::__appendQuery(uint64_t startTime, uint64_t endTime)
163 {
164         IF_FAIL_VOID(startTime > 0 && endTime > startTime);
165
166         char buffer[64];
167         g_snprintf(buffer, sizeof(buffer), "(%llu, %llu),", startTime, endTime);
168         __insertionQuery += buffer;
169 }