Sync with the 3.0
[platform/framework/web/data-provider-master.git] / src / event.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <errno.h>
20 #include <pthread.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26
27 #include <linux/input.h>
28
29 #include <Eina.h>
30 #include <Ecore.h>
31 #include <dlog.h>
32 #include <livebox-errno.h>
33
34 #include "util.h"
35 #include "debug.h"
36 #include "conf.h"
37 #include "event.h"
38
39 #define EVENT_CH        'e'
40
41 #if !defined(ABS_MT_TOOL_X)
42 #define ABS_MT_TOOL_X           0x3c    /* Center X tool position */
43 #endif
44
45 #if !defined(ABS_MT_TOOL_Y)
46 #define ABS_MT_TOOL_Y           0x3d    /* Center Y tool position */
47 #endif
48
49 int errno;
50
51 static struct info {
52         pthread_t tid;
53         Eina_List *event_list;
54         int handle;
55         pthread_mutex_t event_list_lock;
56         int evt_pipe[PIPE_MAX];
57         int tcb_pipe[PIPE_MAX];
58         Ecore_Fd_Handler *event_handler;
59
60         struct event_data event_data;
61
62         Eina_List *event_listener_list;
63         Eina_List *reactivate_list;
64 } s_info = {
65         .event_list = NULL,
66         .handle = -1,
67         .event_handler = NULL,
68
69         .event_data = {
70                 .x = -1,
71                 .y = -1,
72                 .device = -1,
73                 .slot = -1,
74         },
75
76         .event_listener_list = NULL,
77         .reactivate_list = NULL,
78 };
79
80 struct event_listener {
81         int (*event_cb)(enum event_state state, struct event_data *event, void *data);
82         void *cbdata;
83
84         enum event_state state;
85
86 #if defined(_USE_ECORE_TIME_GET)
87         double tv;
88 #else
89         struct timeval tv; /* Recording Activate / Deactivate time */
90 #endif
91         int x; /* RelX */
92         int y; /* RelY */
93 };
94
95 static int activate_thread(void);
96
97 HAPI int event_init(void)
98 {
99         int ret;
100         ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
101         if (ret != 0) {
102                 ErrPrint("Mutex: %s\n", strerror(ret));
103                 return LB_STATUS_ERROR_FAULT;
104         }
105         return LB_STATUS_SUCCESS;
106 }
107
108 HAPI int event_fini(void)
109 {
110         int ret;
111         ret = pthread_mutex_destroy(&s_info.event_list_lock);
112         if (ret != 0) {
113                 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
114         }
115         return LB_STATUS_SUCCESS;
116 }
117
118 static inline int processing_input_event(struct input_event *event)
119 {
120         struct event_data *item;
121
122         switch (event->type) {
123         case EV_SYN:
124                 switch (event->code) {
125                         break;
126                 case SYN_CONFIG:
127                         break;
128                 case SYN_MT_REPORT:
129                 case SYN_REPORT:
130                         if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
131                                 /* Waiting full event packet */
132                                 break;
133                         }
134
135                         item = malloc(sizeof(*item));
136                         if (item) {
137                                 char event_ch = EVENT_CH;
138
139 #if defined(_USE_ECORE_TIME_GET)
140                                 s_info.event_data.tv = ecore_time_get();
141 #else
142                                 if (gettimeofday(&s_info.event_data.tv, NULL) < 0) {
143                                         ErrPrint("gettimeofday: %s\n", strerror(errno));
144                                 }
145 #endif
146
147                                 memcpy(item, &s_info.event_data, sizeof(*item));
148
149                                 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
150                                 s_info.event_list = eina_list_append(s_info.event_list, item);
151                                 CRITICAL_SECTION_END(&s_info.event_list_lock);
152
153                                 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
154                                         ErrPrint("Unable to send an event: %s\n", strerror(errno));
155                                         return LB_STATUS_ERROR_IO;
156                                 }
157
158                                 /* Take a breathe */
159                                 pthread_yield();
160                         } else {
161                                 ErrPrint("Heap: %s\n", strerror(errno));
162                         }
163
164                         if (s_info.event_data.device < 0) {
165                                 s_info.event_data.x = -1;
166                                 s_info.event_data.y = -1;
167                                 s_info.event_data.slot = -1;
168                         }
169                         break;
170                 /*
171                 case SYN_DROPPED:
172                         DbgPrint("EV_SYN, SYN_DROPPED\n");
173                         break;
174                 */
175                 default:
176                         DbgPrint("EV_SYN, 0x%x\n", event->code);
177                         break;
178                 }
179                 break;
180         case EV_KEY:
181                 break;
182         case EV_REL:
183                 break;
184         case EV_ABS:
185                 switch (event->code) {
186                 case ABS_DISTANCE:
187                         s_info.event_data.distance = event->value;
188                         break;
189                 case ABS_MT_TOOL_X:
190                 case ABS_MT_TOOL_Y:
191                         break;
192                 case ABS_MT_POSITION_X:
193                         s_info.event_data.x = event->value;
194                         break;
195                 case ABS_MT_POSITION_Y:
196                         s_info.event_data.y = event->value;
197                         break;
198                 case ABS_MT_SLOT:
199                         s_info.event_data.slot = event->value;
200                         break;
201                 case ABS_MT_TRACKING_ID:
202                         s_info.event_data.device = event->value;
203                         break;
204                 case ABS_MT_TOUCH_MAJOR:
205                         s_info.event_data.touch.major = event->value;
206                         break;
207                 case ABS_MT_TOUCH_MINOR:
208                         s_info.event_data.touch.minor = event->value;
209                         break;
210                 case ABS_MT_WIDTH_MAJOR:
211                         s_info.event_data.width.major = event->value;
212                         break;
213                 case ABS_MT_WIDTH_MINOR:
214                         s_info.event_data.width.minor = event->value;
215                         break;
216                 default:
217                         DbgPrint("EV_ABS, 0x%x\n", event->code);
218                         break;
219                 }
220                 break;
221         case EV_MSC:
222                 break;
223         case EV_SW:
224                 break;
225         case EV_LED:
226                 break;
227         case EV_SND:
228                 break;
229         case EV_REP:
230                 break;
231         case EV_FF:
232                 break;
233         case EV_PWR:
234                 break;
235         case EV_FF_STATUS:
236                 break;
237         default:
238                 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
239                 break;
240         }
241
242         return LB_STATUS_SUCCESS;
243 }
244
245 static void *event_thread_main(void *data)
246 {
247         fd_set set;
248         long ret = 0;
249         struct input_event input_event;
250         char *ptr = (char *)&input_event;
251         int offset = 0;
252         int readsize = 0;
253         int fd;
254
255         DbgPrint("Initiated\n");
256
257         while (1) {
258                 FD_ZERO(&set);
259                 FD_SET(s_info.handle, &set);
260                 FD_SET(s_info.tcb_pipe[PIPE_READ], &set);
261
262                 fd = s_info.handle > s_info.tcb_pipe[PIPE_READ] ? s_info.handle : s_info.tcb_pipe[PIPE_READ];
263                 ret = select(fd + 1, &set, NULL, NULL, NULL);
264                 if (ret < 0) {
265                         ret = -errno;
266                         if (errno == EINTR) {
267                                 DbgPrint("Select receives INTR\n");
268                                 continue;
269                         }
270                         ErrPrint("Error: %s\n", strerror(errno));
271                         break;
272                 } else if (ret == 0) {
273                         ErrPrint("Timeout expired\n");
274                         ret = LB_STATUS_ERROR_TIMEOUT;
275                         break;
276                 }
277
278                 if (FD_ISSET(s_info.handle, &set)) {
279                         readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
280                         if (readsize < 0) {
281                                 ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
282                                 ret = LB_STATUS_ERROR_FAULT;
283                                 break;
284                         }
285
286                         offset += readsize;
287                         if (offset == sizeof(input_event)) {
288                                 offset = 0;
289                                 if (processing_input_event(&input_event) < 0) {
290                                         ret = LB_STATUS_ERROR_FAULT;
291                                         break;
292                                 }
293                         }
294                 }
295
296                 if (FD_ISSET(s_info.tcb_pipe[PIPE_READ], &set)) {
297                         char event_ch;
298
299                         if (read(s_info.tcb_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
300                                 ErrPrint("Unable to read TCB_PIPE: %s\n", strerror(errno));
301                         }
302
303                         ret = LB_STATUS_ERROR_CANCEL;
304                         break;
305                 }
306         }
307
308         return (void *)ret;
309 }
310
311 static inline void clear_all_listener_list(void)
312 {
313         struct event_listener *listener;
314         enum event_state next_state;
315         Eina_List *l;
316         Eina_List *n;
317
318         s_info.event_handler = NULL;
319         CLOSE_PIPE(s_info.evt_pipe);
320
321         while (s_info.event_listener_list) {
322                 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
323                         switch (listener->state) {
324                         case EVENT_STATE_ACTIVATE:
325                                 next_state = EVENT_STATE_ACTIVATED;
326                                 break;
327                         case EVENT_STATE_ACTIVATED:
328                                 next_state = EVENT_STATE_DEACTIVATE;
329                                 break;
330                         case EVENT_STATE_DEACTIVATE:
331                                 next_state = EVENT_STATE_DEACTIVATED;
332                                 break;
333                         case EVENT_STATE_DEACTIVATED:
334                         default:
335                                 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
336                                 DbgFree(listener);
337                                 continue;
338                         }
339
340                         if (listener->event_cb(listener->state, &s_info.event_data, listener->cbdata) < 0) {
341                                 if (eina_list_data_find(s_info.event_listener_list, listener)) {
342                                         s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
343                                         DbgFree(listener);
344                                         continue;
345                                 }
346                         }
347
348                         listener->state = next_state;
349                 }
350         }
351 }
352
353 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
354 {
355         int fd;
356         struct event_data *item;
357         char event_ch;
358         struct event_listener *listener;
359         Eina_List *l;
360         Eina_List *n;
361         enum event_state next_state;
362         enum event_state cur_state;
363         struct event_data modified_item;
364
365         fd = ecore_main_fd_handler_fd_get(handler);
366         if (fd < 0) {
367                 ErrPrint("Invalid fd\n");
368                 return ECORE_CALLBACK_CANCEL;
369         }
370
371         if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
372                 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
373                 return ECORE_CALLBACK_CANCEL;
374         }
375
376         CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
377         item = eina_list_nth(s_info.event_list, 0);
378         if (item) {
379                 s_info.event_list = eina_list_remove(s_info.event_list, item);
380         }
381         CRITICAL_SECTION_END(&s_info.event_list_lock);
382
383         if (item) {
384                 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
385                         switch (listener->state) {
386                         case EVENT_STATE_ACTIVATE:
387 #if defined(_USE_ECORE_TIME_GET)
388                                 if (listener->tv > item->tv) {
389                                         continue;
390                                 }
391 #else
392                                 if (timercmp(&listener->tv, &item->tv, >)) {
393                                         /* Ignore previous events before activating this listener */
394                                         continue;
395                                 }
396 #endif
397
398                                 next_state = EVENT_STATE_ACTIVATED;
399                                 cur_state = listener->state;
400                                 break;
401                         case EVENT_STATE_DEACTIVATE:
402 #if defined(_USE_ECORE_TIME_GET)
403                                 if (listener->tv > item->tv) {
404                                         /* Consuming all events occurred while activating this listener */
405                                         cur_state = EVENT_STATE_ACTIVATED;
406                                         next_state = EVENT_STATE_ACTIVATED;
407                                         break;
408                                 }
409 #else
410                                 if (timercmp(&listener->tv, &item->tv, >)) {
411                                         /* Consuming all events occurred while activating this listener */
412                                         cur_state = EVENT_STATE_ACTIVATED;
413                                         next_state = EVENT_STATE_ACTIVATED;
414                                         break;
415                                 }
416 #endif
417
418                                 cur_state = listener->state;
419                                 next_state = EVENT_STATE_DEACTIVATED;
420                                 break;
421                         case EVENT_STATE_ACTIVATED:
422                                 cur_state = listener->state;
423                                 next_state = listener->state;
424                                 break;
425                         case EVENT_STATE_DEACTIVATED:
426                         default:
427                                 /* Remove this from the list */
428                                         /* Check the item again. the listener can be deleted from the callback */
429                                 if (eina_list_data_find(s_info.event_listener_list, listener)) {
430                                         s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
431                                         DbgFree(listener);
432                                 }
433
434                                 continue;
435                         }
436
437                         memcpy(&modified_item, item, sizeof(modified_item));
438                         modified_item.x -= listener->x;
439                         modified_item.y -= listener->y;
440
441                         if (listener->event_cb(cur_state, &modified_item, listener->cbdata) < 0) {
442                                 if (eina_list_data_find(s_info.event_listener_list, listener)) {
443                                         s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
444                                         DbgFree(listener);
445                                         continue;
446                                 }
447                         }
448
449                         listener->state = next_state;
450                 }
451
452                 DbgFree(item);
453         }
454
455         if (s_info.handle < 0 && !s_info.event_list) {
456                 /* This callback must has to clear all listeners in this case */
457                 clear_all_listener_list();
458
459                 EINA_LIST_FREE(s_info.reactivate_list, listener) {
460                         s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
461                 }
462
463                 if (s_info.event_listener_list) {
464                         if (activate_thread() < 0) {
465                                 EINA_LIST_FREE(s_info.event_listener_list, listener) {
466                                         (void)listener->event_cb(EVENT_STATE_ERROR, NULL, listener->cbdata);
467                                 }
468                         }
469                 }
470
471                 return ECORE_CALLBACK_CANCEL;
472         }
473
474         return ECORE_CALLBACK_RENEW;
475 }
476
477 static int activate_thread(void)
478 {
479         int status;
480
481         s_info.handle = open(INPUT_PATH, O_RDONLY);
482         if (s_info.handle < 0) {
483                 ErrPrint("Unable to access the device: %s\n", strerror(errno));
484                 return LB_STATUS_ERROR_IO;
485         }
486
487         if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0) {
488                 ErrPrint("Error: %s\n", strerror(errno));
489         }
490
491         if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0) {
492                 ErrPrint("Error: %s\n", strerror(errno));
493         }
494
495         status = pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC);
496         if (status < 0) {
497                 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
498                 if (close(s_info.handle) < 0) {
499                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
500                 }
501                 s_info.handle = -1;
502                 return LB_STATUS_ERROR_FAULT;
503         }
504
505         status = pipe2(s_info.tcb_pipe, O_NONBLOCK | O_CLOEXEC);
506         if (status < 0) {
507                 ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
508                 if (close(s_info.handle) < 0) {
509                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
510                 }
511                 s_info.handle = -1;
512                 CLOSE_PIPE(s_info.evt_pipe);
513                 return LB_STATUS_ERROR_FAULT;
514         }
515
516         s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
517         if (!s_info.event_handler) {
518                 if (close(s_info.handle) < 0) {
519                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
520                 }
521                 s_info.handle = -1;
522
523                 CLOSE_PIPE(s_info.tcb_pipe);
524                 CLOSE_PIPE(s_info.evt_pipe);
525                 return LB_STATUS_ERROR_FAULT;
526         }
527
528         status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
529         if (status != 0) {
530                 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
531                 ecore_main_fd_handler_del(s_info.event_handler);
532                 s_info.event_handler = NULL;
533
534                 if (close(s_info.handle) < 0) {
535                         ErrPrint("close: %s\n", strerror(errno));
536                 }
537                 s_info.handle = -1;
538
539                 CLOSE_PIPE(s_info.tcb_pipe);
540                 CLOSE_PIPE(s_info.evt_pipe);
541                 return LB_STATUS_ERROR_FAULT;
542         }
543
544         DbgPrint("Event handler activated\n");
545         return LB_STATUS_SUCCESS;
546 }
547
548 /*!
549  * x, y is the starting point.
550  */
551 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
552 {
553         struct event_listener *listener;
554         int ret = LB_STATUS_SUCCESS;
555
556         listener = malloc(sizeof(*listener));
557         if (!listener) {
558                 ErrPrint("Heap: %s\n", strerror(errno));
559                 return LB_STATUS_ERROR_MEMORY;
560         }
561
562 #if defined(_USE_ECORE_TIME_GET)
563         listener->tv = ecore_time_get();
564 #else
565         if (gettimeofday(&listener->tv, NULL) < 0) {
566                 ErrPrint("gettimeofday: %s\n", strerror(errno));
567                 DbgFree(listener);
568                 return LB_STATUS_ERROR_FAULT;
569         }
570 #endif
571
572         listener->event_cb = event_cb;
573         listener->cbdata = data;
574         listener->state = EVENT_STATE_ACTIVATE;
575         listener->x = x;
576         listener->y = y;
577
578         if (s_info.handle < 0) {
579                 /*!
580                  * \note
581                  * We don't need to lock to access event_list here.
582                  * If the _sinfo.handle is greater than 0, the event_list will not be touched.
583                  * But if the s_info.handle is less than 0, it means, there is not thread,
584                  * so we can access the event_list without lock.
585                  */
586                 if (s_info.event_list) {
587                         DbgPrint("Event thread is deactivating now. activating will be delayed\n");
588                         s_info.reactivate_list = eina_list_append(s_info.reactivate_list, listener);
589                 } else {
590                         s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
591
592                         if ((ret = activate_thread()) < 0) {
593                                 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
594                                 DbgFree(listener);
595                         }
596                 }
597         } else {
598                 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
599         }
600
601         return ret;
602 }
603
604 HAPI int event_deactivate(int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
605 {
606         int status;
607         void *ret;
608         char event_ch = EVENT_CH;
609         struct event_listener *listener = NULL;
610         Eina_List *l;
611         int keep_thread = 0;
612
613         EINA_LIST_FOREACH(s_info.event_listener_list, l, listener) {
614                 if (listener->event_cb == event_cb && listener->cbdata == data) {
615                         listener->state = EVENT_STATE_DEACTIVATE;
616                 }
617
618                 keep_thread += (listener->state == EVENT_STATE_ACTIVATE || listener->state == EVENT_STATE_ACTIVATED);
619         }
620
621         if (!listener) {
622                 ErrPrint("Listener is not registered\n");
623                 return LB_STATUS_ERROR_NOT_EXIST;
624         }
625
626         if (s_info.handle < 0) {
627                 ErrPrint("Event handler is not actiavated\n");
628                 DbgFree(listener);
629                 return LB_STATUS_SUCCESS;
630         }
631
632         if (keep_thread) {
633                 return LB_STATUS_SUCCESS;
634         }
635
636         /* Terminating thread */
637         if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
638                 ErrPrint("Unable to write tcb_pipe: %s\n", strerror(errno));
639         }
640
641         status = pthread_join(s_info.tid, &ret);
642         if (status != 0) {
643                 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
644         } else {
645                 DbgPrint("Thread returns: %p\n", ret);
646         }
647
648         if (close(s_info.handle) < 0) {
649                 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
650         }
651
652         s_info.handle = -1;
653         DbgPrint("Event handler deactivated\n");
654
655         CLOSE_PIPE(s_info.tcb_pipe);
656
657         if (!eina_list_count(s_info.event_list)) {
658                 ecore_main_fd_handler_del(s_info.event_handler);
659                 clear_all_listener_list();
660         }
661
662         s_info.event_data.x = -1;
663         s_info.event_data.y = -1;
664         s_info.event_data.slot = -1;
665         return LB_STATUS_SUCCESS;
666 }
667
668 HAPI int event_is_activated(void)
669 {
670         return s_info.handle >= 0;
671 }
672
673 /* End of a file */