4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <sensor_event_listener.h>
21 #include <client_common.h>
22 #include <sensor_info_manager.h>
28 #include <sensor_types.h>
30 /* TODO: this macro should be adjusted(4224 = 4096(data) + 128(header)) */
31 #define EVENT_BUFFER_SIZE sizeof(sensor_event_t)
38 void operator()(void *data) {
43 sensor_event_listener::sensor_event_listener()
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)
53 sensor_event_listener::~sensor_event_listener()
55 stop_event_listener();
58 sensor_event_listener& sensor_event_listener::get_instance(void)
60 static sensor_event_listener inst;
64 client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
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;
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;
78 event_info = handle_info.get_reg_event_info(event_type);
82 sensor_data_t *cal_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
83 retvm_if(!cal_data, NULL, "Failed to allocate memory");
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());
91 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data);
93 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
95 print_event_occurrence_log(handle_info);
98 if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
99 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
101 return cal_callback_info;
104 void sensor_event_listener::handle_events(void* event)
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;
111 int accuracy = SENSOR_ACCURACY_GOOD;
113 unsigned int event_type = *((unsigned int *)(event));
115 client_callback_info* callback_info = NULL;
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;
122 align_sensor_axis(sensor_id, sensor_event->data);
124 std::shared_ptr<void> sensor_data(sensor_event->data, free_data());
126 { /* scope for the lock */
127 m_client_info.get_all_handle_info(handles_info);
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;
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() ||
138 if (event_info->m_fired)
141 event_info->m_previous_event_time = cur_time;
143 client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
145 if (cal_callback_info)
146 m_cb_deliverer->push(cal_callback_info);
148 callback_info = get_callback_info(sensor_id, event_info, sensor_data);
150 if (!callback_info) {
151 _E("Failed to get callback_info");
155 if (sensor_handle_info.m_accuracy != accuracy) {
156 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
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;
164 m_cb_deliverer->push(callback_info);
166 print_event_occurrence_log(sensor_handle_info);
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)
173 client_callback_info* callback_info;
175 callback_info = new(std::nothrow)client_callback_info;
176 retvm_if(!callback_info, NULL, "Failed to allocate memory");
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;
190 return callback_info;
193 void sensor_event_listener::set_sensor_axis(int axis)
198 void sensor_event_listener::align_sensor_axis(sensor_id_t sensor, sensor_data_t *data)
200 sensor_id_t type = CONVERT_ID_TYPE(sensor);
202 if (m_axis != SENSORD_AXIS_DISPLAY_ORIENTED)
205 if (type != ACCELEROMETER_SENSOR && type != GYROSCOPE_SENSOR && type != GRAVITY_SENSOR && type != LINEAR_ACCEL_SENSOR)
210 switch (m_display_rotation) {
211 case AUTO_ROTATION_DEGREE_90: /* Landscape Left */
212 x = -data->values[1];
215 case AUTO_ROTATION_DEGREE_180: /* Portrait Bottom */
216 x = -data->values[0];
217 y = -data->values[1];
219 case AUTO_ROTATION_DEGREE_270: /* Landscape Right */
221 y = -data->values[0];
231 ssize_t sensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, struct epoll_event &event)
235 len = m_event_socket.recv(buffer, buffer_len);
238 if (!m_poller->poll(event))
240 len = m_event_socket.recv(buffer, buffer_len);
243 _E("%s failed to read after poll!", get_client_name());
249 _E("%s failed to recv event from event socket", get_client_name());
256 void sensor_event_listener::listen_events(void)
258 char buffer[EVENT_BUFFER_SIZE];
259 struct epoll_event event;
262 event.events = EPOLLIN | EPOLLPRI;
268 lock l(m_thread_mutex);
269 if (m_thread_state != THREAD_STATE_START)
272 len = sensor_event_poll(buffer, sizeof(sensor_event_t), event);
274 _E("Failed to sensor_event_poll()");
278 sensor_event_t *sensor_event = reinterpret_cast<sensor_event_t *>(buffer);
279 data_len = sensor_event->data_length;
284 buffer_data = malloc(data_len);
286 len = sensor_event_poll(buffer_data, data_len, event);
288 _E("Failed to sensor_event_poll() for sensor_data");
293 sensor_event->data = reinterpret_cast<sensor_data_t *>(buffer_data);
295 handle_events((void *)buffer);
303 close_event_channel();
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();
311 _I("Event listener thread is terminated.");
313 if (m_client_info.has_client_id() && (event.events & EPOLLHUP)) {
319 bool sensor_event_listener::create_event_channel(void)
321 const int client_type = CLIENT_TYPE_SENSOR_CLIENT;
323 channel_ready_t event_channel_ready;
325 if (!m_event_socket.create(SOCK_SEQPACKET))
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());
333 if (!m_event_socket.set_connection_mode()) {
334 _E("Failed to set connection mode for client %s", get_client_name());
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());
343 client_id = m_client_info.get_client_id();
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());
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);
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);
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);
368 void sensor_event_listener::close_event_channel(void)
370 m_event_socket.close();
373 void sensor_event_listener::set_thread_state(thread_state state)
375 lock l(m_thread_mutex);
376 m_thread_state = state;
379 void sensor_event_listener::clear(void)
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);
388 void sensor_event_listener::set_hup_observer(hup_observer_t observer)
390 m_hup_observer = observer;
393 bool sensor_event_listener::start_event_listener(void)
395 if (!create_event_channel()) {
396 _E("Event channel is not established for %s", get_client_name());
400 if (!start_deliverer())
403 m_event_socket.set_transfer_mode();
405 m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
406 retvm_if(!m_poller, false, "Failed to allocate memory");
408 set_thread_state(THREAD_STATE_START);
410 thread listener(&sensor_event_listener::listen_events, this);
416 void sensor_event_listener::stop_event_listener(void)
418 const int THREAD_TERMINATING_TIMEOUT = 2;
419 std::cv_status status;
421 ulock u(m_thread_mutex);
423 /* TOBE: it can be changed to join() simply */
424 if (m_thread_state != THREAD_STATE_TERMINATE) {
425 m_thread_state = THREAD_STATE_STOP;
427 _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
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);
433 _D("Listener thread for %s is terminated", get_client_name());
442 close_event_channel();
445 bool sensor_event_listener::start_deliverer(void)
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");
452 m_cb_deliverer->start();
456 bool sensor_event_listener::stop_deliverer(void)
461 if (!m_cb_deliverer->stop())
464 delete m_cb_deliverer;
465 m_cb_deliverer = NULL;
469 void sensor_event_listener::set_display_rotation(int rt)
471 _D("New display rotation: %d", rt);
473 if (rt < AUTO_ROTATION_DEGREE_0 || rt > AUTO_ROTATION_DEGREE_270)
476 m_display_rotation = rt;