Refactored user-events protocol

Change-Id: I08afb96ef17a52c3795f5029acfc244a93ab57c7
diff --git a/android/console.c b/android/console.c
index 42c3eb6..59610eb 100644
--- a/android/console.c
+++ b/android/console.c
@@ -52,7 +52,7 @@
 #include "android/charmap.h"
 #include "android/display-core.h"
 #include "android/framebuffer-core.h"
-#include "android/user-events-core.h"
+#include "android/protocol/user-events-impl.h"
 #include "android/protocol/ui-commands-api.h"
 #include "android/protocol/core-commands-impl.h"
 #include "android/protocol/ui-commands-proxy.h"
@@ -126,9 +126,6 @@
 /* User events service client. */
 ControlClient user_events_client = NULL;
 
-/* User events service. */
-CoreUserEvents* core_ue = NULL;
-
 /* UI control service client (UI -> Core). */
 ControlClient ui_core_ctl_client = NULL;
 
@@ -259,7 +256,7 @@
     }
 
     if (client == user_events_client) {
-        coreue_destroy(core_ue);
+        userEventsImpl_destroy();
         user_events_client = NULL;
     }
 
@@ -2592,8 +2589,7 @@
         return -1;
     }
 
-    core_ue = coreue_create(client->sock);
-    if (core_ue != NULL) {
+    if (!userEventsImpl_create(client->sock)) {
         char reply_buf[4096];
         user_events_client = client;
         snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
@@ -2608,7 +2604,7 @@
 }
 
 void
-destroy_control_ue_client(void)
+destroy_user_events_client(void)
 {
     if (user_events_client != NULL) {
         control_client_destroy(user_events_client);
diff --git a/android/main-ui.c b/android/main-ui.c
index 9ab87de..4b86ad1 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -61,6 +61,7 @@
 #include "android/snapshot.h"
 #include "android/core-connection.h"
 #include "android/framebuffer-ui.h"
+#include "android/protocol/user-events-proxy.h"
 #include "android/protocol/core-commands-proxy.h"
 #include "android/protocol/ui-commands-impl.h"
 
@@ -857,9 +858,6 @@
     }
 }
 
-/* Implemented in user-events-ui.c */
-extern int clientue_create(SockAddress* console_socket);
-
 /* Attaches starting UI to a running core process.
  * This routine is called from main() when -attach-core parameter is set,
  * indicating that this UI instance should attach to a running core, rather than
@@ -969,7 +967,7 @@
     }
 
     // Connect to the core's user events service.
-    if (clientue_create(&console_socket)) {
+    if (userEventsProxy_create(&console_socket)) {
         return -1;
     }
 
diff --git a/android/protocol/core-commands-proxy.c b/android/protocol/core-commands-proxy.c
index 6bd3d4e..1bd0937 100644
--- a/android/protocol/core-commands-proxy.c
+++ b/android/protocol/core-commands-proxy.c
@@ -127,10 +127,12 @@
     if (_coreCmdProxy.sync_writer != NULL) {
         syncsocket_close(_coreCmdProxy.sync_writer);
         syncsocket_free(_coreCmdProxy.sync_writer);
+        _coreCmdProxy.sync_writer = NULL;
     }
     if (_coreCmdProxy.sync_reader != NULL) {
         syncsocket_close(_coreCmdProxy.sync_reader);
         syncsocket_free(_coreCmdProxy.sync_reader);
+        _coreCmdProxy.sync_reader = NULL;
     }
     if (_coreCmdProxy.core_connection != NULL) {
         core_connection_close(_coreCmdProxy.core_connection);
diff --git a/android/protocol/user-events-impl.c b/android/protocol/user-events-impl.c
new file mode 100644
index 0000000..5c9525e
--- /dev/null
+++ b/android/protocol/user-events-impl.c
@@ -0,0 +1,206 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains the Core-side of the "user events" service. Here we receive and
+ * handle user events sent from the UI.
+ */
+
+#include "user-events.h"
+#include "android/globals.h"
+#include "android/android.h"
+#include "android/looper.h"
+#include "android/async-utils.h"
+#include "android/sync-utils.h"
+#include "android/utils/system.h"
+#include "android/utils/debug.h"
+#include "android/protocol/user-events-protocol.h"
+#include "android/protocol/user-events-impl.h"
+
+/* Enumerates state values for the event reader in the UserEventsImpl descriptor.
+ */
+typedef enum UserEventsImplState {
+    /* The reader is waiting on event header. */
+    EXPECTS_HEADER,
+
+    /* The reader is waiting on event parameters. */
+    EXPECTS_PARAMETERS,
+} UserEventsImplState;
+
+
+/* Core user events service descriptor. */
+typedef struct UserEventsImpl {
+    /* Reader to receive user events. */
+    AsyncReader         user_events_reader;
+
+    /* I/O associated with this descriptor. */
+    LoopIo              io;
+
+    /* Looper used to communicate user events. */
+    Looper*             looper;
+
+    /* Socket for this service. */
+    int                 sock;
+
+    /* State of the service (see UE_STATE_XXX for possible values). */
+    UserEventsImplState state;
+
+    /* Current event header. */
+    UserEventHeader     event_header;
+
+    /* Current event parameters. */
+    union {
+        UserEventGeneric    generic_event;
+        UserEventMouse      mouse_event;
+        UserEventKeycode    keycode_event;
+    };
+} UserEventsImpl;
+
+/* Implemented in android/console.c */
+extern void destroy_user_events_client(void);
+
+/* One and only one UserEventsImpl instance. */
+static UserEventsImpl   _UserEventsImpl;
+
+/* Asynchronous I/O callback reading user events.
+ * Param:
+ *  opaque - UserEventsImpl instance.
+ */
+static void
+_userEventsImpl_io_func(void* opaque, int fd, unsigned events)
+{
+    UserEventsImpl* ueimpl;
+    AsyncStatus status;
+
+    if (events & LOOP_IO_WRITE) {
+        // We don't use async writer here, so we don't expect
+        // any write callbacks.
+        derror("Unexpected LOOP_IO_WRITE in _userEventsImpl_io_func\n");
+        return;
+    }
+
+    ueimpl = (UserEventsImpl*)opaque;
+    // Read whatever is expected from the socket.
+    status = asyncReader_read(&ueimpl->user_events_reader, &ueimpl->io);
+
+
+    switch (status) {
+        case ASYNC_COMPLETE:
+            switch (ueimpl->state) {
+                case EXPECTS_HEADER:
+                    // We just read event header. Now we expect event parameters.
+                    ueimpl->state = EXPECTS_PARAMETERS;
+                    // Setup the reader depending on the event type.
+                    switch (ueimpl->event_header.event_type) {
+                        case AUSER_EVENT_MOUSE:
+                            asyncReader_init(&ueimpl->user_events_reader,
+                                             &ueimpl->mouse_event,
+                                             sizeof(ueimpl->mouse_event),
+                                             &ueimpl->io);
+                            break;
+
+                        case AUSER_EVENT_KEYCODE:
+                            asyncReader_init(&ueimpl->user_events_reader,
+                                             &ueimpl->keycode_event,
+                                             sizeof(ueimpl->keycode_event),
+                                             &ueimpl->io);
+                            break;
+
+                        case AUSER_EVENT_GENERIC:
+                            asyncReader_init(&ueimpl->user_events_reader,
+                                             &ueimpl->generic_event,
+                                             sizeof(ueimpl->generic_event),
+                                             &ueimpl->io);
+                            break;
+
+                        default:
+                            derror("Unexpected user event type %d\n",
+                                   ueimpl->event_header.event_type);
+                            break;
+                    }
+                    break;
+
+                case EXPECTS_PARAMETERS:
+                    // We just read event parameters. Lets fire the event.
+                    switch (ueimpl->event_header.event_type) {
+                        case AUSER_EVENT_MOUSE:
+                            user_event_mouse(ueimpl->mouse_event.dx,
+                                             ueimpl->mouse_event.dy,
+                                             ueimpl->mouse_event.dz,
+                                             ueimpl->mouse_event.buttons_state);
+                            break;
+
+                        case AUSER_EVENT_KEYCODE:
+                            user_event_keycode(ueimpl->keycode_event.keycode);
+                            break;
+
+                        case AUSER_EVENT_GENERIC:
+                            user_event_generic(ueimpl->generic_event.type,
+                                               ueimpl->generic_event.code,
+                                               ueimpl->generic_event.value);
+                            break;
+
+                        default:
+                            derror("Unexpected user event type %d\n",
+                                   ueimpl->event_header.event_type);
+                            break;
+                    }
+                    // Prepare to receive the next event header.
+                    ueimpl->event_header.event_type = -1;
+                    ueimpl->state = EXPECTS_HEADER;
+                    asyncReader_init(&ueimpl->user_events_reader,
+                                     &ueimpl->event_header,
+                                     sizeof(ueimpl->event_header), &ueimpl->io);
+                    break;
+            }
+            break;
+        case ASYNC_ERROR:
+            loopIo_dontWantRead(&ueimpl->io);
+            if (errno == ECONNRESET) {
+                // UI has exited. We need to destroy user event service.
+                destroy_user_events_client();
+            } else {
+                derror("User event read error %d -> %s\n", errno, errno_str);
+            }
+            break;
+
+        case ASYNC_NEED_MORE:
+            // Transfer will eventually come back into this routine.
+            return;
+    }
+}
+
+int
+userEventsImpl_create(int fd)
+{
+    _UserEventsImpl.sock = fd;
+    _UserEventsImpl.event_header.event_type = -1;
+    _UserEventsImpl.state = EXPECTS_HEADER;
+    _UserEventsImpl.looper = looper_newCore();
+    loopIo_init(&_UserEventsImpl.io, _UserEventsImpl.looper, _UserEventsImpl.sock,
+                _userEventsImpl_io_func, &_UserEventsImpl);
+    asyncReader_init(&_UserEventsImpl.user_events_reader,
+                     &_UserEventsImpl.event_header,
+                     sizeof(_UserEventsImpl.event_header), &_UserEventsImpl.io);
+    return 0;
+}
+
+void
+userEventsImpl_destroy(void)
+{
+    if (_UserEventsImpl.looper != NULL) {
+        // Stop all I/O that may still be going on.
+        loopIo_done(&_UserEventsImpl.io);
+        looper_free(_UserEventsImpl.looper);
+        _UserEventsImpl.looper = NULL;
+    }
+}
diff --git a/android/protocol/user-events-impl.h b/android/protocol/user-events-impl.h
new file mode 100644
index 0000000..af5d5a4
--- /dev/null
+++ b/android/protocol/user-events-impl.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains the Core-side of the "user events" service. Here we receive and
+ * handle user events sent from the UI.
+ */
+
+#ifndef _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H
+#define _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H
+
+/* Creates and initializes descriptor for the Core-side of the "user-events"
+ * service. Note that there can be only one instance of this service in the core.
+ * Param:
+ *  fd - Socket descriptor for the service.
+ * Return:
+ *  0 on success, or < 0 on failure.
+ */
+extern int userEventsImpl_create(int fd);
+
+/* Destroys the descriptor for the Core-side of the "user-events" service. */
+extern void userEventsImpl_destroy(void);
+
+#endif /* _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H */
diff --git a/android/user-events-common.h b/android/protocol/user-events-protocol.h
similarity index 65%
rename from android/user-events-common.h
rename to android/protocol/user-events-protocol.h
index 4d02c09..c1e64e2 100644
--- a/android/user-events-common.h
+++ b/android/protocol/user-events-protocol.h
@@ -10,10 +10,14 @@
 ** GNU General Public License for more details.
 */
 
-#ifndef _ANDROID_USER_EVENTS_COMMON_H
-#define _ANDROID_USER_EVENTS_COMMON_H
+#ifndef _ANDROID_PROTOCOL_USER_EVENTS_H
+#define _ANDROID_PROTOCOL_USER_EVENTS_H
 
-#include "globals.h"
+/*
+ * Contains declarations related to the UI events handled by the Core.
+ */
+
+#include "android/globals.h"
 
 /* Mouse event. */
 #define AUSER_EVENT_MOUSE     0
@@ -22,15 +26,16 @@
 /* Generic event. */
 #define AUSER_EVENT_GENERIC   2
 
-/* Header for user event message sent from UI to the core. */
+/* Header for user event message sent from the UI to the Core.
+ * Every user event sent by the UI begins with this header, immediately followed
+ * by the event parameters (if there are any).
+ */
 typedef struct UserEventHeader {
     /* Event type. See AUSER_EVENT_XXX for possible values. */
     uint8_t event_type;
 } UserEventHeader;
 
-/* Formats mouse event message (AUSER_EVENT_MOUSE) sent from
- * UI to the core.
- */
+/* Formats mouse event message (AUSER_EVENT_MOUSE) */
 typedef struct UserEventMouse {
     int         dx;
     int         dy;
@@ -38,20 +43,16 @@
     unsigned    buttons_state;
 } UserEventMouse;
 
-/* Formats keycode event message (AUSER_EVENT_KEYCODE) sent from
- * UI to the core.
- */
+/* Formats keycode event message (AUSER_EVENT_KEYCODE) */
 typedef struct UserEventKeycode {
     int         keycode;
 } UserEventKeycode;
 
-/* Formats generic event message (AUSER_EVENT_GENERIC) sent from
- * UI to the core.
- */
+/* Formats generic event message (AUSER_EVENT_GENERIC) */
 typedef struct UserEventGeneric {
     int         type;
     int         code;
     int         value;
 } UserEventGeneric;
 
-#endif /* _ANDROID_USER_EVENTS_COMMON_H */
+#endif /* _ANDROID_PROTOCOL_USER_EVENTS_H */
diff --git a/android/protocol/user-events-proxy.c b/android/protocol/user-events-proxy.c
new file mode 100644
index 0000000..d35012f
--- /dev/null
+++ b/android/protocol/user-events-proxy.c
@@ -0,0 +1,180 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+#include "user-events.h"
+#include "console.h"
+#include "android/looper.h"
+#include "android/async-utils.h"
+#include "android/core-connection.h"
+#include "android/utils/debug.h"
+#include "android/protocol/user-events-protocol.h"
+#include "android/protocol/user-events-proxy.h"
+
+/* Descriptor for the user events client. */
+typedef struct UserEventsProxy {
+    /* Core connection instance for the user events client. */
+    CoreConnection* core_connection;
+
+    /* Socket for the client. */
+    int             sock;
+
+    /* Writes user events to the socket. */
+    SyncSocket*     sync_writer;
+} UserEventsProxy;
+
+/* One and only one user events client instance. */
+static UserEventsProxy _userEventsProxy = { 0 };
+
+/* Destroys CoreCmdProxy instance. */
+static void
+_userEventsProxy_destroy(void)
+{
+    if (_userEventsProxy.sync_writer != NULL) {
+        syncsocket_close(_userEventsProxy.sync_writer);
+        syncsocket_free(_userEventsProxy.sync_writer);
+        _userEventsProxy.sync_writer = NULL;
+    }
+    if (_userEventsProxy.core_connection != NULL) {
+        core_connection_close(_userEventsProxy.core_connection);
+        core_connection_free(_userEventsProxy.core_connection);
+        _userEventsProxy.core_connection = NULL;
+    }
+}
+
+/* Sends an event to the core.
+ * Parameters:
+ *  event - Event type. Must be one of the AUSER_EVENT_XXX.
+ *  event_param - Event parameters.
+ *  size - Byte size of the event parameters buffer.
+ * Return:
+ *  0 on success, or -1 on failure.
+ */
+static int
+_userEventsProxy_send(uint8_t event, const void* event_param, size_t size)
+{
+    int res;
+    UserEventHeader header;
+
+    header.event_type = event;
+    res = syncsocket_start_write(_userEventsProxy.sync_writer);
+    if (!res) {
+        // Send event type first (event header)
+        res = syncsocket_write(_userEventsProxy.sync_writer, &header,
+                               sizeof(header),
+                               core_connection_get_timeout(sizeof(header)));
+        if (res > 0) {
+            // Send event param next.
+            res = syncsocket_write(_userEventsProxy.sync_writer, event_param,
+                                   size,
+                                   core_connection_get_timeout(sizeof(size)));
+        }
+        res = syncsocket_result(res);
+        syncsocket_stop_write(_userEventsProxy.sync_writer);
+    }
+    if (res < 0) {
+        derror("Unable to send user event: %s\n", errno_str);
+    }
+    return res;
+}
+
+int
+userEventsProxy_create(SockAddress* console_socket)
+{
+    char* handshake = NULL;
+
+    // Connect to the user-events service.
+    _userEventsProxy.core_connection =
+        core_connection_create_and_switch(console_socket, "user-events",
+                                          &handshake);
+    if (_userEventsProxy.core_connection == NULL) {
+        derror("Unable to connect to the user-events service: %s\n",
+               errno_str);
+        return -1;
+    }
+
+    // Initialze event writer.
+    _userEventsProxy.sock =
+        core_connection_get_socket(_userEventsProxy.core_connection);
+    _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock);
+    if (_userEventsProxy.sync_writer == NULL) {
+        derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str);
+        _userEventsProxy_destroy();
+        return -1;
+    }
+
+    fprintf(stdout, "user-events is now connected to the core at %s.",
+            sock_address_to_string(console_socket));
+    if (handshake != NULL) {
+        if (handshake[0] != '\0') {
+            fprintf(stdout, " Handshake: %s", handshake);
+        }
+        free(handshake);
+    }
+    fprintf(stdout, "\n");
+
+    return 0;
+}
+
+void
+user_event_keycodes(int *kcodes, int count)
+{
+    int nn;
+    for (nn = 0; nn < count; nn++)
+        user_event_keycode(kcodes[nn]);
+}
+
+void
+user_event_keycode(int  kcode)
+{
+    UserEventKeycode    message;
+    message.keycode = kcode;
+    _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message));
+}
+
+void
+user_event_key(unsigned code, unsigned down)
+{
+    if(code == 0) {
+        return;
+    }
+    if (VERBOSE_CHECK(keys))
+        printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );
+
+    user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0));
+}
+
+
+void
+user_event_mouse(int dx, int dy, int dz, unsigned buttons_state)
+{
+    UserEventMouse    message;
+    message.dx = dx;
+    message.dy = dy;
+    message.dz = dz;
+    message.buttons_state = buttons_state;
+    _userEventsProxy_send(AUSER_EVENT_MOUSE, &message, sizeof(message));
+}
+
+void
+user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
+{
+}
+
+void
+user_event_generic(int type, int code, int value)
+{
+    UserEventGeneric    message;
+    message.type = type;
+    message.code = code;
+    message.value = value;
+    _userEventsProxy_send(AUSER_EVENT_GENERIC, &message, sizeof(message));
+}
diff --git a/android/protocol/user-events-proxy.h b/android/protocol/user-events-proxy.h
new file mode 100644
index 0000000..95f6614
--- /dev/null
+++ b/android/protocol/user-events-proxy.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains the UI-side of the "user events" service. Here we send user events
+ * to the Core.
+ */
+
+#ifndef _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H
+#define _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H
+
+/* Creates and initializes descriptor for the UI-side of the "user-events"
+ * service. Note that there can be only one instance of this service in the UI.
+ * Param:
+ *  console_socket - Addresses Core's console.
+ * Return:
+ *  0 on success, or < 0 on failure.
+ */
+extern int userEventsProxy_create(SockAddress* console_socket);
+
+#endif /* _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H */
diff --git a/android/user-events-core.c b/android/user-events-core.c
deleted file mode 100644
index 3b97c00..0000000
--- a/android/user-events-core.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (C) 2010 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-*/
-
-#include "user-events.h"
-#include "android/globals.h"
-#include "android/android.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/user-events-common.h"
-#include "android/user-events-core.h"
-#include "android/sync-utils.h"
-
-/* States of the core user events service.
- */
-
-/* Event header is expected in the pipe. */
-#define UE_STATE_EVENT_HEADER  0
-/* Event parameters are expected in the pipe. */
-#define UE_STATE_EVENT_PARAM   1
-
-/* Core user events service descriptor. */
-struct CoreUserEvents {
-    /* Reader to receive user events. */
-    AsyncReader     user_events_reader;
-
-    /* I/O associated with this descriptor. */
-    LoopIo          io;
-
-    /* Looper used to communicate user events. */
-    Looper*         looper;
-
-    /* Socket for this service. */
-    int             sock;
-
-    /* State of the service (see UE_STATE_XXX for possible values). */
-    int             state;
-
-    /* Current event header. */
-    UserEventHeader event_header;
-
-    /* Current event parameters. */
-    union {
-        UserEventGeneric    generic_event;
-        UserEventMouse      mouse_event;
-        UserEventKeycode    keycode_event;
-    };
-};
-
-/* Implemented in android/console.c */
-extern void destroy_control_ue_client(void);
-
-/*
- * Asynchronous I/O callback launched when reading user events from the socket.
- * Param:
- *  opaque - CoreUserEvents instance.
- */
-static void
-coreue_io_func(void* opaque, int fd, unsigned events)
-{
-    CoreUserEvents* ue = opaque;
-    // Read whatever is expected from the socket.
-    const AsyncStatus status = asyncReader_read(&ue->user_events_reader, &ue->io);
-
-    switch (status) {
-        case ASYNC_COMPLETE:
-            switch (ue->state) {
-                case UE_STATE_EVENT_HEADER:
-                    // We just read event header. Now we expect event parameters.
-                    ue->state = UE_STATE_EVENT_PARAM;
-                    // Setup the reader depending on the event type.
-                    switch (ue->event_header.event_type) {
-                        case AUSER_EVENT_MOUSE:
-                            asyncReader_init(&ue->user_events_reader,
-                                             &ue->mouse_event,
-                                             sizeof(ue->mouse_event),
-                                             &ue->io);
-                            break;
-                        case AUSER_EVENT_KEYCODE:
-                            asyncReader_init(&ue->user_events_reader,
-                                             &ue->keycode_event,
-                                             sizeof(ue->keycode_event),
-                                             &ue->io);
-                            break;
-                        case AUSER_EVENT_GENERIC:
-                            asyncReader_init(&ue->user_events_reader,
-                                             &ue->generic_event,
-                                             sizeof(ue->generic_event),
-                                             &ue->io);
-                            break;
-                        default:
-                            derror("Unexpected event type %d\n",
-                                   ue->event_header.event_type);
-                            break;
-                    }
-                    break;
-
-                case UE_STATE_EVENT_PARAM:
-                    // We just read event parameters. Lets fire the event.
-                    switch (ue->event_header.event_type) {
-                        case AUSER_EVENT_MOUSE:
-                            user_event_mouse(ue->mouse_event.dx,
-                                             ue->mouse_event.dy,
-                                             ue->mouse_event.dz,
-                                             ue->mouse_event.buttons_state);
-                            break;
-                        case AUSER_EVENT_KEYCODE:
-                            user_event_keycode(ue->keycode_event.keycode);
-                            break;
-                        case AUSER_EVENT_GENERIC:
-                            user_event_generic(ue->generic_event.type,
-                                               ue->generic_event.code,
-                                               ue->generic_event.value);
-                            break;
-                        default:
-                            derror("Unexpected event type %d\n",
-                                   ue->event_header.event_type);
-                            break;
-                    }
-                    // Now we expect event header.
-                    ue->event_header.event_type = -1;
-                    ue->state = UE_STATE_EVENT_HEADER;
-                    asyncReader_init(&ue->user_events_reader, &ue->event_header,
-                                     sizeof(ue->event_header), &ue->io);
-                    break;
-            }
-            break;
-        case ASYNC_ERROR:
-            loopIo_dontWantRead(&ue->io);
-            if (errno == ECONNRESET) {
-                // UI has exited. We need to destroy user event service.
-                destroy_control_ue_client();
-            }
-            break;
-
-        case ASYNC_NEED_MORE:
-            // Transfer will eventually come back into this routine.
-            return;
-    }
-}
-
-CoreUserEvents*
-coreue_create(int fd)
-{
-    CoreUserEvents* ue;
-    ANEW0(ue);
-    ue->sock = fd;
-    ue->state = UE_STATE_EVENT_HEADER;
-    ue->looper = looper_newCore();
-    loopIo_init(&ue->io, ue->looper, ue->sock, coreue_io_func, ue);
-    asyncReader_init(&ue->user_events_reader, &ue->event_header,
-                     sizeof(ue->event_header), &ue->io);
-    return ue;
-}
-
-void
-coreue_destroy(CoreUserEvents* ue)
-{
-    if (ue != NULL) {
-        if (ue->looper != NULL) {
-            // Stop all I/O that may still be going on.
-            loopIo_done(&ue->io);
-            looper_free(ue->looper);
-            ue->looper = NULL;
-        }
-        free(ue);
-    }
-}
diff --git a/android/user-events-core.h b/android/user-events-core.h
deleted file mode 100644
index 04bab6c..0000000
--- a/android/user-events-core.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (C) 2010 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-*/
-
-/*
- * Contains recepient of user events sent from the UI.
- */
-
-#ifndef _ANDROID_USER_EVENTS_CORE_H
-#define _ANDROID_USER_EVENTS_CORE_H
-
-/* Descriptor for a core user events instance */
-typedef struct CoreUserEvents CoreUserEvents;
-
-/*
- * Creates and initializes core user events instance.
- * Param:
- *  fd - Socket descriptor for the service.
- */
-extern CoreUserEvents* coreue_create(int fd);
-
-/*
- * Destroys core user events service.
- * Param:
- *  ue - User event service descriptor to destroy.
- */
-extern void coreue_destroy(CoreUserEvents* ue);
-
-#endif /* _ANDROID_USER_EVENTS_CORE_H */