From 85276806ec6ac969d7befa2496c1de59adaaac74 Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Mon, 31 Jan 2011 15:18:45 -0800 Subject: Refactor attach-UI service Change-Id: Ia68ceb57ee5b5a66fa76b837fe3b990eb12e7188 --- android/protocol/attach-ui-impl.c | 83 +++++++++++++++++++++++++ android/protocol/attach-ui-impl.h | 39 ++++++++++++ android/protocol/attach-ui-proxy.c | 110 +++++++++++++++++++++++++++++++++ android/protocol/attach-ui-proxy.h | 33 ++++++++++ android/protocol/core-commands-proxy.c | 46 +++++++------- android/protocol/core-commands-proxy.h | 3 + android/protocol/ui-commands-impl.c | 42 ++++++------- android/protocol/ui-commands-impl.h | 3 + android/protocol/user-events-proxy.c | 32 +++++----- android/protocol/user-events-proxy.h | 3 + 10 files changed, 332 insertions(+), 62 deletions(-) create mode 100644 android/protocol/attach-ui-impl.c create mode 100644 android/protocol/attach-ui-impl.h create mode 100644 android/protocol/attach-ui-proxy.c create mode 100644 android/protocol/attach-ui-proxy.h (limited to 'android/protocol') diff --git a/android/protocol/attach-ui-impl.c b/android/protocol/attach-ui-impl.c new file mode 100644 index 0000000..8ca204c --- /dev/null +++ b/android/protocol/attach-ui-impl.c @@ -0,0 +1,83 @@ +/* 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 implementation of the "core-ui-control" service that is + * part of the UI control protocol. Here we handle UI control commands received + * from the Core. + */ + +#include "android/core-connection.h" +#include "android/utils/debug.h" +#include "android/utils/panic.h" +#include "android/protocol/attach-ui-impl.h" + +/* Descriptor for the UI-side of the "attach-ui" service. */ +typedef struct AttachUIImpl { + /* Address of the Core's console socket. */ + SockAddress console_socket; + + /* Core connection established for this service. */ + CoreConnection* core_connection; + + /* Socket descriptor for the UI service. */ + int sock; +} AttachUIImpl; + +/* One and only one AttachUIImpl instance. */ +static AttachUIImpl _attachUiImpl; + +SockAddress* +attachUiImpl_get_console_socket(void) +{ + return &_attachUiImpl.console_socket; +} + +int +attachUiImpl_create(SockAddress* console_socket) +{ + char* handshake = NULL; + + _attachUiImpl.console_socket = *console_socket; + + // Connect to the core-ui-control service. + _attachUiImpl.core_connection = + core_connection_create_and_switch(console_socket, "attach-UI", + &handshake); + if (_attachUiImpl.core_connection == NULL) { + derror("Unable to connect to the attach-UI service: %s\n", + errno_str); + return -1; + } + + fprintf(stdout, "UI is now attached 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 +attachUiImpl_destroy(void) +{ + if (_attachUiImpl.core_connection != NULL) { + core_connection_close(_attachUiImpl.core_connection); + core_connection_free(_attachUiImpl.core_connection); + _attachUiImpl.core_connection = NULL; + } +} diff --git a/android/protocol/attach-ui-impl.h b/android/protocol/attach-ui-impl.h new file mode 100644 index 0000000..3adc83a --- /dev/null +++ b/android/protocol/attach-ui-impl.h @@ -0,0 +1,39 @@ +/* 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. +*/ + +#ifndef _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H +#define _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H + +#include "sockets.h" + +/* + * Contains the UI-side implementation of the "attach-ui" service that is + * used to establish connection between the UI and the Core. + */ + +/* Creates and initializes descriptor for the UI-side of the "atatch-ui" + * service. Note that there can be only one instance of this service in the core. + * Param: + * console_socket - Addresses Core's console. + * Return: + * 0 on success, or < 0 on failure. + */ +extern int attachUiImpl_create(SockAddress* console_socket); + +/* Destroys the descriptor for the UI-side of the "attach-ui" service. */ +extern void attachUiImpl_destroy(void); + +/* Gets Core's console socket address for the attached UI. */ +extern SockAddress* attachUiImpl_get_console_socket(void); + +#endif /* _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H */ + 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; +} diff --git a/android/protocol/attach-ui-proxy.h b/android/protocol/attach-ui-proxy.h new file mode 100644 index 0000000..a7d54f4 --- /dev/null +++ b/android/protocol/attach-ui-proxy.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. +*/ + +#ifndef _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H +#define _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H + +/* + * Contains the Core-side implementation of the "attach-ui" service that is + * used to establish connection between the UI and the Core. + */ + +/* Creates and initializes descriptor for the Core-side of the "atatch-ui" + * service. Note that there can be only one instance of this service in the core. + * Param: + * fd - Socket descriptor for the proxy. + * Return: + * 0 on success, or < 0 on failure. + */ +extern int attachUiProxy_create(int fd); + +/* Destroys the descriptor for the Core-side of the "attach-ui" service. */ +extern void attachUiProxy_destroy(void); + +#endif /* _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H */ diff --git a/android/protocol/core-commands-proxy.c b/android/protocol/core-commands-proxy.c index 1bd0937..a52a376 100644 --- a/android/protocol/core-commands-proxy.c +++ b/android/protocol/core-commands-proxy.c @@ -120,27 +120,6 @@ _coreCmdProxy_get_response(UICmdRespHeader* resp, void** resp_data) return status; } -/* Destroys CoreCmdProxy instance. */ -static void -_coreCmdProxy_destroy(void) -{ - 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); - core_connection_free(_coreCmdProxy.core_connection); - _coreCmdProxy.core_connection = NULL; - } -} - int corecmd_set_coarse_orientation(AndroidCoarseOrientation orient) { @@ -351,13 +330,13 @@ coreCmdProxy_create(SockAddress* console_socket) _coreCmdProxy.sync_writer = syncsocket_init(_coreCmdProxy.sock); if (_coreCmdProxy.sync_writer == NULL) { derror("Unable to initialize CoreCmdProxy writer: %s\n", errno_str); - _coreCmdProxy_destroy(); + coreCmdProxy_destroy(); return -1; } _coreCmdProxy.sync_reader = syncsocket_init(_coreCmdProxy.sock); if (_coreCmdProxy.sync_reader == NULL) { derror("Unable to initialize CoreCmdProxy reader: %s\n", errno_str); - _coreCmdProxy_destroy(); + coreCmdProxy_destroy(); return -1; } @@ -374,3 +353,24 @@ coreCmdProxy_create(SockAddress* console_socket) return 0; } + +/* Destroys CoreCmdProxy instance. */ +void +coreCmdProxy_destroy(void) +{ + 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); + core_connection_free(_coreCmdProxy.core_connection); + _coreCmdProxy.core_connection = NULL; + } +} diff --git a/android/protocol/core-commands-proxy.h b/android/protocol/core-commands-proxy.h index 8303ed4..4283296 100644 --- a/android/protocol/core-commands-proxy.h +++ b/android/protocol/core-commands-proxy.h @@ -29,4 +29,7 @@ */ extern int coreCmdProxy_create(SockAddress* console_socket); +/* Destroys the UI-side of the "ui-core-control" */ +void coreCmdProxy_destroy(void); + #endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H */ diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c index 456c61e..30d5277 100644 --- a/android/protocol/ui-commands-impl.c +++ b/android/protocol/ui-commands-impl.c @@ -17,7 +17,6 @@ */ #include "console.h" -//#include "android/hw-control.h" #include "android/looper.h" #include "android/core-connection.h" #include "android/async-utils.h" @@ -73,25 +72,6 @@ static UICmdImpl _uiCmdImpl; static AndroidHwLightBrightnessCallback _brightness_change_callback = NULL; static void* _brightness_change_callback_param = NULL; -/* Destroys UICmdImpl instance. */ -static void -_uiCmdImpl_destroy() -{ - if (_uiCmdImpl.core_connection != NULL) { - // Disable I/O callbacks. - qemu_set_fd_handler(_uiCmdImpl.sock, NULL, NULL, NULL); - core_connection_close(_uiCmdImpl.core_connection); - core_connection_free(_uiCmdImpl.core_connection); - _uiCmdImpl.core_connection = NULL; - } - // Properly deallocate the reader buffer. - if (_uiCmdImpl.reader_buffer != NULL && - _uiCmdImpl.reader_buffer != (uint8_t*)&_uiCmdImpl.cmd_header) { - free(_uiCmdImpl.reader_buffer); - _uiCmdImpl.reader_buffer = (uint8_t*)&_uiCmdImpl.cmd_header; - } -} - /* Handles UI control command received from the core. * Param: * uicmd - UICmdImpl instance that received the command. @@ -146,7 +126,7 @@ _uiCmdImpl_io_read(void* opaque) if (status == 0) { /* Disconnection, meaning that the core process got termonated. */ fprintf(stderr, "core-ui-control service got disconnected\n"); - _uiCmdImpl_destroy(); + uiCmdImpl_destroy(); return; } if (status < 0) { @@ -227,7 +207,7 @@ uiCmdImpl_create(SockAddress* console_socket) &_uiCmdImpl)) { derror("Unable to set up UI _uiCmdImpl_io_read callback: %s\n", errno_str); - _uiCmdImpl_destroy(); + uiCmdImpl_destroy(); if (handshake != NULL) { free(handshake); } @@ -247,6 +227,24 @@ uiCmdImpl_create(SockAddress* console_socket) return 0; } +void +uiCmdImpl_destroy(void) +{ + if (_uiCmdImpl.core_connection != NULL) { + // Disable I/O callbacks. + qemu_set_fd_handler(_uiCmdImpl.sock, NULL, NULL, NULL); + core_connection_close(_uiCmdImpl.core_connection); + core_connection_free(_uiCmdImpl.core_connection); + _uiCmdImpl.core_connection = NULL; + } + // Properly deallocate the reader buffer. + if (_uiCmdImpl.reader_buffer != NULL && + _uiCmdImpl.reader_buffer != (uint8_t*)&_uiCmdImpl.cmd_header) { + free(_uiCmdImpl.reader_buffer); + _uiCmdImpl.reader_buffer = (uint8_t*)&_uiCmdImpl.cmd_header; + } +} + int uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback, void* opaque) diff --git a/android/protocol/ui-commands-impl.h b/android/protocol/ui-commands-impl.h index 0e5b52f..fa05e8e 100644 --- a/android/protocol/ui-commands-impl.h +++ b/android/protocol/ui-commands-impl.h @@ -31,4 +31,7 @@ */ extern int uiCmdImpl_create(SockAddress* console_socket); +/* Destroys UI-side of the "core-ui-control" service. */ +extern void uiCmdImpl_destroy(); + #endif /* _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H */ diff --git a/android/protocol/user-events-proxy.c b/android/protocol/user-events-proxy.c index d35012f..2049b68 100644 --- a/android/protocol/user-events-proxy.c +++ b/android/protocol/user-events-proxy.c @@ -34,22 +34,6 @@ typedef struct 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. @@ -107,7 +91,7 @@ userEventsProxy_create(SockAddress* console_socket) _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock); if (_userEventsProxy.sync_writer == NULL) { derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str); - _userEventsProxy_destroy(); + userEventsProxy_destroy(); return -1; } @@ -125,6 +109,20 @@ userEventsProxy_create(SockAddress* console_socket) } 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; + } +} +void user_event_keycodes(int *kcodes, int count) { int nn; diff --git a/android/protocol/user-events-proxy.h b/android/protocol/user-events-proxy.h index 95f6614..08a80cf 100644 --- a/android/protocol/user-events-proxy.h +++ b/android/protocol/user-events-proxy.h @@ -27,4 +27,7 @@ */ extern int userEventsProxy_create(SockAddress* console_socket); +/* Destroys the UI-side of the "user-events". */ +extern void userEventsProxy_destroy(void); + #endif /* _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H */ -- cgit v1.1