Rename the class Json to avoid symbol conflicts with Jsoncpp
[platform/core/context/context-provider.git] / src / sensor / SensorProvider.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 <ctime>
18 #include <cmath>
19 #include <SensorRecorderTypes.h>
20 #include "TypesInternal.h"
21 #include "SensorProvider.h"
22
23 using namespace ctx;
24
25 std::map<std::string, SensorProvider*> SensorProvider::__providerMap;
26
27 SensorProvider::SensorProvider(const char *subject) :
28         ContextProvider(subject),
29         sensorLogger(NULL)
30 {
31         __providerMap[subject] = this;
32 }
33
34 SensorProvider::~SensorProvider()
35 {
36         __providerMap.erase(getSubject());
37         delete sensorLogger;
38 }
39
40 int SensorProvider::subscribe(CtxJson1 option, CtxJson1 *requestResult)
41 {
42         return ERR_NONE;
43 }
44
45 int SensorProvider::unsubscribe(CtxJson1 option)
46 {
47         return ERR_NONE;
48 }
49
50 int SensorProvider::read(CtxJson1 option, CtxJson1 *requestResult)
51 {
52         int endTime = static_cast<int>(time(NULL)) + 1;
53         int startTime = endTime - DEFAULT_QUERY_PERIOD - 1;
54         int anchor = -1;
55         int interval = -1;
56
57         if (option.get(NULL, KEY_START_TIME, &startTime))
58                 IF_FAIL_RETURN(startTime >= 0, ERR_INVALID_PARAMETER);
59
60         if (option.get(NULL, KEY_END_TIME, &endTime))
61                 IF_FAIL_RETURN(endTime >= 0, ERR_INVALID_PARAMETER);
62
63         if (option.get(NULL, KEY_ANCHOR, &anchor))
64                 IF_FAIL_RETURN(anchor >= 0, ERR_INVALID_PARAMETER);
65
66         if (option.get(NULL, KEY_INTERVAL, &interval))
67                 IF_FAIL_RETURN(interval >= 0, ERR_INVALID_PARAMETER);
68
69         if (endTime >= 0 && startTime >= endTime)
70                 return ERR_INVALID_PARAMETER;
71
72         if (interval > 0 && anchor < 0)
73                 anchor = endTime;
74
75         if (anchor >= 0 && interval < 0)
76                 interval = static_cast<int>(ceil(static_cast<double>(endTime - startTime) / SECONDS_PER_MINUTE));
77
78         int ret;
79         Querier *querier = getQuerier(option);
80         IF_FAIL_RETURN(querier, ERR_OPERATION_FAILED);
81
82         sensorLogger->flushCache(true);
83
84         if (interval == 0)
85                 ret = querier->queryRaw(startTime, endTime);
86         else if (interval > 0)
87                 ret = querier->query(startTime, endTime, anchor, interval * SECONDS_PER_MINUTE);
88         else
89                 ret = querier->query(startTime, endTime);
90
91         if (ret != ERR_NONE)
92                 delete querier;
93
94         return ret;
95 }
96
97 int SensorProvider::write(CtxJson1 data, CtxJson1 *requestResult)
98 {
99         IF_FAIL_RETURN(sensorLogger, ERR_OPERATION_FAILED);
100
101         std::string operation;
102         std::string pkgId;
103         CtxJson1 option;
104         int retentionPeriod = DEFAULT_RETENTION;
105
106         _J("Data", data);
107
108         IF_FAIL_RETURN(data.get(NULL, KEY_OPERATION, &operation), ERR_INVALID_PARAMETER);
109         IF_FAIL_RETURN(data.get(NULL, KEY_CLIENT_PKG_ID, &pkgId), ERR_INVALID_PARAMETER);
110
111         data.get(NULL, KEY_OPTION, &option);
112
113         if (option.get(NULL, KEY_RETENTION, &retentionPeriod)) {
114                 retentionPeriod *= SECONDS_PER_HOUR;
115                 option.remove(NULL, KEY_RETENTION);
116         }
117
118         IF_FAIL_RETURN(verifyOption(option), ERR_INVALID_PARAMETER);
119
120         if (operation == VAL_START)
121                 return __addClient(pkgId, retentionPeriod, option);
122         else if (operation == VAL_STOP)
123                 return __removeClient(pkgId);
124
125         return ERR_NOT_SUPPORTED;
126 }
127
128 bool SensorProvider::verifyOption(CtxJson1 option)
129 {
130         std::list<std::string> keys;
131         option.getKeys(&keys);
132         return keys.size() == 0;
133 }
134
135 int SensorProvider::__addClient(std::string pkgId, int retentionPeriod, CtxJson1 option)
136 {
137         CtxJson1 tmp;
138         int ret;
139
140         /* Validate the retention period */
141         IF_FAIL_RETURN(retentionPeriod > 0 && retentionPeriod <= MAX_RETENTION_PERIOD, ERR_INVALID_PARAMETER);
142
143         /* Check if the app already started Sensor recording */
144         ret = __clientInfo.get(getSubject(), pkgId, tmp);
145         IF_FAIL_RETURN(ret != ERR_NONE, ERR_ALREADY_STARTED);
146         IF_FAIL_RETURN(ret == ERR_NO_DATA, ERR_OPERATION_FAILED);
147
148         /* Store the app's request */
149         if (!__clientInfo.set(getSubject(), pkgId, option, retentionPeriod))
150                 return ERR_OPERATION_FAILED;
151
152         /* If not listening the sensor yet, start */
153         sensorLogger->start();
154
155         return ERR_NONE;
156 }
157
158 int SensorProvider::__removeClient(std::string pkgId)
159 {
160         std::vector<CtxJson1> options;
161         int ret;
162
163         /* Remove the app's request first */
164         IF_FAIL_RETURN(__clientInfo.remove(getSubject(), pkgId), ERR_OPERATION_FAILED);
165
166         /* Check if there is no client anymore */
167         ret = __clientInfo.get(getSubject(), options);
168
169         if (ret == ERR_NONE) {
170                 /* Still, one or more clients exist */
171                 /* If necessary, the logger restarts its logging logic with updated parameters */
172                 sensorLogger->start();
173                 return ERR_NONE;
174
175         } else if (ret == ERR_NO_DATA) {
176                 /* No client */
177                 sensorLogger->stop();
178                 return ERR_NONE;
179         }
180
181         return ERR_OPERATION_FAILED;
182 }
183
184 void SensorProvider::removeClient(std::string subject, std::string pkgId)
185 {
186         __providerMap[subject]->__removeClient(pkgId);
187 }