Home | History | Annotate | Download | only in protocol
      1 /* Copyright (C) 2010 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 
     13 /*
     14  * Contains the Core-side of the "user events" service. Here we receive and
     15  * handle user events sent from the UI.
     16  */
     17 
     18 #include "user-events.h"
     19 #include "android/globals.h"
     20 #include "android/android.h"
     21 #include "android/looper.h"
     22 #include "android/async-utils.h"
     23 #include "android/sync-utils.h"
     24 #include "android/utils/system.h"
     25 #include "android/utils/debug.h"
     26 #include "android/protocol/user-events-protocol.h"
     27 #include "android/protocol/user-events-impl.h"
     28 
     29 /* Enumerates state values for the event reader in the UserEventsImpl descriptor.
     30  */
     31 typedef enum UserEventsImplState {
     32     /* The reader is waiting on event header. */
     33     EXPECTS_HEADER,
     34 
     35     /* The reader is waiting on event parameters. */
     36     EXPECTS_PARAMETERS,
     37 } UserEventsImplState;
     38 
     39 
     40 /* Core user events service descriptor. */
     41 typedef struct UserEventsImpl {
     42     /* Reader to receive user events. */
     43     AsyncReader         user_events_reader;
     44 
     45     /* I/O associated with this descriptor. */
     46     LoopIo              io;
     47 
     48     /* Looper used to communicate user events. */
     49     Looper*             looper;
     50 
     51     /* Socket for this service. */
     52     int                 sock;
     53 
     54     /* State of the service (see UE_STATE_XXX for possible values). */
     55     UserEventsImplState state;
     56 
     57     /* Current event header. */
     58     UserEventHeader     event_header;
     59 
     60     /* Current event parameters. */
     61     union {
     62         UserEventGeneric    generic_event;
     63         UserEventMouse      mouse_event;
     64         UserEventKeycode    keycode_event;
     65     };
     66 } UserEventsImpl;
     67 
     68 /* Implemented in android/console.c */
     69 extern void destroy_user_events_client(void);
     70 
     71 /* One and only one UserEventsImpl instance. */
     72 static UserEventsImpl   _UserEventsImpl;
     73 
     74 /* Asynchronous I/O callback reading user events.
     75  * Param:
     76  *  opaque - UserEventsImpl instance.
     77  */
     78 static void
     79 _userEventsImpl_io_func(void* opaque, int fd, unsigned events)
     80 {
     81     UserEventsImpl* ueimpl;
     82     AsyncStatus status;
     83 
     84     if (events & LOOP_IO_WRITE) {
     85         // We don't use async writer here, so we don't expect
     86         // any write callbacks.
     87         derror("Unexpected LOOP_IO_WRITE in _userEventsImpl_io_func\n");
     88         return;
     89     }
     90 
     91     ueimpl = (UserEventsImpl*)opaque;
     92     // Read whatever is expected from the socket.
     93     status = asyncReader_read(&ueimpl->user_events_reader);
     94 
     95 
     96     switch (status) {
     97         case ASYNC_COMPLETE:
     98             switch (ueimpl->state) {
     99                 case EXPECTS_HEADER:
    100                     // We just read event header. Now we expect event parameters.
    101                     ueimpl->state = EXPECTS_PARAMETERS;
    102                     // Setup the reader depending on the event type.
    103                     switch (ueimpl->event_header.event_type) {
    104                         case AUSER_EVENT_MOUSE:
    105                             asyncReader_init(&ueimpl->user_events_reader,
    106                                              &ueimpl->mouse_event,
    107                                              sizeof(ueimpl->mouse_event),
    108                                              &ueimpl->io);
    109                             break;
    110 
    111                         case AUSER_EVENT_KEYCODE:
    112                             asyncReader_init(&ueimpl->user_events_reader,
    113                                              &ueimpl->keycode_event,
    114                                              sizeof(ueimpl->keycode_event),
    115                                              &ueimpl->io);
    116                             break;
    117 
    118                         case AUSER_EVENT_GENERIC:
    119                             asyncReader_init(&ueimpl->user_events_reader,
    120                                              &ueimpl->generic_event,
    121                                              sizeof(ueimpl->generic_event),
    122                                              &ueimpl->io);
    123                             break;
    124 
    125                         default:
    126                             derror("Unexpected user event type %d\n",
    127                                    ueimpl->event_header.event_type);
    128                             break;
    129                     }
    130                     break;
    131 
    132                 case EXPECTS_PARAMETERS:
    133                     // We just read event parameters. Lets fire the event.
    134                     switch (ueimpl->event_header.event_type) {
    135                         case AUSER_EVENT_MOUSE:
    136                             user_event_mouse(ueimpl->mouse_event.dx,
    137                                              ueimpl->mouse_event.dy,
    138                                              ueimpl->mouse_event.dz,
    139                                              ueimpl->mouse_event.buttons_state);
    140                             break;
    141 
    142                         case AUSER_EVENT_KEYCODE:
    143                             user_event_keycode(ueimpl->keycode_event.keycode);
    144                             break;
    145 
    146                         case AUSER_EVENT_GENERIC:
    147                             user_event_generic(ueimpl->generic_event.type,
    148                                                ueimpl->generic_event.code,
    149                                                ueimpl->generic_event.value);
    150                             break;
    151 
    152                         default:
    153                             derror("Unexpected user event type %d\n",
    154                                    ueimpl->event_header.event_type);
    155                             break;
    156                     }
    157                     // Prepare to receive the next event header.
    158                     ueimpl->event_header.event_type = -1;
    159                     ueimpl->state = EXPECTS_HEADER;
    160                     asyncReader_init(&ueimpl->user_events_reader,
    161                                      &ueimpl->event_header,
    162                                      sizeof(ueimpl->event_header), &ueimpl->io);
    163                     break;
    164             }
    165             break;
    166         case ASYNC_ERROR:
    167             loopIo_dontWantRead(&ueimpl->io);
    168             if (errno == ECONNRESET) {
    169                 // UI has exited. We need to destroy user event service.
    170                 destroy_user_events_client();
    171             } else {
    172                 derror("User event read error %d -> %s\n", errno, errno_str);
    173             }
    174             break;
    175 
    176         case ASYNC_NEED_MORE:
    177             // Transfer will eventually come back into this routine.
    178             return;
    179     }
    180 }
    181 
    182 int
    183 userEventsImpl_create(int fd)
    184 {
    185     _UserEventsImpl.sock = fd;
    186     _UserEventsImpl.event_header.event_type = -1;
    187     _UserEventsImpl.state = EXPECTS_HEADER;
    188     _UserEventsImpl.looper = looper_newCore();
    189     loopIo_init(&_UserEventsImpl.io, _UserEventsImpl.looper, _UserEventsImpl.sock,
    190                 _userEventsImpl_io_func, &_UserEventsImpl);
    191     asyncReader_init(&_UserEventsImpl.user_events_reader,
    192                      &_UserEventsImpl.event_header,
    193                      sizeof(_UserEventsImpl.event_header), &_UserEventsImpl.io);
    194     return 0;
    195 }
    196 
    197 void
    198 userEventsImpl_destroy(void)
    199 {
    200     if (_UserEventsImpl.looper != NULL) {
    201         // Stop all I/O that may still be going on.
    202         loopIo_done(&_UserEventsImpl.io);
    203         looper_free(_UserEventsImpl.looper);
    204         _UserEventsImpl.looper = NULL;
    205     }
    206 }
    207