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