Merge branch 'tizen_3.0' into devel/tizen
[platform/core/system/sensord.git] / src / client / sensor_event_listener.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <sensor_event_listener.h>
21 #include <client_common.h>
22 #include <sensor_info_manager.h>
23
24 #include <thread>
25 #include <chrono>
26 #include <vector>
27
28 #include <sensor_types.h>
29
30 /* TODO: this macro should be adjusted(4224 = 4096(data) + 128(header)) */
31 #define EVENT_BUFFER_SIZE sizeof(sensor_event_t)
32
33 using std::thread;
34 using std::pair;
35 using std::vector;
36
37 struct free_data {
38         void operator()(void *data) {
39                 free(data);
40         }
41 };
42
43 sensor_event_listener::sensor_event_listener()
44 : m_poller(NULL)
45 , m_thread_state(THREAD_STATE_TERMINATE)
46 , m_hup_observer(NULL)
47 , m_client_info(sensor_client_info::get_instance())
48 , m_axis(SENSORD_AXIS_DISPLAY_ORIENTED)
49 , m_display_rotation(AUTO_ROTATION_DEGREE_UNKNOWN)
50 {
51 }
52
53 sensor_event_listener::~sensor_event_listener()
54 {
55         stop_event_listener();
56 }
57
58 sensor_event_listener& sensor_event_listener::get_instance(void)
59 {
60         static sensor_event_listener inst;
61         return inst;
62 }
63
64 client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
65 {
66         unsigned int cal_event_type = get_calibration_event_type(event_type);
67         reg_event_info *event_info = NULL;
68         reg_event_info *cal_event_info = NULL;
69         client_callback_info* cal_callback_info = NULL;
70
71         if (!cal_event_type)
72                 return NULL;
73
74         cal_event_info = handle_info.get_reg_event_info(cal_event_type);
75         if ((accuracy == SENSOR_ACCURACY_BAD) && !handle_info.m_bad_accuracy && cal_event_info) {
76                 cal_event_info->m_previous_event_time = time;
77
78                 event_info = handle_info.get_reg_event_info(event_type);
79                 if (!event_info)
80                         return NULL;
81
82                 sensor_data_t *cal_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
83                 retvm_if(!cal_data, NULL, "Failed to allocate memory");
84
85                 cal_data->accuracy = accuracy;
86                 cal_data->timestamp = time;
87                 cal_data->values[0] = accuracy;
88                 cal_data->value_count = 1;
89                 std::shared_ptr<void> cal_sensor_data(cal_data, free_data());
90
91                 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data);
92
93                 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
94
95                 print_event_occurrence_log(handle_info);
96         }
97
98         if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
99                 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
100
101         return cal_callback_info;
102 }
103
104 void sensor_event_listener::handle_events(void* event)
105 {
106         unsigned long long cur_time;
107         reg_event_info *event_info = NULL;
108         sensor_id_t sensor_id;
109         sensor_handle_info_map handles_info;
110
111         int accuracy = SENSOR_ACCURACY_GOOD;
112
113         unsigned int event_type = *((unsigned int *)(event));
114
115         client_callback_info* callback_info = NULL;
116
117         sensor_event_t *sensor_event = (sensor_event_t *)event;
118         sensor_id = sensor_event->sensor_id;
119         cur_time = sensor_event->data->timestamp;
120         accuracy = sensor_event->data->accuracy;
121
122         align_sensor_axis(sensor_id, sensor_event->data);
123
124         std::shared_ptr<void> sensor_data(sensor_event->data, free_data());
125
126         {       /* scope for the lock */
127                 m_client_info.get_all_handle_info(handles_info);
128
129                 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
130                         sensor_handle_info &sensor_handle_info = it_handle->second;
131
132                         event_info = sensor_handle_info.get_reg_event_info(event_type);
133                         if ((sensor_handle_info.m_sensor_id != sensor_id) ||
134                             !sensor_handle_info.is_started() ||
135                             !event_info)
136                                 continue;
137
138                         if (event_info->m_fired)
139                                 continue;
140
141                         event_info->m_previous_event_time = cur_time;
142
143                         client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
144
145                         if (cal_callback_info)
146                                 m_cb_deliverer->push(cal_callback_info);
147
148                         callback_info = get_callback_info(sensor_id, event_info, sensor_data);
149
150                         if (!callback_info) {
151                                 _E("Failed to get callback_info");
152                                 continue;
153                         }
154
155                         if (sensor_handle_info.m_accuracy != accuracy) {
156                                 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
157
158                                 callback_info->accuracy_cb = sensor_handle_info.m_accuracy_cb;
159                                 callback_info->timestamp = cur_time;
160                                 callback_info->accuracy = accuracy;
161                                 callback_info->accuracy_user_data = sensor_handle_info.m_accuracy_user_data;
162                         }
163
164                         m_cb_deliverer->push(callback_info);
165
166                         print_event_occurrence_log(sensor_handle_info);
167                 }
168         }
169 }
170
171 client_callback_info* sensor_event_listener::get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, std::shared_ptr<void> sensor_data)
172 {
173         client_callback_info* callback_info;
174
175         callback_info = new(std::nothrow)client_callback_info;
176         retvm_if(!callback_info, NULL, "Failed to allocate memory");
177
178         callback_info->sensor = sensor_info_to_sensor(sensor_info_manager::get_instance().get_info(sensor_id));
179         callback_info->event_id = event_info->m_id;
180         callback_info->handle = event_info->m_handle;
181         callback_info->cb = (sensor_cb_t)(event_info->m_cb);
182         callback_info->event_type = event_info->type;
183         callback_info->user_data = event_info->m_user_data;
184         callback_info->accuracy_cb = NULL;
185         callback_info->timestamp = 0;
186         callback_info->accuracy = -1;
187         callback_info->accuracy_user_data = NULL;
188         callback_info->sensor_data = sensor_data;
189
190         return callback_info;
191 }
192
193 void sensor_event_listener::set_sensor_axis(int axis)
194 {
195         m_axis = axis;
196 }
197
198 void sensor_event_listener::align_sensor_axis(sensor_id_t sensor, sensor_data_t *data)
199 {
200         sensor_id_t type = CONVERT_ID_TYPE(sensor);
201
202         if (m_axis != SENSORD_AXIS_DISPLAY_ORIENTED)
203                 return;
204
205         if (type != ACCELEROMETER_SENSOR && type != GYROSCOPE_SENSOR && type != GRAVITY_SENSOR && type != LINEAR_ACCEL_SENSOR)
206                 return;
207
208         float x, y;
209
210         switch (m_display_rotation) {
211         case AUTO_ROTATION_DEGREE_90:   /* Landscape Left */
212                 x = -data->values[1];
213                 y = data->values[0];
214                 break;
215         case AUTO_ROTATION_DEGREE_180:  /* Portrait Bottom */
216                 x = -data->values[0];
217                 y = -data->values[1];
218                 break;
219         case AUTO_ROTATION_DEGREE_270:  /* Landscape Right */
220                 x = data->values[1];
221                 y = -data->values[0];
222                 break;
223         default:
224                 return;
225         }
226
227         data->values[0] = x;
228         data->values[1] = y;
229 }
230
231 ssize_t sensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, struct epoll_event &event)
232 {
233         ssize_t len;
234
235         len = m_event_socket.recv(buffer, buffer_len);
236
237         if (!len) {
238                 if (!m_poller->poll(event))
239                         return -1;
240                 len = m_event_socket.recv(buffer, buffer_len);
241
242                 if (!len) {
243                         _E("%s failed to read after poll!", get_client_name());
244                         return -1;
245                 }
246         }
247
248         if (len < 0) {
249                 _E("%s failed to recv event from event socket", get_client_name());
250                 return -1;
251         }
252
253         return len;
254 }
255
256 void sensor_event_listener::listen_events(void)
257 {
258         char buffer[EVENT_BUFFER_SIZE];
259         struct epoll_event event;
260         ssize_t len = -1;
261
262         event.events = EPOLLIN | EPOLLPRI;
263
264         do {
265                 void *buffer_data;
266                 int data_len;
267
268                 lock l(m_thread_mutex);
269                 if (m_thread_state != THREAD_STATE_START)
270                         break;
271
272                 len = sensor_event_poll(buffer, sizeof(sensor_event_t), event);
273                 if (len <= 0) {
274                         _E("Failed to sensor_event_poll()");
275                         break;
276                 }
277
278                 sensor_event_t *sensor_event = reinterpret_cast<sensor_event_t *>(buffer);
279                 data_len = sensor_event->data_length;
280
281                 if (data_len == 0)
282                         continue;
283
284                 buffer_data = malloc(data_len);
285
286                 len = sensor_event_poll(buffer_data, data_len, event);
287                 if (len <= 0) {
288                         _E("Failed to sensor_event_poll() for sensor_data");
289                         free(buffer_data);
290                         break;
291                 }
292
293                 sensor_event->data = reinterpret_cast<sensor_data_t *>(buffer_data);
294
295                 handle_events((void *)buffer);
296         } while (true);
297
298         if (m_poller) {
299                 delete m_poller;
300                 m_poller = NULL;
301         }
302
303         close_event_channel();
304
305         { /* the scope for the lock */
306                 lock l(m_thread_mutex);
307                 m_thread_state = THREAD_STATE_TERMINATE;
308                 m_thread_cond.notify_one();
309         }
310
311         _I("Event listener thread is terminated.");
312
313         if (m_client_info.has_client_id() && (event.events & EPOLLHUP)) {
314                 if (m_hup_observer)
315                         m_hup_observer();
316         }
317 }
318
319 bool sensor_event_listener::create_event_channel(void)
320 {
321         const int client_type = CLIENT_TYPE_SENSOR_CLIENT;
322         int client_id;
323         channel_ready_t event_channel_ready;
324
325         if (!m_event_socket.create(SOCK_SEQPACKET))
326                 return false;
327
328         if (!m_event_socket.connect(EVENT_CHANNEL_PATH)) {
329                 _E("Failed to connect event channel for client %s, event socket fd[%d]", get_client_name(), m_event_socket.get_socket_fd());
330                 return false;
331         }
332
333         if (!m_event_socket.set_connection_mode()) {
334                 _E("Failed to set connection mode for client %s", get_client_name());
335                 return false;
336         }
337
338         if (m_event_socket.send(&client_type, sizeof(client_type)) <= 0) {
339                 _E("Failed to send client type in client %s, event socket fd[%d]", get_client_name(), m_event_socket.get_socket_fd());
340                 return false;
341         }
342
343         client_id = m_client_info.get_client_id();
344
345         if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) {
346                 _E("Failed to send client id for client %s on event socket[%d]", get_client_name(), m_event_socket.get_socket_fd());
347                 return false;
348         }
349
350         if (m_event_socket.recv(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
351                 _E("%s failed to recv event_channel_ready packet on event socket[%d] with client id [%d]",
352                         get_client_name(), m_event_socket.get_socket_fd(), client_id);
353                 return false;
354         }
355
356         if ((event_channel_ready.magic != CHANNEL_MAGIC_NUM) || (event_channel_ready.client_id != client_id)) {
357                 _E("Event_channel_ready packet is wrong, magic = %#x, client id = %d",
358                         event_channel_ready.magic, event_channel_ready.client_id);
359                 return false;
360         }
361
362         _I("Event channel is established for client %s on socket[%d] with client id : %d",
363                 get_client_name(), m_event_socket.get_socket_fd(), client_id);
364
365         return true;
366 }
367
368 void sensor_event_listener::close_event_channel(void)
369 {
370         m_event_socket.close();
371 }
372
373 void sensor_event_listener::set_thread_state(thread_state state)
374 {
375         lock l(m_thread_mutex);
376         m_thread_state = state;
377 }
378
379 void sensor_event_listener::clear(void)
380 {
381         close_event_channel();
382         stop_event_listener();
383         m_client_info.close_command_channel();
384         m_client_info.clear();
385         m_client_info.set_client_id(CLIENT_ID_INVALID);
386 }
387
388 void sensor_event_listener::set_hup_observer(hup_observer_t observer)
389 {
390         m_hup_observer = observer;
391 }
392
393 bool sensor_event_listener::start_event_listener(void)
394 {
395         if (!create_event_channel()) {
396                 _E("Event channel is not established for %s", get_client_name());
397                 return false;
398         }
399
400         if (!start_deliverer())
401                 return false;
402
403         m_event_socket.set_transfer_mode();
404
405         m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
406         retvm_if(!m_poller, false, "Failed to allocate memory");
407
408         set_thread_state(THREAD_STATE_START);
409
410         thread listener(&sensor_event_listener::listen_events, this);
411         listener.detach();
412
413         return true;
414 }
415
416 void sensor_event_listener::stop_event_listener(void)
417 {
418         const int THREAD_TERMINATING_TIMEOUT = 2;
419         std::cv_status status;
420
421         ulock u(m_thread_mutex);
422
423         /* TOBE: it can be changed to join() simply */
424         if (m_thread_state != THREAD_STATE_TERMINATE) {
425                 m_thread_state = THREAD_STATE_STOP;
426
427                 _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
428
429                 status = m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT));
430                 if (status == std::cv_status::timeout)
431                         _E("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT);
432                 else
433                         _D("Listener thread for %s is terminated", get_client_name());
434         }
435
436         if (m_poller) {
437                 delete m_poller;
438                 m_poller = NULL;
439         }
440
441         stop_deliverer();
442         close_event_channel();
443 }
444
445 bool sensor_event_listener::start_deliverer(void)
446 {
447         if (!m_cb_deliverer) {
448                 m_cb_deliverer = new(std::nothrow) sensor_callback_deliverer();
449                 retvm_if(!m_cb_deliverer, false, "Failed to allocated memory");
450         }
451
452         m_cb_deliverer->start();
453         return true;
454 }
455
456 bool sensor_event_listener::stop_deliverer(void)
457 {
458         if (!m_cb_deliverer)
459                 return false;
460
461         if (!m_cb_deliverer->stop())
462                 return false;
463
464         delete m_cb_deliverer;
465         m_cb_deliverer = NULL;
466         return true;
467 }
468
469 void sensor_event_listener::set_display_rotation(int rt)
470 {
471         _D("New display rotation: %d", rt);
472
473         if (rt < AUTO_ROTATION_DEGREE_0 || rt > AUTO_ROTATION_DEGREE_270)
474                 return;
475
476         m_display_rotation = rt;
477 }