diff options
Diffstat (limited to 'android/protocol/attach-ui-proxy.c')
-rw-r--r-- | android/protocol/attach-ui-proxy.c | 110 |
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; +} |