sensor: remove unnecessary logs in the dummy
[platform/core/api/sensor.git] / src / sensor_recorder.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 <stdlib.h>
18 #include <sensor.h>
19
20 #include <Json.h>
21 #include <ErrorTypes.h>
22 #include <DBusClient.h>
23 #include <ProviderTypes.h>
24 #include <SensorRecorderTypes.h>
25 #include <ScopeMutex.h>
26 #include <map>
27 #include <string>
28 #include <memory>
29
30 #include "include/sensor_log.h"
31
32 static ctx::DBusClient dbusClient;
33 static GMutex info_mutex;
34
35 static std::map<sensor_type_e, std::string> sensor_keys = {
36         {SENSOR_HRM,                              SUBJ_SENSOR_HEART_RATE},
37         {SENSOR_HUMAN_PEDOMETER,                  SUBJ_SENSOR_PEDOMETER},
38         {SENSOR_HUMAN_SLEEP_MONITOR,              SUBJ_SENSOR_SLEEP_MONITOR},
39         {SENSOR_PRESSURE,                         SUBJ_SENSOR_PRESSURE},
40 };
41
42 static std::map<sensor_recorder_option_e, std::string> option_keys = {
43         {SENSOR_RECORDER_OPTION_RETENTION_PERIOD, KEY_RETENTION},
44         {SENSOR_RECORDER_OPTION_INTERVAL,         KEY_INTERVAL}
45 };
46
47 static std::map<sensor_recorder_query_e, std::string> query_keys = {
48         {SENSOR_RECORDER_QUERY_START_TIME,        KEY_START_TIME},
49         {SENSOR_RECORDER_QUERY_END_TIME,          KEY_END_TIME},
50         {SENSOR_RECORDER_QUERY_ANCHOR_TIME,       KEY_ANCHOR},
51         {SENSOR_RECORDER_QUERY_TIME_INTERVAL,     KEY_INTERVAL},
52 };
53
54 static std::map<sensor_recorder_data_e, std::string> data_keys = {
55         {SENSOR_RECORDER_DATA_STEPS,              KEY_STEPS},
56         {SENSOR_RECORDER_DATA_WALK_STEPS,         KEY_WALK_STEPS},
57         {SENSOR_RECORDER_DATA_RUN_STEPS,          KEY_RUN_STEPS},
58         {SENSOR_RECORDER_DATA_DISTANCE,           KEY_DISTANCE},
59         {SENSOR_RECORDER_DATA_CALORIE,            KEY_CALORIES},
60         {SENSOR_RECORDER_DATA_HEART_RATE,         KEY_HEART_RATE},
61         {SENSOR_RECORDER_DATA_SLEEP_STATE,        KEY_SLEEP_STATE},
62         {SENSOR_RECORDER_DATA_PRESSURE,           KEY_PRESSURE},
63         {SENSOR_RECORDER_DATA_MAX_PRESSURE,       KEY_MAX_PRESSURE},
64         {SENSOR_RECORDER_DATA_MIN_PRESSURE,       KEY_MIN_PRESSURE},
65         {SENSOR_RECORDER_DATA_AVERAGE_PRESSURE,   KEY_AVG_PRESSURE}
66 };
67
68 static sensor_error_e convert_error(int error)
69 {
70         switch (error) {
71         case ERR_NONE:
72         case ERR_INVALID_PARAMETER:
73         case ERR_OUT_OF_MEMORY:
74         case ERR_PERMISSION_DENIED:
75         case ERR_NOT_SUPPORTED:
76         case ERR_NO_DATA:
77                 return (sensor_error_e)error;
78         case ERR_ALREADY_STARTED:
79                 return SENSOR_ERROR_NOT_AVAILABLE;
80         default:
81                 break;
82         }
83         return SENSOR_ERROR_OPERATION_FAILED;
84 }
85
86 typedef struct {
87         ctx::Json *json;
88         int index;
89 } tuple_info;
90
91 typedef struct {
92         sensor_type_e type;
93         sensor_recorder_data_cb cb;
94         void *user_data;
95 } callback_info;
96
97 class DBusListener : public ctx::IDBusClientListener {
98 public:
99         void onPublish(std::string subject, int reqId, int error, ctx::Json event);
100         void setCallbackInfo(int reqid, callback_info *info);
101
102 private:
103         std::map<int, std::shared_ptr<callback_info>> infos;
104 };
105
106 void DBusListener::onPublish(std::string subject, int reqId, int error, ctx::Json event)
107 {
108         bool ret = false;
109         int size = 0;
110         tuple_info data;
111
112         {
113                 ctx::ScopeMutex sm(&info_mutex);
114                 if (infos.find(reqId) == infos.end())
115                         return;
116         }
117
118         ret = event.get(NULL, KEY_RESULT_SIZE, &size);
119
120         if (!ret)
121                 return;
122
123         if (size == 0) {
124                 infos[reqId]->cb(infos[reqId]->type, (sensor_recorder_data_h)&data, 0, SENSOR_ERROR_NO_DATA, infos[reqId]->user_data);
125                 goto CLEAN;
126         }
127
128         data.json = &event;
129
130         for (int i = 0; i < size; ++i) {
131                 data.index = i;
132                 ret = infos[reqId]->cb(infos[reqId]->type, (sensor_recorder_data_h)&data, (size - (i + 1)), convert_error(error), infos[reqId]->user_data);
133
134                 if (!ret)
135                         break;
136         }
137
138 CLEAN:
139         _D("Succeeded to call DBusListener::onPublish() with reqId[%d]", reqId);
140
141         infos.erase(reqId);
142 }
143
144 void DBusListener::setCallbackInfo(int reqId, callback_info *info)
145 {
146         infos[reqId] = std::shared_ptr<callback_info>(info);
147 }
148
149 int sensor_recorder_is_supported(sensor_type_e type, bool *supported)
150 {
151         int ret = SENSOR_ERROR_NONE;
152
153         if (type <= SENSOR_ALL)
154                 return SENSOR_ERROR_INVALID_PARAMETER;
155         if (!supported)
156                 return SENSOR_ERROR_INVALID_PARAMETER;
157
158         ret = dbusClient.isSupported(sensor_keys[type]);
159
160         if (ret == ERR_NONE)
161                 *supported = true;
162         else if (ret == ERR_NOT_SUPPORTED)
163                 *supported = false;
164         else
165                 return convert_error(ret);
166
167         _D("sensor[%#x] is %s", type, (*supported ? "supported" : "not supported"));
168
169         return SENSOR_ERROR_NONE;
170 }
171
172 int sensor_recorder_start(sensor_type_e type, sensor_recorder_option_h option)
173 {
174         int ret = SENSOR_ERROR_NONE;
175         ctx::Json operation;
176
177         if (type <= SENSOR_ALL)
178                 return SENSOR_ERROR_INVALID_PARAMETER;
179
180         operation.set(NULL, KEY_OPERATION, VAL_START);
181
182         if (option)
183                 operation.set(NULL, KEY_OPTION, *static_cast<ctx::Json *>(option));
184
185         ret = dbusClient.write(sensor_keys[type], operation.str(), NULL);
186
187         _D("Started to record sensor[%#x] data with operation : %s", type, operation.str().c_str());
188
189         return convert_error(ret);
190 }
191
192 int sensor_recorder_stop(sensor_type_e type)
193 {
194         int ret = SENSOR_ERROR_NONE;
195         ctx::Json operation;
196
197         if (type <= SENSOR_ALL)
198                 return SENSOR_ERROR_INVALID_PARAMETER;
199
200         operation.set(NULL, KEY_OPERATION, VAL_STOP);
201
202         ret = dbusClient.write(sensor_keys[type], operation.str(), NULL);
203
204         _D("Stopped to record sensor[%#x] data with operation : %s", type, operation.str().c_str());
205
206         return convert_error(ret);
207 }
208
209 int sensor_recorder_create_option(sensor_recorder_option_h *option)
210 {
211         if (!option)
212                 return SENSOR_ERROR_INVALID_PARAMETER;
213
214         *option = static_cast<sensor_recorder_option_h>(new(std::nothrow) ctx::Json());
215
216         if (!*option) {
217                 _D("Failed to create option handle");
218                 return SENSOR_ERROR_OUT_OF_MEMORY;
219         }
220
221         _D("Created option handle[%p]", *option);
222
223         return SENSOR_ERROR_NONE;
224 }
225
226 int sensor_recorder_destroy_option(sensor_recorder_option_h option)
227 {
228         if (!option)
229                 return SENSOR_ERROR_INVALID_PARAMETER;
230
231         delete static_cast<ctx::Json *>(option);
232         option = NULL;
233
234         _D("Destroyed option handle");
235
236         return SENSOR_ERROR_NONE;
237 }
238
239 int sensor_recorder_option_set_int(sensor_recorder_option_h option, sensor_recorder_option_e attribute, int value)
240 {
241         if (!option)
242                 return SENSOR_ERROR_INVALID_PARAMETER;
243         if (attribute < 0)
244                 return SENSOR_ERROR_INVALID_PARAMETER;
245         if (option_keys.find(attribute) == option_keys.end())
246                 return SENSOR_ERROR_INVALID_PARAMETER;
247
248         static_cast<ctx::Json *>(option)->set(NULL, option_keys[attribute].c_str(), value);
249
250         _D("Set attribute[%d] with value[%d] to option[%p]", attribute, value, option);
251
252         return SENSOR_ERROR_NONE;
253 }
254
255 int sensor_recorder_create_query(sensor_recorder_query_h *query)
256 {
257         if (!query)
258                 return SENSOR_ERROR_INVALID_PARAMETER;
259
260         *query = static_cast<sensor_recorder_query_h>(new(std::nothrow) ctx::Json());
261
262         if (!*query) {
263                 _D("Failed to create query handle");
264                 return SENSOR_ERROR_OUT_OF_MEMORY;
265         }
266
267         _D("Created query handle[%p]", *query);
268
269         return SENSOR_ERROR_NONE;
270 }
271
272 int sensor_recorder_destroy_query(sensor_recorder_query_h query)
273 {
274         if (!query)
275                 return SENSOR_ERROR_INVALID_PARAMETER;
276
277         delete static_cast<ctx::Json *>(query);
278         query = NULL;
279
280         _D("Destroyed query handle");
281
282         return SENSOR_ERROR_NONE;
283 }
284
285 int sensor_recorder_query_set_int(sensor_recorder_query_h query, sensor_recorder_query_e attribute, int value)
286 {
287         if (!query)
288                 return SENSOR_ERROR_INVALID_PARAMETER;
289         if (attribute < 0)
290                 return SENSOR_ERROR_INVALID_PARAMETER;
291         if (query_keys.find(attribute) == query_keys.end())
292                 return SENSOR_ERROR_INVALID_PARAMETER;
293         if (attribute == SENSOR_RECORDER_QUERY_TIME_INTERVAL && value < 0)
294                 return SENSOR_ERROR_INVALID_PARAMETER;
295
296         static_cast<ctx::Json *>(query)->set(NULL, query_keys[attribute].c_str(), (int)value);
297
298         _D("Set attribute[%d] with value[%d] to query[%p]", attribute, value, query);
299
300         return SENSOR_ERROR_NONE;
301 }
302
303 int sensor_recorder_query_set_time(sensor_recorder_query_h query, sensor_recorder_query_e attribute, time_t t)
304 {
305         ctx::Json *time_query = static_cast<ctx::Json *>(query);
306         int64_t endTime;
307         int64_t startTime;
308
309         if (!query)
310                 return SENSOR_ERROR_INVALID_PARAMETER;
311         if (attribute < 0)
312                 return SENSOR_ERROR_INVALID_PARAMETER;
313         if (query_keys.find(attribute) == query_keys.end())
314                 return SENSOR_ERROR_INVALID_PARAMETER;
315         if (t < 0)
316                 return SENSOR_ERROR_INVALID_PARAMETER;
317         if (time_query->get(NULL, KEY_END_TIME, &endTime))
318                 if (attribute == SENSOR_RECORDER_QUERY_START_TIME && t >= endTime)
319                         return SENSOR_ERROR_INVALID_PARAMETER;
320         if (time_query->get(NULL, KEY_START_TIME, &startTime))
321                 if (attribute == SENSOR_RECORDER_QUERY_END_TIME && t <= startTime)
322                         return SENSOR_ERROR_INVALID_PARAMETER;
323
324         time_query->set(NULL, query_keys[attribute].c_str(), (int64_t)t);
325
326         _D("Set attribute[%d] with value[%ld] to query[%p]", attribute, t, query);
327
328         return SENSOR_ERROR_NONE;
329 }
330
331 int sensor_recorder_read(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
332 {
333         int ret = SENSOR_ERROR_NONE;
334         int reqId = 0;
335         callback_info *info = NULL;
336
337         if (type <= SENSOR_ALL)
338                 return SENSOR_ERROR_INVALID_PARAMETER;
339         if (!query || !cb)
340                 return SENSOR_ERROR_INVALID_PARAMETER;
341
342         /* Lazy creating listener */
343         static DBusListener listener;
344
345         dbusClient.addListener(sensor_keys[type], &listener);
346
347         {
348                 ctx::ScopeMutex sm(&info_mutex);
349
350                 ret = dbusClient.read(sensor_keys[type], *static_cast<ctx::Json *>(query), &reqId, NULL);
351
352                 if (ret != SENSOR_ERROR_NONE)
353                         return convert_error(ret);
354
355                 info = new(std::nothrow) callback_info();
356                 if (!info) {
357                         _D("Failed to create callback info");
358                         return SENSOR_ERROR_OUT_OF_MEMORY;
359                 }
360
361                 info->type = type;
362                 info->cb = cb;
363                 info->user_data = user_data;
364
365                 listener.setCallbackInfo(reqId, info);
366         }
367
368         _D("succeeded to read sensor[%#x] data with query : %s", type, static_cast<ctx::Json *>(query)->str().c_str());
369
370         return SENSOR_ERROR_NONE;
371 }
372
373 int sensor_recorder_read_sync(sensor_type_e type, sensor_recorder_query_h query, sensor_recorder_data_cb cb, void *user_data)
374 {
375         int ret = SENSOR_ERROR_NONE;
376         int reqId = 0;
377         int size = 0;
378         ctx::Json output;
379         tuple_info data;
380
381         if (type <= SENSOR_ALL)
382                 return SENSOR_ERROR_INVALID_PARAMETER;
383         if (!query || !cb)
384                 return SENSOR_ERROR_INVALID_PARAMETER;
385
386         ret = dbusClient.readSync(sensor_keys[type], *static_cast<ctx::Json *>(query), &reqId, &output);
387
388         if (ret != ERR_NONE)
389                 return convert_error(ret);
390
391         ret = output.get(NULL, KEY_RESULT_SIZE, &size);
392
393         if (!ret)
394                 return SENSOR_ERROR_INVALID_PARAMETER;
395         if (size == 0)
396                 return SENSOR_ERROR_NO_DATA;
397
398         data.json = &output;
399
400         for (int i = 0; i < size; ++i) {
401                 data.index = i;
402                 ret = cb(type, (sensor_recorder_data_h)&data, (size - (i + 1)), SENSOR_ERROR_NONE, user_data);
403
404                 if (!ret)
405                         break;
406         }
407
408         _D("succeeded to read sensor[%#x] data with query : %s", type, static_cast<ctx::Json *>(query)->str().c_str());
409
410         return SENSOR_ERROR_NONE;
411 }
412
413 int sensor_recorder_data_get_time(sensor_recorder_data_h data, time_t *start_time, time_t *end_time)
414 {
415         int64_t start = 0, end = 0;
416         tuple_info *tuple = NULL;
417         ctx::Json *json = NULL;
418
419         if (!data || !start_time || !end_time)
420                 return SENSOR_ERROR_INVALID_PARAMETER;
421
422         tuple = static_cast<tuple_info *>(data);
423         json = tuple->json;
424
425         if (!json)
426                 return SENSOR_ERROR_INVALID_PARAMETER;
427
428         if (!json->getAt(NULL, KEY_START_TIME, tuple->index, &start))
429                 return SENSOR_ERROR_INVALID_PARAMETER;
430
431         if (!json->getAt(NULL, KEY_END_TIME, tuple->index, &end))
432                 return SENSOR_ERROR_INVALID_PARAMETER;
433
434         *start_time = static_cast<time_t>(start / 1000);
435         *end_time = static_cast<time_t>(end / 1000);
436
437         _D("Get start_time[%ld] and end_time[%ld] from data[%p]", *start_time, *end_time, data);
438
439         return SENSOR_ERROR_NONE;
440 }
441
442 int sensor_recorder_data_get_int(sensor_recorder_data_h data, sensor_recorder_data_e key, int *value)
443 {
444         tuple_info *tuple = NULL;
445         ctx::Json *json = NULL;
446
447         if (!data || !value)
448                 return SENSOR_ERROR_INVALID_PARAMETER;
449         if (key < 0)
450                 return SENSOR_ERROR_INVALID_PARAMETER;
451         if (data_keys.find(key) == data_keys.end())
452                 return SENSOR_ERROR_INVALID_PARAMETER;
453
454         tuple = static_cast<tuple_info *>(data);
455         json = tuple->json;
456
457         if (!json)
458                 return SENSOR_ERROR_INVALID_PARAMETER;
459
460         if (!json->getAt(NULL, data_keys[key].c_str(), tuple->index, value))
461                 return SENSOR_ERROR_INVALID_PARAMETER;
462
463         _D("Get value[%d] from data[%p]", *value, data);
464
465         return SENSOR_ERROR_NONE;
466 }
467
468 int sensor_recorder_data_get_double(sensor_recorder_data_h data, sensor_recorder_data_e key, double *value)
469 {
470         tuple_info *tuple = NULL;
471         ctx::Json *json = NULL;
472
473         if (!data || !value)
474                 return SENSOR_ERROR_INVALID_PARAMETER;
475         if (key < 0)
476                 return SENSOR_ERROR_INVALID_PARAMETER;
477         if (data_keys.find(key) == data_keys.end())
478                 return SENSOR_ERROR_INVALID_PARAMETER;
479
480         tuple = static_cast<tuple_info *>(data);
481         json = tuple->json;
482
483         if (!json)
484                 return SENSOR_ERROR_INVALID_PARAMETER;
485
486         if (!json->getAt(NULL, data_keys[key].c_str(), tuple->index, value))
487                 return SENSOR_ERROR_INVALID_PARAMETER;
488
489         _D("Get value[%f] from data[%p]", *value, data);
490
491         return SENSOR_ERROR_NONE;
492 }