aboutsummaryrefslogtreecommitdiffstats
path: root/android/protocol/attach-ui-proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/protocol/attach-ui-proxy.c')
-rw-r--r--android/protocol/attach-ui-proxy.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/android/protocol/attach-ui-proxy.c b/android/protocol/attach-ui-proxy.c
new file mode 100644
index 0000000..191b36d
--- /dev/null
+++ b/android/protocol/attach-ui-proxy.c
@@ -0,0 +1,110 @@
+/* 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 implementation of the "attach-ui" service that is
+ * used to establish connection between the UI and the Core.
+ */
+
+#include "android/android.h"
+#include "android/globals.h"
+#include "android/looper.h"
+#include "android/async-utils.h"
+#include "android/sync-utils.h"
+#include "android/utils/debug.h"
+#include "android/protocol/core-commands.h"
+#include "android/protocol/core-commands-impl.h"
+
+/* Descriptor for the UI attach-ui proxy. */
+typedef struct AttachUIProxy {
+ /* Reader to detect UI disconnection. */
+ AsyncReader async_reader;
+
+ /* I/O associated with this descriptor. */
+ LoopIo io;
+
+ /* Looper used to communicate with the UI. */
+ Looper* looper;
+
+ /* Socket descriptor for this service. */
+ int sock;
+} AttachUIProxy;
+
+/* One and only one AttachUIProxy instance. */
+static AttachUIProxy _attachUiProxy;
+
+/* Implemented in android/console.c */
+extern void destroy_attach_ui_client(void);
+
+/* Asynchronous I/O callback for AttachUIProxy instance.
+ * We expect this callback to be called only on UI detachment condition. In this
+ * case the event should be LOOP_IO_READ, and read should fail with errno set
+ * to ECONNRESET.
+ * Param:
+ * opaque - AttachUIProxy instance.
+ */
+static void
+_attachUiProxy_io_func(void* opaque, int fd, unsigned events)
+{
+ AttachUIProxy* uicmd = (AttachUIProxy*)opaque;
+ AsyncReader reader;
+ AsyncStatus status;
+ uint8_t read_buf[1];
+
+ if (events & LOOP_IO_WRITE) {
+ derror("Unexpected LOOP_IO_WRITE in _attachUiProxy_io_func.\n");
+ return;
+ }
+
+ // Try to read
+ asyncReader_init(&reader, read_buf, sizeof(read_buf), &uicmd->io);
+ status = asyncReader_read(&reader, &uicmd->io);
+ // We expect only error status here.
+ if (status != ASYNC_ERROR) {
+ derror("Unexpected read status %d in _attachUiProxy_io_func\n", status);
+ return;
+ }
+ // We expect only socket disconnection error here.
+ if (errno != ECONNRESET) {
+ derror("Unexpected read error %d (%s) in _attachUiProxy_io_func.\n",
+ errno, errno_str);
+ return;
+ }
+
+ // Client got disconnectted.
+ destroy_attach_ui_client();
+}
+
+int
+attachUiProxy_create(int fd)
+{
+ // Initialize the only AttachUIProxy instance.
+ _attachUiProxy.sock = fd;
+ _attachUiProxy.looper = looper_newCore();
+ loopIo_init(&_attachUiProxy.io, _attachUiProxy.looper, _attachUiProxy.sock,
+ _attachUiProxy_io_func, &_attachUiProxy);
+ loopIo_wantRead(&_attachUiProxy.io);
+
+ return 0;
+}
+
+void
+attachUiProxy_destroy(void)
+{
+ if (_attachUiProxy.looper != NULL) {
+ // Stop all I/O that may still be going on.
+ loopIo_done(&_attachUiProxy.io);
+ looper_free(_attachUiProxy.looper);
+ _attachUiProxy.looper = NULL;
+ }
+ _attachUiProxy.sock = -1;
+}