aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-01-26 11:19:19 -0800
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-01-28 09:14:01 -0800
commit777eb68eb60cac18f4b62e2e1b14a906875cbe7a (patch)
tree5850f03e01bb348ad7fc4e92dd08695416650c48
parent316669d58104cb260e2ffa1848f24547b71af49c (diff)
downloadexternal_qemu-777eb68eb60cac18f4b62e2e1b14a906875cbe7a.zip
external_qemu-777eb68eb60cac18f4b62e2e1b14a906875cbe7a.tar.gz
external_qemu-777eb68eb60cac18f4b62e2e1b14a906875cbe7a.tar.bz2
Refactored ui-core-control and core-ui-control protocols
Also cleaned the code up from obsolete ui-core-protocol.* and core-ui-protocol.* Change-Id: I194bec669d25b68a10c32b2be50bc9da50c52ebb
-rw-r--r--Makefile.android11
-rw-r--r--android/console.c32
-rw-r--r--android/core-connection.c40
-rw-r--r--android/core-connection.h32
-rw-r--r--android/core-ui-protocol.c41
-rw-r--r--android/core-ui-protocol.h27
-rw-r--r--android/help.c6
-rw-r--r--android/main-ui.c12
-rw-r--r--android/protocol/core-commands-api.h95
-rw-r--r--android/protocol/core-commands-impl.c440
-rw-r--r--android/protocol/core-commands-impl.h34
-rw-r--r--android/protocol/core-commands-proxy.c374
-rw-r--r--android/protocol/core-commands-proxy.h32
-rw-r--r--android/protocol/core-commands-qemu.c108
-rw-r--r--android/protocol/core-commands.h104
-rw-r--r--android/protocol/ui-commands-api.h41
-rw-r--r--android/protocol/ui-commands-impl.c257
-rw-r--r--android/protocol/ui-commands-impl.h34
-rw-r--r--android/protocol/ui-commands-proxy.c209
-rw-r--r--android/protocol/ui-commands-proxy.h41
-rw-r--r--android/protocol/ui-commands-qemu.c40
-rw-r--r--android/protocol/ui-commands.h44
-rw-r--r--android/protocol/ui-common.h53
-rw-r--r--android/qemu-setup.c1
-rw-r--r--android/qemulator.c18
-rw-r--r--android/skin/window.c6
-rw-r--r--android/ui-core-protocol.c173
-rw-r--r--android/ui-core-protocol.h88
-rw-r--r--android/ui-ctl-common.h144
-rw-r--r--android/ui-ctl-core.c568
-rw-r--r--android/ui-ctl-core.h63
-rw-r--r--android/ui-ctl-ui.c568
-rw-r--r--android/ui-ctl-ui.h108
33 files changed, 2026 insertions, 1818 deletions
diff --git a/Makefile.android b/Makefile.android
index 58b37f1..a5336aa 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -799,9 +799,6 @@ UI_AND_CORE_CFLAGS += $(ZLIB_CFLAGS) -I$(LOCAL_PATH)/$(ZLIB_DIR)
UI_AND_CORE_SOURCES += $(LIBPNG_SOURCES)
UI_AND_CORE_CFLAGS += $(LIBPNG_CFLAGS) -I$(LOCAL_PATH)/$(LIBPNG_DIR)
-# temp files used to collect UI->Core exchange protocol.
-UI_AND_CORE_SOURCES += android/ui-core-protocol.c android/core-ui-protocol.c
-
# The common libraries
#
QEMU_SYSTEM_LDLIBS := -lm
@@ -879,6 +876,8 @@ VL_SOURCES := framebuffer.c \
user-events-qemu.c \
android/cmdline-option.c \
android/looper-qemu.c \
+ android/protocol/ui-commands-qemu.c \
+ android/protocol/core-commands-qemu.c \
android/main.c \
# Add common system libraries
@@ -1059,7 +1058,8 @@ VL_SOURCES := framebuffer.c \
android/display-core.c \
android/framebuffer-core.c \
android/user-events-core.c \
- android/ui-ctl-core.c \
+ android/protocol/ui-commands-proxy.c \
+ android/protocol/core-commands-impl.c \
# Add common system libraries
#
@@ -1217,7 +1217,8 @@ VL_SOURCES := framebuffer.c \
console-ui.c \
iolooper-select.c \
android/framebuffer-ui.c \
- android/ui-ctl-ui.c \
+ android/protocol/ui-commands-impl.c \
+ android/protocol/core-commands-proxy.c \
# Add common system libraries
#
diff --git a/android/console.c b/android/console.c
index 81c2efe..42c3eb6 100644
--- a/android/console.c
+++ b/android/console.c
@@ -50,11 +50,12 @@
#include "user-events.h"
#include "android/keycode-array.h"
#include "android/charmap.h"
-#include "android/core-ui-protocol.h"
#include "android/display-core.h"
#include "android/framebuffer-core.h"
#include "android/user-events-core.h"
-#include "android/ui-ctl-core.h"
+#include "android/protocol/ui-commands-api.h"
+#include "android/protocol/core-commands-impl.h"
+#include "android/protocol/ui-commands-proxy.h"
#if defined(CONFIG_SLIRP)
#include "libslirp.h"
@@ -263,12 +264,12 @@ control_client_destroy( ControlClient client )
}
if (client == ui_core_ctl_client) {
- uicorectl_destroy();
+ coreCmdImpl_destroy();
ui_core_ctl_client = NULL;
}
if (client == core_ui_ctl_client) {
- coreuictl_destroy();
+ uiCmdProxy_destroy();
core_ui_ctl_client = NULL;
}
#endif // CONFIG_STANDALONE_CORE
@@ -2443,7 +2444,7 @@ do_window_scale( ControlClient client, char* args )
}
}
- android_ui_set_window_scale( scale, is_dpi );
+ uicmd_set_window_scale( scale, is_dpi );
return 0;
}
@@ -2624,7 +2625,7 @@ do_create_ui_core_ctl_service( ControlClient client, char* args )
return -1;
}
- if (!uicorectl_create(client->sock)) {
+ if (!coreCmdImpl_create(client->sock)) {
char reply_buf[4096];
ui_core_ctl_client = client;
snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
@@ -2646,6 +2647,14 @@ destroy_ui_core_ctl_client(void)
}
}
+void
+destroy_corecmd_client(void)
+{
+ if (ui_core_ctl_client != NULL) {
+ control_client_destroy(ui_core_ctl_client);
+ }
+}
+
static int
do_create_core_ui_ctl_service( ControlClient client, char* args )
{
@@ -2656,7 +2665,7 @@ do_create_core_ui_ctl_service( ControlClient client, char* args )
return -1;
}
- if (!coreuictl_create(client->sock)) {
+ if (!uiCmdProxy_create(client->sock)) {
char reply_buf[4096];
core_ui_ctl_client = client;
snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
@@ -2677,6 +2686,15 @@ destroy_core_ui_ctl_client(void)
control_client_destroy(core_ui_ctl_client);
}
}
+
+void
+destroy_uicmd_client(void)
+{
+ if (core_ui_ctl_client != NULL) {
+ control_client_destroy(core_ui_ctl_client);
+ }
+}
+
#endif // CONFIG_STANDALONE_CORE
static const CommandDefRec qemu_commands[] =
diff --git a/android/core-connection.c b/android/core-connection.c
index 93a3efe..1099291 100644
--- a/android/core-connection.c
+++ b/android/core-connection.c
@@ -281,10 +281,15 @@ core_connection_switch_stream(CoreConnection* desc,
syncsocket_read_line_absolute(desc->ssocket, buf, sizeof(buf), deadline);
_zero_terminate(buf, sizeof(buf), handshake_len);
// Replace terminating "\r\n" with 0
- if (handshake_len >= 2 && buf[handshake_len - 2] == '\r') {
- buf[handshake_len - 2] = '\0';
+ if (handshake_len >= 1) {
+ if (buf[handshake_len - 1] == '\r' || buf[handshake_len - 1] == '\n') {
+ buf[handshake_len - 1] = '\0';
+ if (handshake_len >= 2 && (buf[handshake_len - 2] == '\r' ||
+ buf[handshake_len - 2] == '\n')) {
+ buf[handshake_len - 2] = '\0';
+ }
+ }
}
- printf("Handshake: %s\n", buf);
// Lets see what kind of response we've got here.
if (_is_reply_ok(buf, handshake_len)) {
*handshake = strdup(buf + 3);
@@ -316,6 +321,35 @@ core_connection_switch_stream(CoreConnection* desc,
}
}
+CoreConnection*
+core_connection_create_and_switch(SockAddress* console_socket,
+ const char* stream_name,
+ char** handshake)
+{
+ char switch_cmd[256];
+ CoreConnection* connection = NULL;
+
+ // Connect to the console service.
+ connection = core_connection_create(console_socket);
+ if (connection == NULL) {
+ return NULL;
+ }
+ if (core_connection_open(connection)) {
+ core_connection_free(connection);
+ return NULL;
+ }
+
+ // Perform the switch.
+ snprintf(switch_cmd, sizeof(switch_cmd), "%s", stream_name);
+ if (core_connection_switch_stream(connection, switch_cmd, handshake)) {
+ core_connection_close(connection);
+ core_connection_free(connection);
+ return NULL;
+ }
+
+ return connection;
+}
+
void
core_connection_detach(CoreConnection* desc)
{
diff --git a/android/core-connection.h b/android/core-connection.h
index 19e91a1..5701f8c 100644
--- a/android/core-connection.h
+++ b/android/core-connection.h
@@ -29,8 +29,8 @@ typedef struct CoreConnection CoreConnection;
// Maximum number of core porocesses running simultaneously on a machine.
#define MAX_CORE_PROCS 16
-// Socket timeout in millisec (set to half a second)
-#define CORE_PORT_TIMEOUT_MS 500
+// Socket timeout in millisec (set to 5 seconds)
+#define CORE_PORT_TIMEOUT_MS 5000
/* Opens core console socket.
* Param:
@@ -122,6 +122,20 @@ int core_connection_switch_stream(CoreConnection* desc,
const char* stream_name,
char** handshake);
+/* Creates a console client, and switches it to a given stream.
+ * console_socket Socket address for the console.
+ * stream_name Name of the stream to switch to.
+ * handshake Address of a string to allocate for a handshake message on
+ * success, or an error message on failure. If upon return from this
+ * routine that string is not NULL, its buffer must be freed with 'free'.
+ * Return:
+ * Allocated and initialized descriptor for the switched client on success, or
+ * NULL on failure.
+ */
+CoreConnection* core_connection_create_and_switch(SockAddress* console_socket,
+ const char* stream_name,
+ char** handshake);
+
/* Detaches opened console client from the console.
* By console protocol, writing "\r\n" string to the console will destroy the
* console client.
@@ -138,4 +152,18 @@ void core_connection_detach(CoreConnection* desc);
*/
int core_connection_get_socket(CoreConnection* desc);
+/* Calculates timeout for transferring the given number of bytes via core
+ * connection.
+ * Return:
+ * Number of milliseconds during which the entire number of bytes is expected
+ * to be transferred via core connection.
+ */
+static inline int
+core_connection_get_timeout(size_t data_size)
+{
+ // Min 2 seconds + 10 millisec for each transferring byte.
+ // TODO: Come up with a better arithmetics here.
+ return 2000 + data_size * 10;
+}
+
#endif // QEMU_ANDROID_CORE_CONNECTION_H
diff --git a/android/core-ui-protocol.c b/android/core-ui-protocol.c
deleted file mode 100644
index a85ae7c..0000000
--- a/android/core-ui-protocol.c
+++ /dev/null
@@ -1,41 +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.
-*/
-
-/*
- * This file contains helper routines that are used to establish communication
- * between Core and UI components of the emulator. This is a temporary file
- * where we will collect functional dependencies between Core and UI in the
- * process of separating UI and Core in the emulator build.
- */
-
-#include "android/globals.h"
-#include "android/android.h"
-#include "android/core-ui-protocol.h"
-#if defined(CONFIG_STANDALONE_CORE)
-#include "android/ui-ctl-core.h"
-#endif // defined(CONFIG_STANDALONE_CORE)
-
-#if !defined(CONFIG_STANDALONE_CORE)
-/* in android/qemulator.c */
-extern void android_emulator_set_window_scale( double, int );
-#endif
-
-void
-android_ui_set_window_scale(double scale, int is_dpi)
-{
-#if !defined(CONFIG_STANDALONE_CORE)
- android_emulator_set_window_scale(scale, is_dpi);
-#else
- coreuictl_set_window_scale(scale, is_dpi);
-#endif
-}
-
diff --git a/android/core-ui-protocol.h b/android/core-ui-protocol.h
deleted file mode 100644
index 5fc2372..0000000
--- a/android/core-ui-protocol.h
+++ /dev/null
@@ -1,27 +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.
-*/
-
-/*
- * This file contains declarations of helper routines that are used to
- * establish communication between Core and UI components of the emulator.
- * This is a temporary file where we will collect functional dependencies
- * between Core and UI in the process of separating UI and Core in the
- * emulator build.
- */
-
-#ifndef QEMU_ANDROID_CORE_UI_PROTOCOL_H
-#define QEMU_ANDROID_CORE_UI_PROTOCOL_H
-
-/* Changes the scale of the emulator window at runtime. */
-void android_ui_set_window_scale(double scale, int is_dpi);
-
-#endif // QEMU_ANDROID_CORE_UI_PROTOCOL_H
diff --git a/android/help.c b/android/help.c
index efdcd06..7df6704 100644
--- a/android/help.c
+++ b/android/help.c
@@ -10,7 +10,7 @@
#include "audio/audio.h"
#include <string.h>
#include <stdlib.h>
-#include "android/ui-core-protocol.h"
+#include "android/protocol/core-commands-api.h"
/* XXX: TODO: put most of the help stuff in auto-generated files */
@@ -778,7 +778,7 @@ help_shaper(stralloc_t* out)
" the format of -netspeed is one of the following (numbers are kbits/s):\n\n" );
- for (n = 0; !android_core_get_android_netspeed(n, &android_netspeed); n++) {
+ for (n = 0; !corecmd_get_netspeed(n, &android_netspeed); n++) {
PRINTF( " -netspeed %-12s %-15s (up: %.1f, down: %.1f)\n",
android_netspeed->name,
android_netspeed->display,
@@ -791,7 +791,7 @@ help_shaper(stralloc_t* out)
PRINTF( " -netspeed %-12s %s", "<up>:<down>", "select individual up and down speed\n");
PRINTF( "\n The format of -netdelay is one of the following (numbers are msec):\n\n" );
- for (n = 0; !android_core_get_android_netdelay(n, &android_netdelay); n++) {
+ for (n = 0; !corecmd_get_netdelay(n, &android_netdelay); n++) {
PRINTF( " -netdelay %-10s %-15s (min %d, max %d)\n",
android_netdelay->name, android_netdelay->display,
android_netdelay->min_ms, android_netdelay->max_ms );
diff --git a/android/main-ui.c b/android/main-ui.c
index d150be5..9ab87de 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -61,7 +61,8 @@
#include "android/snapshot.h"
#include "android/core-connection.h"
#include "android/framebuffer-ui.h"
-#include "android/ui-ctl-ui.h"
+#include "android/protocol/core-commands-proxy.h"
+#include "android/protocol/ui-commands-impl.h"
#include "framebuffer.h"
#include "iolooper.h"
@@ -760,8 +761,8 @@ _adjustPartitionSize( const char* description,
// Maximum number of core porocesses running simultaneously on a machine.
#define MAX_CORE_PROCS 16
-// Socket timeout in millisec (set to half a second)
-#define CORE_PORT_TIMEOUT_MS 500
+// Socket timeout in millisec (set to 5 seconds)
+#define CORE_PORT_TIMEOUT_MS 5000
#include "android/async-console.h"
@@ -976,7 +977,10 @@ attach_to_core(AndroidOptions* opts) {
// implementation there are two UI control services: "ui-core-control" that
// handle UI controls initiated in the UI, and "core-ui-control" that handle
// UI controls initiated in the core.
- if (clientuictl_create(&console_socket)) {
+ if (coreCmdProxy_create(&console_socket)) {
+ return -1;
+ }
+ if (uiCmdImpl_create(&console_socket)) {
return -1;
}
diff --git a/android/protocol/core-commands-api.h b/android/protocol/core-commands-api.h
new file mode 100644
index 0000000..93a569c
--- /dev/null
+++ b/android/protocol/core-commands-api.h
@@ -0,0 +1,95 @@
+/* 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_CORE_COMMANDS_API_H
+#define _ANDROID_PROTOCOL_CORE_COMMANDS_API_H
+
+/*
+ * Contains the API for calling into the Core with UI control commands.
+ */
+
+#include "android/android.h"
+#include "android/hw-sensors.h"
+
+/* Instructs the Core to change the coarse orientation.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_set_coarse_orientation(AndroidCoarseOrientation orient);
+
+/* Toggles the network in the Core.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_toggle_network();
+
+/* Starts or stops tracing in the Core.
+ * Param:
+ * start - Starts (> 0), or stops (== 0) tracing.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_trace_control(int start);
+
+/* Checks if network is disabled in the Core.
+ * Return:
+ * 0 if network is enabled, 1 if it is disabled, or < 0 on failure.
+ */
+extern int corecmd_is_network_disabled();
+
+/* Requests a NetworkSpeed instance from the Core.
+ * Param:
+ * index - Index of an entry in the NetworkSpeed array.
+ * netspeed - Upon success contains allocated and initialized NetworkSpeed
+ * instance for the given index. Note that strings addressed by "name" and
+ * "display" fileds in the returned NetworkSpeed instance are containd
+ * inside the buffer allocated for the returned NetworkSpeed instance.
+ * Caller of this routine must eventually free the buffer returned in this
+ * parameter.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_get_netspeed(int index, NetworkSpeed** netspeed);
+
+/* Requests a NetworkLatency instance from the Core.
+ * Param:
+ * index - Index of an entry in the NetworkLatency array.
+ * netdelay - Upon success contains allocated and initialized NetworkLatency
+ * instance for the given index. Note that strings addressed by "name" and
+ * "display" fileds in the returned NetworkLatency instance are containd
+ * inside the buffer allocated for the returned NetworkLatency instance.
+ * Caller of this routine must eventually free the buffer returned in this
+ * parameter.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_get_netdelay(int index, NetworkLatency** netdelay);
+
+/* Requests a QEMU file path from the Core.
+ * Param:
+ * type, filename - Request parameters that define the file for which path is
+ * requested.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int corecmd_get_qemu_path(int type,
+ const char* filename,
+ char* path,
+ size_t path_buf_size);
+
+/* Gets LCD density property from the core properties.
+ * Return:
+ * LCD density on success, or < 0 on failure.
+ */
+extern int corecmd_get_hw_lcd_density(void);
+
+#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_API_H */
diff --git a/android/protocol/core-commands-impl.c b/android/protocol/core-commands-impl.c
new file mode 100644
index 0000000..7fa2a0b
--- /dev/null
+++ b/android/protocol/core-commands-impl.c
@@ -0,0 +1,440 @@
+/* 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 "ui-core-control" service that is
+ * part of the UI control protocol. Here we handle UI control commands sent by
+ * the UI to the Core.
+ */
+
+#include "android/android.h"
+#include "android/globals.h"
+#include "telephony/modem_driver.h"
+#include "trace.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"
+
+/* Enumerates state values for the command reader in the CoreCmdImpl descriptor.
+ */
+typedef enum CoreCmdImplState {
+ /* The reader is waiting on command header. */
+ EXPECTS_HEADER,
+
+ /* The reader is waiting on command parameters. */
+ EXPECTS_PARAMETERS,
+} CoreCmdImplState;
+
+/* Descriptor for the Core-side implementation of the "ui-core-control" service.
+ */
+typedef struct CoreCmdImpl {
+ /* 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;
+
+ /* Writer to send responses to the UI commands. */
+ SyncSocket* sync_writer;
+
+ /* Socket descriptor for this service. */
+ int sock;
+
+ /* Command reader state. */
+ CoreCmdImplState cmd_state;
+
+ /* Incoming command header. */
+ UICmdHeader cmd_header;
+
+ /* A small preallocated buffer for command parameters. */
+ uint8_t cmd_param[256];
+
+ /* Buffer to use for reading command parameters. Depending on expected size
+ * of the parameters this buffer can point to cmd_param field of this
+ * structure (for small commands), or can be allocated for large commands. */
+ void* cmd_param_buf;
+} CoreCmdImpl;
+
+/* One and only one CoreCmdImpl instance. */
+static CoreCmdImpl _coreCmdImpl;
+
+/* Implemented in android/console.c */
+extern void destroy_corecmd_client(void);
+/* Implemented in vl-android.c */
+extern char* qemu_find_file(int type, const char* filename);
+
+/* Properly initializes cmd_param_buf field in CoreCmdImpl instance to receive
+ * the expected command parameters.
+ */
+static uint8_t*
+_alloc_cmd_param_buf(CoreCmdImpl* corecmd, uint32_t size)
+{
+ if (size < sizeof(corecmd->cmd_param)) {
+ // cmd_param can contain all request data.
+ corecmd->cmd_param_buf = &corecmd->cmd_param[0];
+ } else {
+ // Expected request us too large to fit into preallocated buffer.
+ corecmd->cmd_param_buf = qemu_malloc(size);
+ }
+ return corecmd->cmd_param_buf;
+}
+
+/* Properly frees cmd_param_buf field in CoreCmdImpl instance.
+ */
+static void
+_free_cmd_param_buf(CoreCmdImpl* corecmd)
+{
+ if (corecmd->cmd_param_buf != &corecmd->cmd_param[0]) {
+ qemu_free(corecmd->cmd_param_buf);
+ corecmd->cmd_param_buf = &corecmd->cmd_param[0];
+ }
+}
+
+/* Calculates timeout for transferring the given number of bytes via socket.
+ * Return:
+ * Number of milliseconds during which the entire number of bytes is expected
+ * to be transferred via socket for this service.
+ */
+static int
+_coreCmdImpl_get_timeout(size_t data_size)
+{
+ // Min 2 seconds + 10 millisec for each transferring byte.
+ // TODO: Come up with a better arithmetics here.
+ return 2000 + data_size * 10;
+}
+
+/* Sends command response back to the UI.
+ * Param:
+ * corecmd - CoreCmdImpl instance to use to send the response.
+ * resp - Response header.
+ * resp_data - Response data. Data size is defined by the header.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+static int
+_coreCmdImpl_respond(CoreCmdImpl* corecmd, UICmdRespHeader* resp, void* resp_data)
+{
+ int status = syncsocket_start_write(corecmd->sync_writer);
+ if (!status) {
+ // Write the header
+ status = syncsocket_write(corecmd->sync_writer, resp,
+ sizeof(UICmdRespHeader),
+ _coreCmdImpl_get_timeout(sizeof(UICmdRespHeader)));
+ // Write response data (if any).
+ if (status > 0 && resp_data != NULL && resp->resp_data_size != 0) {
+ status = syncsocket_write(corecmd->sync_writer, resp_data,
+ resp->resp_data_size,
+ _coreCmdImpl_get_timeout(resp->resp_data_size));
+ }
+ status = syncsocket_result(status);
+ syncsocket_stop_write(corecmd->sync_writer);
+ }
+ if (status < 0) {
+ derror("Core is unable to respond with %u bytes to the UI control command: %s\n",
+ resp->resp_data_size, errno_str);
+ }
+ return status;
+}
+
+/* Handles UI control command received from the UI.
+ * Param:
+ * corecmd - CoreCmdImpl instance that received the command.
+ * cmd_header - Command header.
+ * cmd_param - Command data.
+ */
+static void
+_coreCmdImpl_handle_command(CoreCmdImpl* corecmd,
+ const UICmdHeader* cmd_header,
+ const uint8_t* cmd_param)
+{
+ switch (cmd_header->cmd_type) {
+ case AUICMD_SET_COARSE_ORIENTATION:
+ {
+ UICmdSetCoarseOrientation* cmd =
+ (UICmdSetCoarseOrientation*)cmd_param;
+ android_sensors_set_coarse_orientation(cmd->orient);
+ break;
+ }
+
+ case AUICMD_TOGGLE_NETWORK:
+ qemu_net_disable = !qemu_net_disable;
+ if (android_modem) {
+ amodem_set_data_registration(
+ android_modem,
+ qemu_net_disable ? A_REGISTRATION_UNREGISTERED
+ : A_REGISTRATION_HOME);
+ }
+ break;
+
+ case AUICMD_TRACE_CONTROL:
+ {
+ UICmdTraceControl* cmd = (UICmdTraceControl*)cmd_param;
+ if (cmd->start) {
+ start_tracing();
+ } else {
+ stop_tracing();
+ }
+ break;
+ }
+
+ case AUICMD_CHK_NETWORK_DISABLED:
+ {
+ UICmdRespHeader resp;
+ resp.resp_data_size = 0;
+ resp.result = qemu_net_disable;
+ _coreCmdImpl_respond(corecmd, &resp, NULL);
+ break;
+ }
+
+ case AUICMD_GET_NETSPEED:
+ {
+ UICmdRespHeader resp;
+ UICmdGetNetSpeedResp* resp_data = NULL;
+ UICmdGetNetSpeed* cmd = (UICmdGetNetSpeed*)cmd_param;
+
+ resp.resp_data_size = 0;
+ resp.result = 0;
+
+ if (cmd->index >= android_netspeeds_count ||
+ android_netspeeds[cmd->index].name == NULL) {
+ resp.result = -1;
+ } else {
+ const NetworkSpeed* netspeed = &android_netspeeds[cmd->index];
+ // Calculate size of the response data:
+ // fixed header + zero-terminated netspeed name.
+ resp.resp_data_size = sizeof(UICmdGetNetSpeedResp) +
+ strlen(netspeed->name) + 1;
+ // Count in zero-terminated netspeed display.
+ if (netspeed->display != NULL) {
+ resp.resp_data_size += strlen(netspeed->display) + 1;
+ } else {
+ resp.resp_data_size++;
+ }
+ // Allocate and initialize response data buffer.
+ resp_data =
+ (UICmdGetNetSpeedResp*)qemu_malloc(resp.resp_data_size);
+ resp_data->upload = netspeed->upload;
+ resp_data->download = netspeed->download;
+ strcpy(resp_data->name, netspeed->name);
+ if (netspeed->display != NULL) {
+ strcpy(resp_data->name + strlen(resp_data->name) + 1,
+ netspeed->display);
+ } else {
+ strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
+ }
+ }
+ _coreCmdImpl_respond(corecmd, &resp, resp_data);
+ if (resp_data != NULL) {
+ qemu_free(resp_data);
+ }
+ break;
+ }
+
+ case AUICMD_GET_NETDELAY:
+ {
+ UICmdRespHeader resp;
+ UICmdGetNetDelayResp* resp_data = NULL;
+ UICmdGetNetDelay* cmd = (UICmdGetNetDelay*)cmd_param;
+
+ resp.resp_data_size = 0;
+ resp.result = 0;
+
+ if (cmd->index >= android_netdelays_count ||
+ android_netdelays[cmd->index].name == NULL) {
+ resp.result = -1;
+ } else {
+ const NetworkLatency* netdelay = &android_netdelays[cmd->index];
+ // Calculate size of the response data:
+ // fixed header + zero-terminated netdelay name.
+ resp.resp_data_size = sizeof(UICmdGetNetDelayResp) +
+ strlen(netdelay->name) + 1;
+ // Count in zero-terminated netdelay display.
+ if (netdelay->display != NULL) {
+ resp.resp_data_size += strlen(netdelay->display) + 1;
+ } else {
+ resp.resp_data_size++;
+ }
+ // Allocate and initialize response data buffer.
+ resp_data =
+ (UICmdGetNetDelayResp*)qemu_malloc(resp.resp_data_size);
+ resp_data->min_ms = netdelay->min_ms;
+ resp_data->max_ms = netdelay->max_ms;
+ strcpy(resp_data->name, netdelay->name);
+ if (netdelay->display != NULL) {
+ strcpy(resp_data->name + strlen(resp_data->name) + 1,
+ netdelay->display);
+ } else {
+ strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
+ }
+ }
+ _coreCmdImpl_respond(corecmd, &resp, resp_data);
+ if (resp_data != NULL) {
+ qemu_free(resp_data);
+ }
+ break;
+ }
+
+ case AUICMD_GET_QEMU_PATH:
+ {
+ UICmdRespHeader resp;
+ UICmdGetQemuPath* cmd = (UICmdGetQemuPath*)cmd_param;
+ char* filepath = NULL;
+
+ resp.resp_data_size = 0;
+ resp.result = -1;
+ filepath = qemu_find_file(cmd->type, cmd->filename);
+ if (filepath != NULL) {
+ resp.resp_data_size = strlen(filepath) + 1;
+ }
+ _coreCmdImpl_respond(corecmd, &resp, filepath);
+ if (filepath != NULL) {
+ qemu_free(filepath);
+ }
+ break;
+ }
+
+ case AUICMD_GET_LCD_DENSITY:
+ {
+ UICmdRespHeader resp;
+ resp.resp_data_size = 0;
+ resp.result = android_hw->hw_lcd_density;
+ _coreCmdImpl_respond(corecmd, &resp, NULL);
+ break;
+ }
+
+ default:
+ derror("Unknown UI control command %d is received by the Core.\n",
+ cmd_header->cmd_type);
+ break;
+ }
+}
+
+/* Asynchronous I/O callback reading UI control commands.
+ * Param:
+ * opaque - CoreCmdImpl instance.
+ * events - Lists I/O event (read or write) this callback is called for.
+ */
+static void
+_coreCmdImpl_io_func(void* opaque, int fd, unsigned events)
+{
+ AsyncStatus status;
+ CoreCmdImpl* corecmd;
+
+ 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 _coreCmdImpl_io_func\n");
+ return;
+ }
+
+ corecmd = (CoreCmdImpl*)opaque;
+
+ // Read whatever is expected from the socket.
+ status = asyncReader_read(&corecmd->async_reader, &corecmd->io);
+ switch (status) {
+ case ASYNC_COMPLETE:
+ switch (corecmd->cmd_state) {
+ case EXPECTS_HEADER:
+ // We just read the command header. Now we expect the param.
+ if (corecmd->cmd_header.cmd_param_size != 0) {
+ corecmd->cmd_state = EXPECTS_PARAMETERS;
+ // Setup the reader to read expected amount of data.
+ _alloc_cmd_param_buf(corecmd,
+ corecmd->cmd_header.cmd_param_size);
+ asyncReader_init(&corecmd->async_reader,
+ corecmd->cmd_param_buf,
+ corecmd->cmd_header.cmd_param_size,
+ &corecmd->io);
+ } else {
+ // Command doesn't have param. Go ahead and handle it.
+ _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
+ NULL);
+ // Prepare for the next header.
+ corecmd->cmd_state = EXPECTS_HEADER;
+ asyncReader_init(&corecmd->async_reader,
+ &corecmd->cmd_header,
+ sizeof(corecmd->cmd_header),
+ &corecmd->io);
+ }
+ break;
+
+ case EXPECTS_PARAMETERS:
+ // Entore command is received. Handle it.
+ _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
+ corecmd->cmd_param_buf);
+ _free_cmd_param_buf(corecmd);
+ // Prepare for the next command.
+ corecmd->cmd_state = EXPECTS_HEADER;
+ asyncReader_init(&corecmd->async_reader, &corecmd->cmd_header,
+ sizeof(corecmd->cmd_header), &corecmd->io);
+ break;
+ }
+ break;
+
+ case ASYNC_ERROR:
+ loopIo_dontWantRead(&corecmd->io);
+ if (errno == ECONNRESET) {
+ // UI has exited. We need to destroy the service.
+ destroy_corecmd_client();
+ }
+ break;
+
+ case ASYNC_NEED_MORE:
+ // Transfer will eventually come back into this routine.
+ return;
+ }
+}
+
+int
+coreCmdImpl_create(int fd)
+{
+ _coreCmdImpl.sock = fd;
+ _coreCmdImpl.looper = looper_newCore();
+ loopIo_init(&_coreCmdImpl.io, _coreCmdImpl.looper, _coreCmdImpl.sock,
+ _coreCmdImpl_io_func, &_coreCmdImpl);
+ _coreCmdImpl.cmd_state = EXPECTS_HEADER;
+ _coreCmdImpl.cmd_param_buf = &_coreCmdImpl.cmd_param[0];
+ asyncReader_init(&_coreCmdImpl.async_reader, &_coreCmdImpl.cmd_header,
+ sizeof(_coreCmdImpl.cmd_header), &_coreCmdImpl.io);
+ _coreCmdImpl.sync_writer = syncsocket_init(fd);
+ if (_coreCmdImpl.sync_writer == NULL) {
+ derror("Unable to create writer for CoreCmdImpl instance: %s\n",
+ errno_str);
+ coreCmdImpl_destroy();
+ return -1;
+ }
+ return 0;
+}
+
+void
+coreCmdImpl_destroy()
+{
+ // Destroy the writer
+ if (_coreCmdImpl.sync_writer != NULL) {
+ syncsocket_close(_coreCmdImpl.sync_writer);
+ syncsocket_free(_coreCmdImpl.sync_writer);
+ }
+ if (_coreCmdImpl.looper != NULL) {
+ // Stop all I/O that may still be going on.
+ loopIo_done(&_coreCmdImpl.io);
+ looper_free(_coreCmdImpl.looper);
+ _coreCmdImpl.looper = NULL;
+ }
+ // Free allocated memory.
+ _free_cmd_param_buf(&_coreCmdImpl);
+}
diff --git a/android/protocol/core-commands-impl.h b/android/protocol/core-commands-impl.h
new file mode 100644
index 0000000..8690613
--- /dev/null
+++ b/android/protocol/core-commands-impl.h
@@ -0,0 +1,34 @@
+/* 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_CORE_COMMANDS_IMPL_H
+#define _ANDROID_PROTOCOL_CORE_COMMANDS_IMPL_H
+
+/*
+ * Contains the Core-side implementation of the "ui-core-control" service that is
+ * part of the UI control protocol. Here we handle UI control commands sent by
+ * the UI to the Core.
+ */
+
+/* Creates and initializes descriptor for the Core-side of the "ui-core-control"
+ * 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 coreCmdImpl_create(int fd);
+
+/* Destroys the descriptor for the Core-side of the "ui-core-control" service. */
+extern void coreCmdImpl_destroy();
+
+#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_IMPL_H */
diff --git a/android/protocol/core-commands-proxy.c b/android/protocol/core-commands-proxy.c
new file mode 100644
index 0000000..6bd3d4e
--- /dev/null
+++ b/android/protocol/core-commands-proxy.c
@@ -0,0 +1,374 @@
+/* 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 "ui-core-control" service that is
+ * part of the UI control protocol. Here we send UI control commands to the Core.
+ */
+
+#include "console.h"
+#include "android/looper.h"
+#include "android/core-connection.h"
+#include "android/async-utils.h"
+#include "android/sync-utils.h"
+#include "android/utils/debug.h"
+#include "android/utils/panic.h"
+#include "android/protocol/core-commands.h"
+#include "android/protocol/core-commands-proxy.h"
+#include "android/protocol/core-commands-api.h"
+
+/* Descriptor for the UI-side "ui-core-control" service. */
+typedef struct CoreCmdProxy {
+ /* Core connection established for this service. */
+ CoreConnection* core_connection;
+
+ /* Socket descriptor for the UI service. */
+ int sock;
+
+ /* Socket wrapper for sync srites. */
+ SyncSocket* sync_writer;
+
+ /* Socket wrapper for sync reads. */
+ SyncSocket* sync_reader;
+} CoreCmdProxy;
+
+/* One and only one CoreCmdProxy instance. */
+static CoreCmdProxy _coreCmdProxy = { 0 };
+
+/* Sends UI command to the core.
+ * Param:
+ * cmd_type, cmd_param, cmd_param_size - Define the command.
+ * Return:
+ * 0 On success, or < 0 on failure.
+ */
+static int
+_coreCmdProxy_send_command(uint8_t cmd_type,
+ void* cmd_param,
+ uint32_t cmd_param_size)
+{
+ int status;
+ UICmdHeader header;
+
+ // Prepare the command header.
+ header.cmd_type = cmd_type;
+ header.cmd_param_size = cmd_param_size;
+ status = syncsocket_start_write(_coreCmdProxy.sync_writer);
+ if (!status) {
+ // Send the header.
+ status = syncsocket_write(_coreCmdProxy.sync_writer, &header,
+ sizeof(header),
+ core_connection_get_timeout(sizeof(header)));
+ // If there is request data, send it too.
+ if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
+ status = syncsocket_write(_coreCmdProxy.sync_writer, cmd_param,
+ cmd_param_size,
+ core_connection_get_timeout(cmd_param_size));
+ }
+ status = syncsocket_result(status);
+ syncsocket_stop_write(_coreCmdProxy.sync_writer);
+ }
+ if (status < 0) {
+ derror("Unable to send UI control command %d (size %u): %s\n",
+ cmd_type, cmd_param_size, errno_str);
+ }
+ return status;
+}
+
+/* Reads UI control command response from the core.
+ * Param:
+ * resp - Upon success contains command response header.
+ * resp_data - Upon success contains allocated reponse data (if any). The caller
+ * is responsible for deallocating the memory returned here.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+static int
+_coreCmdProxy_get_response(UICmdRespHeader* resp, void** resp_data)
+{
+ int status = syncsocket_start_read(_coreCmdProxy.sync_reader);
+ if (!status) {
+ // Read the header.
+ status = syncsocket_read(_coreCmdProxy.sync_reader, resp,
+ sizeof(UICmdRespHeader),
+ core_connection_get_timeout(sizeof(UICmdRespHeader)));
+ // Read response data (if any).
+ if (status > 0 && resp->resp_data_size) {
+ *resp_data = malloc(resp->resp_data_size);
+ if (*resp_data == NULL) {
+ APANIC("_coreCmdProxy_get_response is unable to allocate response data buffer.\n");
+ }
+ status = syncsocket_read(_coreCmdProxy.sync_reader, *resp_data,
+ resp->resp_data_size,
+ core_connection_get_timeout(resp->resp_data_size));
+ }
+ status = syncsocket_result(status);
+ syncsocket_stop_read(_coreCmdProxy.sync_reader);
+ }
+ if (status < 0) {
+ derror("Unable to get UI command response from the Core: %s\n",
+ errno_str);
+ }
+ 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);
+ }
+ if (_coreCmdProxy.sync_reader != NULL) {
+ syncsocket_close(_coreCmdProxy.sync_reader);
+ syncsocket_free(_coreCmdProxy.sync_reader);
+ }
+ 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)
+{
+ UICmdSetCoarseOrientation cmd;
+ cmd.orient = orient;
+ return _coreCmdProxy_send_command(AUICMD_SET_COARSE_ORIENTATION,
+ &cmd, sizeof(cmd));
+}
+
+int
+corecmd_toggle_network()
+{
+ return _coreCmdProxy_send_command(AUICMD_TOGGLE_NETWORK, NULL, 0);
+}
+
+int
+corecmd_trace_control(int start)
+{
+ UICmdTraceControl cmd;
+ cmd.start = start;
+ return _coreCmdProxy_send_command(AUICMD_TRACE_CONTROL,
+ &cmd, sizeof(cmd));
+}
+
+int
+corecmd_is_network_disabled()
+{
+ UICmdRespHeader resp;
+ void* tmp = NULL;
+ int status;
+
+ status = _coreCmdProxy_send_command(AUICMD_CHK_NETWORK_DISABLED, NULL, 0);
+ if (status < 0) {
+ return status;
+ }
+ status = _coreCmdProxy_get_response(&resp, &tmp);
+ if (status < 0) {
+ return status;
+ }
+ return resp.result;
+}
+
+int
+corecmd_get_netspeed(int index, NetworkSpeed** netspeed)
+{
+ UICmdGetNetSpeed req;
+ UICmdRespHeader resp;
+ UICmdGetNetSpeedResp* resp_data = NULL;
+ int status;
+
+ // Initialize and send the query.
+ req.index = index;
+ status = _coreCmdProxy_send_command(AUICMD_GET_NETSPEED, &req, sizeof(req));
+ if (status < 0) {
+ return status;
+ }
+
+ // Obtain the response from the core.
+ status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
+ if (status < 0) {
+ return status;
+ }
+ if (!resp.result) {
+ NetworkSpeed* ret;
+ // Allocate memory for the returning NetworkSpeed instance.
+ // It includes: NetworkSpeed structure +
+ // size of zero-terminated "name" and "display" strings saved in
+ // resp_data.
+ *netspeed = malloc(sizeof(NetworkSpeed) + 1 +
+ resp.resp_data_size - sizeof(UICmdGetNetSpeedResp));
+ ret = *netspeed;
+
+ // Copy data obtained from the core to the returning NetworkSpeed
+ // instance.
+ ret->upload = resp_data->upload;
+ ret->download = resp_data->download;
+ ret->name = (char*)ret + sizeof(NetworkSpeed);
+ strcpy((char*)ret->name, resp_data->name);
+ ret->display = ret->name + strlen(ret->name) + 1;
+ strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
+ }
+ if (resp_data != NULL) {
+ free(resp_data);
+ }
+ return resp.result;
+}
+
+int
+corecmd_get_netdelay(int index, NetworkLatency** netdelay)
+{
+ UICmdGetNetDelay req;
+ UICmdRespHeader resp;
+ UICmdGetNetDelayResp* resp_data = NULL;
+ int status;
+
+ // Initialize and send the query.
+ req.index = index;
+ status = _coreCmdProxy_send_command(AUICMD_GET_NETDELAY, &req, sizeof(req));
+ if (status < 0) {
+ return status;
+ }
+
+ // Obtain the response from the core.
+ status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
+ if (status < 0) {
+ return status;
+ }
+ if (!resp.result) {
+ NetworkLatency* ret;
+ // Allocate memory for the returning NetworkLatency instance.
+ // It includes: NetworkLatency structure +
+ // size of zero-terminated "name" and "display" strings saved in
+ // resp_data.
+ *netdelay = malloc(sizeof(NetworkLatency) + 1 +
+ resp.resp_data_size - sizeof(UICmdGetNetDelayResp));
+ ret = *netdelay;
+
+ // Copy data obtained from the core to the returning NetworkLatency
+ // instance.
+ ret->min_ms = resp_data->min_ms;
+ ret->max_ms = resp_data->max_ms;
+ ret->name = (char*)ret + sizeof(NetworkLatency);
+ strcpy((char*)ret->name, resp_data->name);
+ ret->display = ret->name + strlen(ret->name) + 1;
+ strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
+ }
+ if (resp_data != NULL) {
+ free(resp_data);
+ }
+ return resp.result;
+}
+
+int
+corecmd_get_qemu_path(int type,
+ const char* filename,
+ char* path,
+ size_t path_buf_size)
+{
+ UICmdRespHeader resp;
+ char* resp_data = NULL;
+ int status;
+
+ // Initialize and send the query.
+ uint32_t cmd_data_size = sizeof(UICmdGetQemuPath) + strlen(filename) + 1;
+ UICmdGetQemuPath* req = (UICmdGetQemuPath*)malloc(cmd_data_size);
+ if (req == NULL) {
+ APANIC("corecmd_get_qemu_path is unable to allocate %u bytes\n",
+ cmd_data_size);
+ }
+ req->type = type;
+ strcpy(req->filename, filename);
+ status = _coreCmdProxy_send_command(AUICMD_GET_QEMU_PATH, req,
+ cmd_data_size);
+ if (status < 0) {
+ return status;
+ }
+
+ // Obtain the response from the core.
+ status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
+ if (status < 0) {
+ return status;
+ }
+ if (!resp.result && resp_data != NULL) {
+ strncpy(path, resp_data, path_buf_size);
+ path[path_buf_size - 1] = '\0';
+ }
+ if (resp_data != NULL) {
+ free(resp_data);
+ }
+ return resp.result;
+}
+
+int
+corecmd_get_hw_lcd_density(void)
+{
+ UICmdRespHeader resp;
+ void* tmp = NULL;
+ int status;
+
+ status = _coreCmdProxy_send_command(AUICMD_GET_LCD_DENSITY, NULL, 0);
+ if (status < 0) {
+ return status;
+ }
+ status = _coreCmdProxy_get_response(&resp, &tmp);
+ if (status < 0) {
+ return status;
+ }
+ return resp.result;
+}
+
+int
+coreCmdProxy_create(SockAddress* console_socket)
+{
+ char* handshake = NULL;
+
+ // Connect to the ui-core-control service.
+ _coreCmdProxy.core_connection =
+ core_connection_create_and_switch(console_socket, "ui-core-control",
+ &handshake);
+ if (_coreCmdProxy.core_connection == NULL) {
+ derror("Unable to connect to the ui-core-control service: %s\n",
+ errno_str);
+ return -1;
+ }
+
+ // Initialze command writer and response reader.
+ _coreCmdProxy.sock = core_connection_get_socket(_coreCmdProxy.core_connection);
+ _coreCmdProxy.sync_writer = syncsocket_init(_coreCmdProxy.sock);
+ if (_coreCmdProxy.sync_writer == NULL) {
+ derror("Unable to initialize CoreCmdProxy writer: %s\n", errno_str);
+ _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();
+ return -1;
+ }
+
+
+ fprintf(stdout, "ui-core-control 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;
+}
diff --git a/android/protocol/core-commands-proxy.h b/android/protocol/core-commands-proxy.h
new file mode 100644
index 0000000..8303ed4
--- /dev/null
+++ b/android/protocol/core-commands-proxy.h
@@ -0,0 +1,32 @@
+/* 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_CORE_COMMANDS_PROXY_H
+#define _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H
+
+#include "sockets.h"
+
+/*
+ * Contains the UI-side implementation of the "ui-core-control" service that is
+ * part of the UI control protocol. Here we send UI control commands to the Core.
+ */
+
+/* Creates and initializes descriptor for the UI-side of the "ui-core-control"
+ * 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 coreCmdProxy_create(SockAddress* console_socket);
+
+#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H */
diff --git a/android/protocol/core-commands-qemu.c b/android/protocol/core-commands-qemu.c
new file mode 100644
index 0000000..03fef64
--- /dev/null
+++ b/android/protocol/core-commands-qemu.c
@@ -0,0 +1,108 @@
+/* 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 implementation of the API for calling into the Core with the UI
+ * control commands for standalone (monolithic) emulator.
+ */
+
+#include "android/android.h"
+#include "android/globals.h"
+#include "android/hw-sensors.h"
+#include "telephony/modem_driver.h"
+#include "trace.h"
+#include "audio/audio.h"
+#include "android/protocol/core-commands-api.h"
+
+/* Implemented in vl-android.c */
+extern char* qemu_find_file(int type, const char* filename);
+
+int
+corecmd_set_coarse_orientation(AndroidCoarseOrientation orient)
+{
+ android_sensors_set_coarse_orientation(orient);
+ return 0;
+}
+
+int
+corecmd_toggle_network()
+{
+ qemu_net_disable = !qemu_net_disable;
+ if (android_modem) {
+ amodem_set_data_registration(
+ android_modem,
+ qemu_net_disable ? A_REGISTRATION_UNREGISTERED
+ : A_REGISTRATION_HOME);
+ }
+ return 0;
+}
+
+int corecmd_trace_control(int start)
+{
+ if (start) {
+ start_tracing();
+ } else {
+ stop_tracing();
+ }
+ return 0;
+}
+
+int corecmd_is_network_disabled()
+{
+ return qemu_net_disable;
+}
+
+int
+corecmd_get_netspeed(int index, NetworkSpeed** netspeed)
+{
+ if (index >= android_netspeeds_count ||
+ android_netspeeds[index].name == NULL) {
+ return -1;
+ }
+ *netspeed = (NetworkSpeed*)malloc(sizeof(NetworkSpeed));
+ memcpy(*netspeed, &android_netspeeds[index], sizeof(NetworkSpeed));
+ return 0;
+}
+
+int
+corecmd_get_netdelay(int index, NetworkLatency** netdelay)
+{
+ if (index >= android_netdelays_count ||
+ android_netdelays[index].name == NULL) {
+ return -1;
+ }
+ *netdelay = (NetworkLatency*)malloc(sizeof(NetworkLatency));
+ memcpy(*netdelay, &android_netdelays[index], sizeof(NetworkLatency));
+ return 0;
+}
+
+int
+corecmd_get_qemu_path(int type,
+ const char* filename,
+ char* path,
+ size_t path_buf_size)
+{
+ char* filepath = qemu_find_file(type, filename);
+ if (filepath == NULL) {
+ return -1;
+ }
+ strncpy(path, filepath, path_buf_size);
+ path[path_buf_size - 1] = '\0';
+ qemu_free(filepath);
+ return 0;
+}
+
+int
+corecmd_get_hw_lcd_density(void)
+{
+ return android_hw->hw_lcd_density;
+}
diff --git a/android/protocol/core-commands.h b/android/protocol/core-commands.h
new file mode 100644
index 0000000..3ac0ca5
--- /dev/null
+++ b/android/protocol/core-commands.h
@@ -0,0 +1,104 @@
+/* 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_CORE_COMMANDS_H
+#define _ANDROID_PROTOCOL_CORE_COMMANDS_H
+
+/*
+ * Contains declarations related to the UI control commands sent by the UI and
+ * handled by the Core.
+ */
+
+#include "android/hw-sensors.h"
+#include "android/protocol/ui-common.h"
+
+/* Sets coarse orientation. */
+#define AUICMD_SET_COARSE_ORIENTATION 1
+
+/* Toggles the network. */
+#define AUICMD_TOGGLE_NETWORK 2
+
+/* Starts / stops the tracing. */
+#define AUICMD_TRACE_CONTROL 3
+
+/* Checks if network is disabled. */
+#define AUICMD_CHK_NETWORK_DISABLED 4
+
+/* Gets network speed. */
+#define AUICMD_GET_NETSPEED 5
+
+/* Gets network delays */
+#define AUICMD_GET_NETDELAY 6
+
+/* Gets path to a QEMU file on local host. */
+#define AUICMD_GET_QEMU_PATH 7
+
+/* Gets LCD density. */
+#define AUICMD_GET_LCD_DENSITY 8
+
+/* Formats AUICMD_SET_COARSE_ORIENTATION UI control command parameters. */
+typedef struct UICmdSetCoarseOrientation {
+ AndroidCoarseOrientation orient;
+} UICmdSetCoarseOrientation;
+
+/* Formats AUICMD_TRACE_CONTROL UI control command parameters. */
+typedef struct UICmdTraceControl {
+ int start;
+} UICmdTraceControl;
+
+/* Formats AUICMD_GET_NETSPEED UI control command parameters. */
+typedef struct UICmdGetNetSpeed {
+ int index;
+} UICmdGetNetSpeed;
+
+/* Formats AUICMD_GET_NETSPEED UI control command response.
+ * Instances of this structure contains content of the NetworkSpeed structure,
+ * including actual "name" and "display" strings. */
+typedef struct UICmdGetNetSpeedResp {
+ int upload;
+ int download;
+ /* Zero-terminated NetworkSpeed's "name" strings starts here. The "display"
+ * string begins inside this structure, right after the "name"'s
+ * zero-terminator. */
+ char name[0];
+} UICmdGetNetSpeedResp;
+
+/* Formats AUICMD_GET_NETDELAY UI control command parameters. */
+typedef struct UICmdGetNetDelay {
+ int index;
+} UICmdGetNetDelay;
+
+/* Formats AUICMD_GET_NETDELAY UI control command response.
+ * Instances of this structure contains content of the NetworkLatency structure,
+ * including actual "name" and "display" strings. */
+typedef struct UICmdGetNetDelayResp {
+ int min_ms;
+ int max_ms;
+ /* Zero-terminated NetworkLatency's "name" strings starts here. The "display"
+ * string begins inside this structure, right after the "name"'s
+ * zero-terminator. */
+ char name[0];
+} UICmdGetNetDelayResp;
+
+/* Formats AUICMD_GET_QEMU_PATH UI control command parameters. */
+typedef struct UICmdGetQemuPath {
+ int type;
+ char filename[0];
+} UICmdGetQemuPath;
+
+/* Formats AUICMD_GET_QEMU_PATH UI control command response. */
+typedef struct UICmdGetQemuPathResp {
+ /* Queried qemu path begins here. */
+ char path[0];
+} UICmdGetQemuPathResp;
+
+#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_H */
diff --git a/android/protocol/ui-commands-api.h b/android/protocol/ui-commands-api.h
new file mode 100644
index 0000000..d9fe6b0
--- /dev/null
+++ b/android/protocol/ui-commands-api.h
@@ -0,0 +1,41 @@
+/* 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_UI_COMMANDS_API_H
+#define _ANDROID_PROTOCOL_UI_COMMANDS_API_H
+
+/*
+ * Contains the API for calling into the UI with the Core control commands.
+ */
+
+/* Changes the scale of the emulator window at runtime.
+ * Param:
+ * scale, is_dpi - New window scale parameters
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int uicmd_set_window_scale(double scale, int is_dpi);
+
+/* This is temporary redeclaration for AndroidHwLightBrightnessFunc declared
+ * in android/hw-control.h We redeclare it here in order to keep type
+ * consistency between android_core_set_brightness_change_callback and
+ * light_brightness field of AndroidHwControlFuncs structure.
+ */
+typedef void (*AndroidHwLightBrightnessCallback)(void* opaque,
+ const char* light,
+ int brightness);
+
+/* Registers a UI callback to be called when brightness is changed by the core. */
+extern int uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
+ void* opaque);
+
+#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_API_H */
diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c
new file mode 100644
index 0000000..456c61e
--- /dev/null
+++ b/android/protocol/ui-commands-impl.c
@@ -0,0 +1,257 @@
+/* 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 "console.h"
+//#include "android/hw-control.h"
+#include "android/looper.h"
+#include "android/core-connection.h"
+#include "android/async-utils.h"
+#include "android/sync-utils.h"
+#include "android/utils/system.h"
+#include "android/utils/debug.h"
+#include "android/utils/panic.h"
+#include "android/protocol/ui-commands-impl.h"
+#include "android/protocol/ui-commands-api.h"
+
+/* Enumerates states for the command reader in UICmdImpl instance. */
+typedef enum UICmdImplState {
+ /* The reader is waiting on command header. */
+ EXPECTS_HEADER,
+
+ /* The reader is waiting on command parameters. */
+ EXPECTS_PARAMETERS,
+} UICmdImplState;
+
+/* Descriptor for the UI-side of the "core-ui-control" service. */
+typedef struct UICmdImpl {
+ /* Core connection established for this service. */
+ CoreConnection* core_connection;
+
+ /* Socket descriptor for the UI service. */
+ int sock;
+
+ /* Command reader state. */
+ UICmdImplState reader_state;
+
+ /* Incoming command header. */
+ UICmdHeader cmd_header;
+
+ /* Reader's buffer. This field can point to the cmd_header field of this
+ * structure (when we expect a command header), or to a buffer allocated for
+ * the (when we expect command parameters). */
+ uint8_t* reader_buffer;
+
+ /* Offset in the reader's buffer where to read next chunk of data. */
+ size_t reader_offset;
+
+ /* Total number of bytes the reader expects to read. */
+ size_t reader_bytes;
+} UICmdImpl;
+
+/* Implemented in android/qemulator.c */
+extern void android_emulator_set_window_scale(double scale, int is_dpi);
+
+/* One and only one UICmdImpl instance. */
+static UICmdImpl _uiCmdImpl;
+
+/* Display brightness change callback. */
+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.
+ * header - UI control command header.
+ * data - Command parameters formatted accordingly to the command type.
+ */
+static void
+_uiCmdImpl_handle_command(UICmdImpl* uicmd,
+ const UICmdHeader* header,
+ const uint8_t* data)
+{
+ switch (header->cmd_type) {
+ case AUICMD_SET_WINDOWS_SCALE:
+ {
+ UICmdSetWindowsScale* cmd = (UICmdSetWindowsScale*)data;
+ android_emulator_set_window_scale(cmd->scale, cmd->is_dpi);
+ break;
+ }
+
+ case AUICMD_CHANGE_DISP_BRIGHTNESS:
+ {
+ UICmdChangeDispBrightness* cmd = (UICmdChangeDispBrightness*)data;
+ if (_brightness_change_callback != NULL) {
+ _brightness_change_callback(_brightness_change_callback_param,
+ cmd->light, cmd->brightness);
+ }
+ break;
+ }
+
+ default:
+ derror("Unknown command %d is received from the Core\n",
+ header->cmd_type);
+ break;
+ }
+}
+
+/* Asynchronous I/O callback reading UI control commands.
+ * Param:
+ * opaque - UICmdImpl instance.
+ */
+static void
+_uiCmdImpl_io_read(void* opaque)
+{
+ UICmdImpl* uicmd = opaque;
+ int status;
+
+ // Read requests while they are immediately available.
+ for (;;) {
+ // Read next chunk of data.
+ status = read(uicmd->sock, uicmd->reader_buffer + uicmd->reader_offset,
+ uicmd->reader_bytes - uicmd->reader_offset);
+ if (status == 0) {
+ /* Disconnection, meaning that the core process got termonated. */
+ fprintf(stderr, "core-ui-control service got disconnected\n");
+ _uiCmdImpl_destroy();
+ return;
+ }
+ if (status < 0) {
+ if (errno == EINTR) {
+ /* loop on EINTR */
+ continue;
+ } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ // Chunk is not avalable at this point. Come back later.
+ return;
+ }
+ }
+
+ uicmd->reader_offset += status;
+ if (uicmd->reader_offset != uicmd->reader_bytes) {
+ // There are still some data left in the pipe.
+ continue;
+ }
+
+ // All expected data has been read. Time to change the state.
+ if (uicmd->reader_state == EXPECTS_HEADER) {
+ // Header has been read.
+ if (uicmd->cmd_header.cmd_param_size) {
+ // Prepare for the command parameters.
+ uicmd->reader_state = EXPECTS_PARAMETERS;
+ uicmd->reader_offset = 0;
+ uicmd->reader_bytes = uicmd->cmd_header.cmd_param_size;
+ uicmd->reader_buffer = malloc(uicmd->reader_bytes);
+ if (uicmd->reader_buffer == NULL) {
+ APANIC("Unable to allocate memory for UI command parameters.\n");
+ }
+ } else {
+ // This command doesn't have any parameters. Handle it now.
+ _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header, NULL);
+ // Prepare for the next command header.
+ uicmd->reader_state = EXPECTS_HEADER;
+ uicmd->reader_offset = 0;
+ uicmd->reader_bytes = sizeof(uicmd->cmd_header);
+ uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
+ }
+ } else {
+ // All command data is in. Handle it.
+ _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header,
+ uicmd->reader_buffer);
+ // Prepare for the next command header.
+ free(uicmd->reader_buffer);
+ uicmd->reader_state = EXPECTS_HEADER;
+ uicmd->reader_offset = 0;
+ uicmd->reader_bytes = sizeof(uicmd->cmd_header);
+ uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
+ }
+ }
+}
+
+int
+uiCmdImpl_create(SockAddress* console_socket)
+{
+ char* handshake = NULL;
+
+ // Setup command reader.
+ _uiCmdImpl.reader_buffer = (uint8_t*)&_uiCmdImpl.cmd_header;
+ _uiCmdImpl.reader_state = EXPECTS_HEADER;
+ _uiCmdImpl.reader_offset = 0;
+ _uiCmdImpl.reader_bytes = sizeof(UICmdHeader);
+
+ // Connect to the core-ui-control service.
+ _uiCmdImpl.core_connection =
+ core_connection_create_and_switch(console_socket, "core-ui-control",
+ &handshake);
+ if (_uiCmdImpl.core_connection == NULL) {
+ derror("Unable to connect to the core-ui-control service: %s\n",
+ errno_str);
+ return -1;
+ }
+
+ // Initialze UI command reader.
+ _uiCmdImpl.sock = core_connection_get_socket(_uiCmdImpl.core_connection);
+ if (qemu_set_fd_handler(_uiCmdImpl.sock, _uiCmdImpl_io_read, NULL,
+ &_uiCmdImpl)) {
+ derror("Unable to set up UI _uiCmdImpl_io_read callback: %s\n",
+ errno_str);
+ _uiCmdImpl_destroy();
+ if (handshake != NULL) {
+ free(handshake);
+ }
+ return -1;
+ }
+
+ fprintf(stdout, "core-ui-control 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;
+}
+
+int
+uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
+ void* opaque)
+{
+ _brightness_change_callback = callback;
+ _brightness_change_callback_param = opaque;
+ return 0;
+}
diff --git a/android/protocol/ui-commands-impl.h b/android/protocol/ui-commands-impl.h
new file mode 100644
index 0000000..0e5b52f
--- /dev/null
+++ b/android/protocol/ui-commands-impl.h
@@ -0,0 +1,34 @@
+/* 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_UI_COMMANDS_IMPL_H
+#define _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H
+
+#include "sockets.h"
+#include "android/protocol/ui-commands.h"
+
+/*
+ * 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 sent by
+ * the Core to the UI.
+ */
+
+/* Creates and initializes descriptor for the UI-side of the "core-ui-control"
+ * 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 uiCmdImpl_create(SockAddress* console_socket);
+
+#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H */
diff --git a/android/protocol/ui-commands-proxy.c b/android/protocol/ui-commands-proxy.c
new file mode 100644
index 0000000..76bf883
--- /dev/null
+++ b/android/protocol/ui-commands-proxy.c
@@ -0,0 +1,209 @@
+/* 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 "core-ui-control" service that is
+ * part of the UI control protocol. Here we send UI control commands to the UI.
+ */
+
+#include "android/android.h"
+#include "android/hw-control.h"
+#include "android/looper.h"
+#include "android/async-utils.h"
+#include "android/sync-utils.h"
+#include "android/utils/debug.h"
+#include "android/protocol/ui-commands.h"
+#include "android/protocol/ui-commands-proxy.h"
+#include "android/protocol/ui-commands-api.h"
+
+/* Descriptor for the UI commands proxy. */
+typedef struct UICmdProxy {
+ /* I/O associated with this descriptor. */
+ LoopIo io;
+
+ /* Looper associated with this descriptor. */
+ Looper* looper;
+
+ /* Writer to send UI commands. */
+ SyncSocket* sync_writer;
+
+ /* Socket descriptor for this service. */
+ int sock;
+} UICmdProxy;
+
+/* One and only one UICmdProxy instance. */
+static UICmdProxy _uiCmdProxy;
+
+/* Implemented in android/console.c */
+extern void destroy_uicmd_client(void);
+
+/* Calculates timeout for transferring the given number of bytes via socket.
+ * Return:
+ * Number of milliseconds during which the entire number of bytes is expected
+ * to be transferred via socket.
+ */
+static int
+_uiCmdProxy_get_timeout(size_t data_size)
+{
+ // Min 2 seconds + 10 millisec for each transferring byte.
+ // TODO: Come up with a better arithmetics here.
+ return 2000 + data_size * 10;
+}
+
+/* Sends request to the UI client of this service.
+ * Param:
+ * cmd_type, cmd_param, cmd_param_size - Define the command to send.
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+static int
+_uiCmdProxy_send_command(uint8_t cmd_type,
+ void* cmd_param,
+ uint32_t cmd_param_size)
+{
+ UICmdHeader header;
+ int status = syncsocket_start_write(_uiCmdProxy.sync_writer);
+ if (!status) {
+ // Initialize and send the header.
+ header.cmd_type = cmd_type;
+ header.cmd_param_size = cmd_param_size;
+ status = syncsocket_write(_uiCmdProxy.sync_writer, &header, sizeof(header),
+ _uiCmdProxy_get_timeout(sizeof(header)));
+ // If there are command parameters, send them too.
+ if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
+ status = syncsocket_write(_uiCmdProxy.sync_writer, cmd_param,
+ cmd_param_size,
+ _uiCmdProxy_get_timeout(cmd_param_size));
+ }
+ status = syncsocket_result(status);
+ syncsocket_stop_write(_uiCmdProxy.sync_writer);
+ }
+ if (status < 0) {
+ derror("Send UI command %d (%u bytes) has failed: %s\n",
+ cmd_type, cmd_param_size, errno_str);
+ }
+ return status;
+}
+
+/* Asynchronous I/O callback for UICmdProxy 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 - UICmdProxy instance.
+ */
+static void
+_uiCmdProxy_io_func(void* opaque, int fd, unsigned events)
+{
+ UICmdProxy* uicmd = (UICmdProxy*)opaque;
+ AsyncReader reader;
+ AsyncStatus status;
+ uint8_t read_buf[1];
+
+ if (events & LOOP_IO_WRITE) {
+ derror("Unexpected LOOP_IO_WRITE in _uiCmdProxy_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 _uiCmdProxy_io_func\n", status);
+ return;
+ }
+ // We expect only socket disconnection error here.
+ if (errno != ECONNRESET) {
+ derror("Unexpected read error %d (%s) in _uiCmdProxy_io_func.\n",
+ errno, errno_str);
+ return;
+ }
+
+ // Client got disconnectted.
+ destroy_uicmd_client();
+}
+/* a callback function called when the system wants to change the brightness
+ * of a given light. 'light' is a string which can be one of:
+ * 'lcd_backlight', 'button_backlight' or 'Keyboard_backlight'
+ *
+ * brightness is an integer (acceptable range are 0..255), however the
+ * default is around 105, and we probably don't want to dim the emulator's
+ * output at that level.
+ */
+static void
+_uiCmdProxy_brightness_change_callback(void* opaque,
+ const char* light,
+ int brightness)
+{
+ // Calculate size of the command parameters.
+ const size_t cmd_size = sizeof(UICmdChangeDispBrightness) + strlen(light) + 1;
+ // Allocate and initialize parameters.
+ UICmdChangeDispBrightness* cmd =
+ (UICmdChangeDispBrightness*)qemu_malloc(cmd_size);
+ cmd->brightness = brightness;
+ strcpy(cmd->light, light);
+ // Send the command.
+ _uiCmdProxy_send_command(AUICMD_CHANGE_DISP_BRIGHTNESS, cmd, cmd_size);
+ qemu_free(cmd);
+}
+
+int
+uiCmdProxy_create(int fd)
+{
+ // Initialize the only UICmdProxy instance.
+ _uiCmdProxy.sock = fd;
+ _uiCmdProxy.looper = looper_newCore();
+ loopIo_init(&_uiCmdProxy.io, _uiCmdProxy.looper, _uiCmdProxy.sock,
+ _uiCmdProxy_io_func, &_uiCmdProxy);
+ loopIo_wantRead(&_uiCmdProxy.io);
+ _uiCmdProxy.sync_writer = syncsocket_init(fd);
+ if (_uiCmdProxy.sync_writer == NULL) {
+ derror("Unable to initialize UICmdProxy writer: %s\n", errno_str);
+ uiCmdProxy_destroy();
+ return -1;
+ }
+ {
+ // Set brighness change callback, so we can notify
+ // the UI about the event.
+ AndroidHwControlFuncs funcs;
+ funcs.light_brightness = _uiCmdProxy_brightness_change_callback;
+ android_hw_control_init(&_uiCmdProxy, &funcs);
+ }
+ return 0;
+}
+
+void
+uiCmdProxy_destroy()
+{
+ // Destroy the sync writer.
+ if (_uiCmdProxy.sync_writer != NULL) {
+ syncsocket_close(_uiCmdProxy.sync_writer);
+ syncsocket_free(_uiCmdProxy.sync_writer);
+ }
+ if (_uiCmdProxy.looper != NULL) {
+ // Stop all I/O that may still be going on.
+ loopIo_done(&_uiCmdProxy.io);
+ looper_free(_uiCmdProxy.looper);
+ _uiCmdProxy.looper = NULL;
+ }
+ _uiCmdProxy.sock = -1;
+}
+
+int
+uicmd_set_window_scale(double scale, int is_dpi)
+{
+ UICmdSetWindowsScale cmd;
+ cmd.scale = scale;
+ cmd.is_dpi = is_dpi;
+ return _uiCmdProxy_send_command(AUICMD_SET_WINDOWS_SCALE, &cmd, sizeof(cmd));
+}
diff --git a/android/protocol/ui-commands-proxy.h b/android/protocol/ui-commands-proxy.h
new file mode 100644
index 0000000..8627537
--- /dev/null
+++ b/android/protocol/ui-commands-proxy.h
@@ -0,0 +1,41 @@
+/* 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_UI_COMMANDS_PROXY_H
+#define _ANDROID_PROTOCOL_UI_COMMANDS_PROXY_H
+
+/*
+ * Contains the Core-side implementation of the "core-ui-control" service that is
+ * part of the UI control protocol. Here we send UI control commands to the UI.
+ */
+
+/* Creates and initializes descriptor for the Core-side of the "core-ui-control"
+ * 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 uiCmdProxy_create(int fd);
+
+/* Destroys the descriptor for the Core-side of the "core-ui-control" service. */
+extern void uiCmdProxy_destroy();
+
+/* Changes the scale of the emulator window at runtime.
+ * Param:
+ * scale, is_dpi - New window scale parameters
+ * Return:
+ * 0 on success, or < 0 on failure.
+ */
+extern int uicmd_set_window_scale(double scale, int is_dpi);
+
+#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_PROXY_H */
diff --git a/android/protocol/ui-commands-qemu.c b/android/protocol/ui-commands-qemu.c
new file mode 100644
index 0000000..3dbed31
--- /dev/null
+++ b/android/protocol/ui-commands-qemu.c
@@ -0,0 +1,40 @@
+/* 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 implementation of the API for calling into the UI with the Core
+ * control commands for standalone (monolithic) emulator.
+ */
+
+#include "android/android.h"
+#include "android/hw-control.h"
+#include "android/protocol/ui-commands-api.h"
+
+/* Implemented in android/qemulator.c */
+extern void android_emulator_set_window_scale(double scale, int is_dpi);
+
+int
+uicmd_set_window_scale(double scale, int is_dpi)
+{
+ android_emulator_set_window_scale(scale, is_dpi);
+ return 0;
+}
+
+int
+uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
+ void* opaque)
+{
+ AndroidHwControlFuncs funcs;
+ funcs.light_brightness = callback;
+ android_hw_control_init(opaque, &funcs);
+ return 0;
+}
diff --git a/android/protocol/ui-commands.h b/android/protocol/ui-commands.h
new file mode 100644
index 0000000..4e47b83
--- /dev/null
+++ b/android/protocol/ui-commands.h
@@ -0,0 +1,44 @@
+/* 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_UI_COMMANDS_H
+#define _ANDROID_PROTOCOL_UI_COMMANDS_H
+
+/*
+ * Contains declarations related to the UI control commands sent by the Core and
+ * handled by the UI.
+ */
+
+#include "android/protocol/ui-common.h"
+
+/* Sets window scale. */
+#define AUICMD_SET_WINDOWS_SCALE 1
+
+/* Changes display brightness. */
+#define AUICMD_CHANGE_DISP_BRIGHTNESS 2
+
+/* Formats AUICMD_SET_WINDOWS_SCALE UI control command parameters.
+ * Contains parameters required by android_emulator_set_window_scale routine.
+ */
+typedef struct UICmdSetWindowsScale {
+ double scale;
+ int is_dpi;
+} UICmdSetWindowsScale;
+
+/* Formats AUICMD_CHANGE_DISP_BRIGHTNESS UI control command parameters.
+ */
+typedef struct UICmdChangeDispBrightness {
+ int brightness;
+ char light[0];
+} UICmdChangeDispBrightness;
+
+#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_H */
diff --git a/android/protocol/ui-common.h b/android/protocol/ui-common.h
new file mode 100644
index 0000000..003ed6d
--- /dev/null
+++ b/android/protocol/ui-common.h
@@ -0,0 +1,53 @@
+/* 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_UI_COMMON_H
+#define _ANDROID_PROTOCOL_UI_COMMON_H
+
+/*
+ * Contains declarations for UI control protocol used by both the Core,
+ * and the UI.
+ */
+
+/* UI control command header.
+ * Every UI control command sent by the Core, or by the UI begins with this
+ * header, immediately followed by the command parameters (if there are any).
+ * Command type is defined by cmd_type field of this header. If command doesn't
+ * have any command-specific parameters, cmd_param_size field of this header
+ * must be 0.
+ */
+typedef struct UICmdHeader {
+ /* Command type. */
+ uint8_t cmd_type;
+
+ /* Byte size of the buffer containing parameters for the comand defined by
+ * the cmd_type field. The buffer containing parameters must immediately
+ * follow this header. If command doesn't have any parameters, this field
+ * must be 0 */
+ uint32_t cmd_param_size;
+} UICmdHeader;
+
+/* UI control command response header.
+ * If UI control command assumes a response from the remote end, the response
+ * must start with this header, immediately followed by the response data buffer.
+ */
+typedef struct UICmdRespHeader {
+ /* Result of the command handling. */
+ int result;
+
+ /* Byte size of the buffer containing response data immediately following
+ * this header. If there are no response data for the command, this field
+ * must be 0. */
+ uint32_t resp_data_size;
+} UICmdRespHeader;
+
+#endif /* _ANDROID_PROTOCOL_UI_COMMON_H */
diff --git a/android/qemu-setup.c b/android/qemu-setup.c
index f0157cd..f1a12ee 100644
--- a/android/qemu-setup.c
+++ b/android/qemu-setup.c
@@ -23,7 +23,6 @@
#include "android/utils/path.h"
#include "android/utils/system.h"
#include "android/utils/bufprint.h"
-#include "android/core-ui-protocol.h"
#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
diff --git a/android/qemulator.c b/android/qemulator.c
index a5f0dc0..f1b2dbc 100644
--- a/android/qemulator.c
+++ b/android/qemulator.c
@@ -14,7 +14,8 @@
#include "android/utils/bufprint.h"
#include "android/globals.h"
#include "android/qemulator.h"
-#include "android/ui-core-protocol.h"
+#include "android/protocol/core-commands-api.h"
+#include "android/protocol/ui-commands-api.h"
#include "user-events.h"
#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
@@ -87,8 +88,8 @@ qemulator_setup( QEmulator* emulator )
}
/* initialize hardware control support */
- android_core_set_brightness_change_callback(qemulator_light_brightness,
- emulator);
+ uicmd_set_brightness_change_callback(qemulator_light_brightness,
+ emulator);
}
static void
@@ -272,7 +273,7 @@ qemulator_set_title(QEmulator* emulator)
int
get_device_dpi( AndroidOptions* opts )
{
- int dpi_device = android_core_get_hw_lcd_density();
+ int dpi_device = corecmd_get_hw_lcd_density();
if (opts->dpi_device != NULL) {
char* end;
@@ -405,8 +406,8 @@ handle_key_command( void* opaque, SkinKeyCommand command, int down )
{
case SKIN_KEY_COMMAND_TOGGLE_NETWORK:
{
- android_core_toggle_network();
- D( "network is now %s", android_core_is_network_disabled() ?
+ corecmd_toggle_network();
+ D( "network is now %s", corecmd_is_network_disabled() ?
"disconnected" : "connected" );
}
break;
@@ -421,10 +422,7 @@ handle_key_command( void* opaque, SkinKeyCommand command, int down )
{
#ifdef CONFIG_TRACE
tracing = !tracing;
- if (tracing)
- android_core_tracing_start();
- else
- android_core_tracing_stop();
+ corecmd_trace_control(tracing);
#endif
}
break;
diff --git a/android/skin/window.c b/android/skin/window.c
index 431412b..c2d0bf4 100644
--- a/android/skin/window.c
+++ b/android/skin/window.c
@@ -16,7 +16,7 @@
#include "android/utils/debug.h"
#include "android/utils/system.h"
#include "android/utils/duff.h"
-#include "android/ui-core-protocol.h"
+#include "android/protocol/core-commands-api.h"
#include <SDL_syswm.h>
#include "user-events.h"
#include <math.h>
@@ -1340,9 +1340,9 @@ skin_window_reset_internal ( SkinWindow* window, SkinLayout* slayout )
user_event_generic( slayout->event_type, slayout->event_code, slayout->event_value );
/* XXX: hack, replace by better code here */
if (slayout->event_value != 0)
- android_core_sensors_set_coarse_orientation( ANDROID_COARSE_PORTRAIT );
+ corecmd_set_coarse_orientation( ANDROID_COARSE_PORTRAIT );
else
- android_core_sensors_set_coarse_orientation( ANDROID_COARSE_LANDSCAPE );
+ corecmd_set_coarse_orientation( ANDROID_COARSE_LANDSCAPE );
}
return 0;
diff --git a/android/ui-core-protocol.c b/android/ui-core-protocol.c
deleted file mode 100644
index 8dd14a7..0000000
--- a/android/ui-core-protocol.c
+++ /dev/null
@@ -1,173 +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.
-*/
-
-/*
- * This file contains helper routines that are used to establish communication
- * between UI and Core components of the emulator. This is a temporary file
- * where we will collect functional dependencies between UI and Core in the
- * process of separating UI and Core in the emulator build. Ideally at the
- * end this will be replaced with a message protocol over sockets, or other
- * means of interprocess communication.
- */
-
-#include "android/android.h"
-#include "android/globals.h"
-#include "android/hw-control.h"
-#include "android/ui-core-protocol.h"
-#include "android/ui-ctl-ui.h"
-#if !defined(CONFIG_STANDALONE_UI)
-#include "telephony/modem_driver.h"
-#include "trace.h"
-#include "audio/audio.h"
-/* Implemented in vl-android.c */
-extern char* qemu_find_file(int type, const char* filename);
-#endif // CONFIG_STANDALONE_UI
-
-int
-android_core_get_hw_lcd_density(void)
-{
- return android_hw->hw_lcd_density;
-}
-
-void
-android_core_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
- void* opaque)
-{
- AndroidHwControlFuncs funcs;
-
- funcs.light_brightness = callback;
-#if !defined(CONFIG_STANDALONE_UI)
- android_hw_control_init( opaque, &funcs );
-#endif // CONFIG_STANDALONE_UI
-}
-
-void
-android_core_sensors_set_coarse_orientation( AndroidCoarseOrientation orient )
-{
-#if !defined(CONFIG_STANDALONE_UI)
- android_sensors_set_coarse_orientation(orient);
-#else
- clientuictl_set_coarse_orientation(orient);
-#endif // CONFIG_STANDALONE_UI
-}
-
-void
-android_core_toggle_network(void)
-{
- /* Temporary implementation for the monolitic (core + ui) builds. */
-#if !defined(CONFIG_STANDALONE_UI)
- qemu_net_disable = !qemu_net_disable;
- if (android_modem) {
- amodem_set_data_registration(
- android_modem,
- qemu_net_disable ? A_REGISTRATION_UNREGISTERED
- : A_REGISTRATION_HOME);
- }
-#else
- clientuictl_toggle_network();
-#endif // CONFIG_STANDALONE_UI
-}
-
-int
-android_core_is_network_disabled(void)
-{
- /* Temporary implementation for the monolitic (core + ui) builds. */
-#if !defined(CONFIG_STANDALONE_UI)
- return qemu_net_disable;
-#else
- return clientuictl_check_network_disabled();
-#endif // CONFIG_STANDALONE_UI
-}
-
-void android_core_tracing_start(void)
-{
-#if !defined(CONFIG_STANDALONE_UI)
- start_tracing();
-#else
- clientuictl_trace_control(1);
-#endif // CONFIG_STANDALONE_UI
-}
-
-void android_core_tracing_stop(void)
-{
-#if !defined(CONFIG_STANDALONE_UI)
- stop_tracing();
-#else
- clientuictl_trace_control(0);
-#endif // CONFIG_STANDALONE_UI
-}
-
-int
-android_core_get_android_netspeed(int index, NetworkSpeed** netspeed) {
- /* This is a temporary code used to support current behavior of the
- *monolitic (core + ui in one executable) emulator executed with
- * -help-netspeed option. In the future, when ui and core get separated,
- * behavior of help may change, and this code should be reviewed. */
-#if !defined(CONFIG_STANDALONE_UI)
- if (index >= android_netspeeds_count ||
- android_netspeeds[index].name == NULL) {
- return -1;
- }
- *netspeed = (NetworkSpeed*)malloc(sizeof(NetworkSpeed));
- memcpy(*netspeed, &android_netspeeds[index], sizeof(NetworkSpeed));
- return 0;
-#else
- return clientuictl_get_netspeed(index, netspeed);
-#endif // !CONFIG_STANDALONE_UI
-}
-
-int
-android_core_get_android_netdelay(int index, NetworkLatency** delay) {
- /* This is a temporary code used to support current behavior of the
- * monolitic (core + ui in one executable) emulator executed with
- * -help-netdelays option. In the future, when ui and core get separated,
- * behavior of help may change, and this code should be reviewed. */
-#if !defined(CONFIG_STANDALONE_UI)
- if (index >= android_netdelays_count ||
- android_netdelays[index].name == NULL) {
- return -1;
- }
- *delay = (NetworkLatency*)malloc(sizeof(NetworkLatency));
- memcpy(*delay, &android_netdelays[index], sizeof(NetworkLatency));
- return 0;
-#else
- return clientuictl_get_netdelay(index, delay);
-#endif // !CONFIG_STANDALONE_UI
-}
-
-int
-android_core_qemu_find_file(int type, const char *filename,
- char* path, size_t path_buf_size)
-{
- /* Temporary implementation for the monolitic (core + ui) builds. */
-#if !defined(CONFIG_STANDALONE_UI)
- char* filepath = qemu_find_file(type, filename);
- if (filepath == NULL) {
- return -1;
- }
- strncpy(path, filepath, path_buf_size);
- path[path_buf_size - 1] = '\0';
- qemu_free(filepath);
- return 0;
-#else
- char* ret_path = NULL;
- int status = clientuictl_get_qemu_path(type, filename, &ret_path);
- if (!status && ret_path != NULL) {
- strncpy(path, ret_path, path_buf_size);
- path[path_buf_size - 1] = '\0';
- }
- if (ret_path != NULL) {
- free(ret_path);
- }
- return status;
-#endif // !CONFIG_STANDALONE_UI
-}
diff --git a/android/ui-core-protocol.h b/android/ui-core-protocol.h
deleted file mode 100644
index 2a4cee6..0000000
--- a/android/ui-core-protocol.h
+++ /dev/null
@@ -1,88 +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.
-*/
-
-/*
- * This file contains declarations of helper routines that are used to
- * establish communication between UI and Core components of the emulator.
- * This is a temporary file where we will collect functional dependencies
- * between UI and Core in the process of separating UI and Core in the
- * emulator build.
- */
-
-#ifndef QEMU_ANDROID_UI_CORE_PROTOCOL_H
-#define QEMU_ANDROID_UI_CORE_PROTOCOL_H
-
-#include "android/hw-sensors.h"
-
-/* Gets LCD density property from the core properties. */
-int android_core_get_hw_lcd_density(void);
-
-/* This is temporary redeclaration for AndroidHwLightBrightnessFunc declared
- * in android/hw-control.h We redeclare it here in order to keep type
- * consistency between android_core_set_brightness_change_callback and
- * light_brightness field of AndroidHwControlFuncs structure.
- */
-typedef void (*AndroidHwLightBrightnessCallback)( void* opaque,
- const char* light,
- int brightness );
-
-/* Registers a UI callback to be called when brightness is changed by the core. */
-void android_core_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
- void* opaque);
-
-/* change the coarse orientation value */
-void android_core_sensors_set_coarse_orientation( AndroidCoarseOrientation orient );
-
-/* Toggles the network state */
-void android_core_toggle_network(void);
-
-/* Gets the network state */
-int android_core_is_network_disabled(void);
-
-/* Start/stop tracing in the guest system */
-void android_core_tracing_start(void);
-void android_core_tracing_stop(void);
-
-/* Gets an entry in android_netspeeds array defined in net-android.c
- * Parameters:
- * index - Index of the entry to get from the array.
- * netspeed - Upon successful return contains copy of the requested entry.
- * Return:
- * 0 on success, or -1 if requested entry index is too large.
- */
-int android_core_get_android_netspeed(int index, NetworkSpeed** netspeed);
-
-/* Gets an entry in android_netdelays array defined in net-android.c
- * Parameters:
- * index - Index of the entry to get from the array.
- * netspeed - Upon successful return contains copy of the requested entry.
- * Return:
- * 0 on success, or -1 if requested entry index is too large.
- */
-int android_core_get_android_netdelay(int index, NetworkLatency** delay);
-
-/* Builds a path to a file of the given type in the emulator's data directory.
- * Param:
- * type - Type of the file to find. Only QEMU_FILE_TYPE_BIOS, and
- * QEMU_FILE_TYPE_KEYMAP are allowed for this value.
- * filename - Name of the file to build path for.
- * path - Upon success contains path to the requested file inside the
- * emulator's data directory.
- * path_buf_size Character size of the buffer addressed by the path parameter.
- * Return:
- * 0 on success, or -1 on an error.
- */
-int
-android_core_qemu_find_file(int type, const char *filename,
- char* path, size_t path_buf_size);
-
-#endif // QEMU_ANDROID_UI_CORE_PROTOCOL_H
diff --git a/android/ui-ctl-common.h b/android/ui-ctl-common.h
deleted file mode 100644
index bc5960c..0000000
--- a/android/ui-ctl-common.h
+++ /dev/null
@@ -1,144 +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.
-*/
-
-#ifndef _ANDROID_UI_CONTROL_COMMON_H
-#define _ANDROID_UI_CONTROL_COMMON_H
-
-#include "android/hw-sensors.h"
-
-/*
- * UI control requests sent by the core to the UI.
- */
-
-/* Sets window scale. */
-#define ACORE_UICTL_SET_WINDOWS_SCALE 1
-
-/*
- * UI control requests sent by the UI to the core.
- */
-
-/* Sets coarse orientation. */
-#define AUI_UICTL_SET_COARSE_ORIENTATION 2
-
-/* Toggles the network (no parameters). */
-#define AUI_UICTL_TOGGLE_NETWORK 3
-
-/* Starts / stops the tracing. */
-#define AUI_UICTL_TRACE_CONTROL 4
-
-/* Checks if network is disabled (no params) */
-#define AUI_UICTL_CHK_NETWORK_DISABLED 5
-
-/* Gets net speed */
-#define AUI_UICTL_GET_NETSPEED 6
-
-/* Gets net delays */
-#define AUI_UICTL_GET_NETDELAY 7
-
-/* Gets path to a QEMU file on local host. */
-#define AUI_UICTL_GET_QEMU_PATH 8
-
-/* UI control message header. */
-typedef struct UICtlHeader {
- /* Message type. */
- uint8_t msg_type;
-
- /* Size of the message data following this header. */
- uint32_t msg_data_size;
-} UICtlHeader;
-
-/* UI control response header. */
-typedef struct UICtlRespHeader {
- /* Result of the request handling. */
- int result;
-
- /* Size of the response data following this header. */
- uint32_t resp_data_size;
-} UICtlRespHeader;
-
-/* Formats ACORE_UICTL_SET_WINDOWS_SCALE UI control request.
- */
-typedef struct UICtlSetWindowsScale {
- double scale;
- int is_dpi;
-} UICtlSetWindowsScale;
-
-/* Formats AUI_UICTL_SET_COARSE_ORIENTATION UI control request.
- */
-typedef struct UICtlSetCoarseOrientation {
- AndroidCoarseOrientation orient;
-} UICtlSetCoarseOrientation;
-
-/* Formats AUI_UICTL_TRACE_CONTROL UI control request.
- */
-typedef struct UICtlTraceControl {
- int start;
-} UICtlTraceControl;
-
-/* Formats AUI_UICTL_GET_NETSPEED UI control request.
- */
-typedef struct UICtlGetNetSpeed {
- int index;
-} UICtlGetNetSpeed;
-
-/* Formats AUI_UICTL_GET_NETSPEED UI control request response.
- */
-typedef struct UICtlGetNetSpeedResp {
- /* Size of the entire response structure including name and display strings. */
- int upload;
- int download;
- /* display field of NetworkSpeed structure is immediately following
- * this field. */
- char name[0];
-} UICtlGetNetSpeedResp;
-
-/* Formats AUI_UICTL_GET_NETDELAY UI control request.
- */
-typedef struct UICtlGetNetDelay {
- int index;
-} UICtlGetNetDelay;
-
-/* Formats AUI_UICTL_GET_NETDELAY UI control request response.
- */
-typedef struct UICtlGetNetDelayResp {
- /* Size of the entire response structure including name and display strings. */
- int min_ms;
- int max_ms;
- /* display field of NetworkLatency structure is immediately following
- * this field. */
- char name[0];
-} UICtlGetNetDelayResp;
-
-/* Formats AUI_UICTL_GET_QEMU_PATH UI control request.
- */
-typedef struct UICtlGetQemuPath {
- int type;
- char filename[0];
-} UICtlGetQemuPath;
-
-/* Formats AUI_UICTL_GET_QEMU_PATH UI control request response.
- */
-typedef struct UICtlGetQemuPathResp {
- /* Size of the entire response structure. */
- char path[0];
-} UICtlGetQemuPathResp;
-
-#if 0
-android_core_get_android_netspeed(int index, NetworkSpeed* netspeed) {
-android_core_get_android_netdelay(int index, NetworkLatency* delay) {
-int
-android_core_qemu_find_file(int type, const char *filename,
- char* path, size_t path_buf_size)
-#endif
-
-#endif /* _ANDROID_UI_CONTROL_COMMON_H */
-
diff --git a/android/ui-ctl-core.c b/android/ui-ctl-core.c
deleted file mode 100644
index 4552bb8..0000000
--- a/android/ui-ctl-core.c
+++ /dev/null
@@ -1,568 +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 "qemu-common.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/ui-ctl-common.h"
-#include "android/ui-ctl-core.h"
-#include "android/hw-sensors.h"
-#include "telephony/modem_driver.h"
-#include "trace.h"
-#include "audio/audio.h"
-
-/* Enumerates state values for UICoreCtl descriptor. */
-typedef enum UICoreCtlState {
- /* UI message header is expected in the pipe. */
- UI_STATE_EXPECT_HEADER,
- /* UI message data are expected in the pipe. */
- UI_STATE_EXPECT_DATA
-} UICoreCtlState;
-
-/* Core UI control service descriptor used for UI->Core communication. */
-typedef struct UICoreCtl {
- /* Reader to detect UI disconnection. */
- AsyncReader async_reader;
-
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper used to communicate user events. */
- Looper* looper;
-
- /* Writer to send responses to UI requests. */
- SyncSocket* sync_writer;
-
- /* Socket descriptor for this service. */
- int sock;
-
- /* State of incoming requests. */
- UICoreCtlState in_req_state;
-
- /* Incoming request header. */
- UICtlHeader req_header;
-
- /* A buffer for small incoming requests. */
- uint8_t req_data[256];
-
- /* Buffer to use for reading incoming request data. Depending on expected
- * incoming request size this buffer can point to req_data field of this
- * structure (for small requests), or can be allocated for large requests. */
- void* req_data_buffer;
-} UICoreCtl;
-
-/* Core UI control service descriptor used for Core->UI communication. */
-typedef struct CoreUICtl {
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper associated with this descriptor. */
- Looper* looper;
-
- /* Writer to send UI commands. */
- SyncSocket* sync_writer;
-
- /* Socket descriptor for this service. */
- int sock;
-} CoreUICtl;
-
-/* One and only one CoreUICtl instance. */
-static CoreUICtl _core_ui_ctl;
-
-/* One and only one UICoreCtl instance. */
-static UICoreCtl _ui_core_ctl;
-
-/* Calculates timeout for transferring the given number of bytes via UI control
- * socket.
- * Return:
- * Number of milliseconds during which the entire number of bytes is expected
- * to be transferred.
- */
-static int
-_get_transfer_timeout(size_t data_size)
-{
- // Min 200 millisec + one millisec for each transferring byte.
- // TODO: Come up with a better arithmetics here.
- return 200 + data_size;
-}
-
-/*
- * Core -> UI control implementation
- */
-
-/* Implemented in android/console.c */
-extern void destroy_core_ui_ctl_client(void);
-
-/* Sends request to the UI client.
- * Param:
- * msg_type, msg_data, msg_data_size - Define core request to send.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_coreuictl_send_request(uint8_t msg_type,
- void* msg_data,
- uint32_t msg_data_size)
-{
- UICtlHeader header;
- int status = syncsocket_start_write(_core_ui_ctl.sync_writer);
- if (!status) {
-
- // Initialize and send the header.
- header.msg_type = msg_type;
- header.msg_data_size = msg_data_size;
- status = syncsocket_write(_core_ui_ctl.sync_writer, &header, sizeof(header),
- _get_transfer_timeout(sizeof(header)));
- // If there is request data, send it too.
- if (status > 0 && msg_data != NULL && msg_data_size > 0) {
- status = syncsocket_write(_core_ui_ctl.sync_writer, msg_data,
- msg_data_size,
- _get_transfer_timeout(msg_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(_core_ui_ctl.sync_writer);
- }
- if (status < 0) {
- derror("Unable to send core UI control request: %s\n", errno_str);
- }
- return status;
-}
-
-/*
- * Asynchronous I/O callback for CoreUICtl 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 - CoreUICtl instance.
- */
-static void
-_coreuictl_io_func(void* opaque, int fd, unsigned events)
-{
- CoreUICtl* uictl = (CoreUICtl*)opaque;
- AsyncReader reader;
- AsyncStatus status;
- uint8_t read_buf[1];
-
- if (events & LOOP_IO_WRITE) {
- derror("Unexpected LOOP_IO_WRITE in coreuictl_io_func\n");
- return;
- }
-
- // Try to read
- asyncReader_init(&reader, read_buf, sizeof(read_buf), &uictl->io);
- status = asyncReader_read(&reader, &uictl->io);
- // We expect only error status here.
- if (status != ASYNC_ERROR) {
- derror("Unexpected read status %d in coreuictl_io_func\n", status);
- return;
- }
- // We expect only socket disconnection here.
- if (errno != ECONNRESET) {
- derror("Unexpected read error %d (%s) in coreuictl_io_func\n",
- errno, errno_str);
- return;
- }
-
- // Client got disconnectted.
- destroy_core_ui_ctl_client();
-}
-
-int
-coreuictl_create(int fd)
-{
- // Initialize _core_ui_ctl instance.
- _core_ui_ctl.sock = fd;
- _core_ui_ctl.looper = looper_newCore();
- loopIo_init(&_core_ui_ctl.io, _core_ui_ctl.looper, _core_ui_ctl.sock,
- _coreuictl_io_func, &_core_ui_ctl);
- loopIo_wantRead(&_core_ui_ctl.io);
- _core_ui_ctl.sync_writer = syncsocket_init(fd);
- if (_core_ui_ctl.sync_writer == NULL) {
- derror("Unable to initialize CoreUICtl writer: %s\n", errno_str);
- return -1;
- }
- return 0;
-}
-
-void
-coreuictl_destroy()
-{
- if (_core_ui_ctl.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_core_ui_ctl.io);
- looper_free(_core_ui_ctl.looper);
- _core_ui_ctl.looper = NULL;
- }
- if (_core_ui_ctl.sync_writer != NULL) {
- syncsocket_close(_core_ui_ctl.sync_writer);
- syncsocket_free(_core_ui_ctl.sync_writer);
- }
- _core_ui_ctl.sock = -1;
-}
-
-int
-coreuictl_set_window_scale(double scale, int is_dpi)
-{
- UICtlSetWindowsScale msg;
- msg.scale = scale;
- msg.is_dpi = is_dpi;
- return _coreuictl_send_request(ACORE_UICTL_SET_WINDOWS_SCALE, &msg,
- sizeof(msg));
-}
-
-/*
- * UI -> Core control implementation
- */
-
-/* Implemented in android/console.c */
-extern void destroy_ui_core_ctl_client(void);
-/* Implemented in vl-android.c */
-extern char* qemu_find_file(int type, const char* filename);
-
-/* Properly initializes req_data_buffer field in UICoreCtl instance to receive
- * the expected incoming request data buffer.
- */
-static uint8_t*
-_alloc_req_data_buffer(UICoreCtl* uictl, uint32_t size)
-{
- if (size < sizeof(uictl->req_data)) {
- // req_data can contain all request data.
- uictl->req_data_buffer = &uictl->req_data[0];
- } else {
- // Expected request us too large to fit into preallocated buffer.
- uictl->req_data_buffer = qemu_malloc(size);
- }
- return uictl->req_data_buffer;
-}
-
-/* Properly frees req_data_buffer field in UICoreCtl instance.
- */
-static void
-_free_req_data_buffer(UICoreCtl* uictl)
-{
- if (uictl->req_data_buffer != &uictl->req_data[0]) {
- qemu_free(uictl->req_data_buffer);
- uictl->req_data_buffer = &uictl->req_data[0];
- }
-}
-
-/* Sends response back to the UI
- * Param:
- * uictl - UICoreCtl instance to use for the response sending.
- * resp - Response header.
- * resp_data - Response data. Data size is defined by the header.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_uicorectl_send_response(UICoreCtl* uictl, UICtlRespHeader* resp, void* resp_data)
-{
- int status = syncsocket_start_write(uictl->sync_writer);
- if (!status) {
- // Write the header
- status = syncsocket_write(uictl->sync_writer, resp,
- sizeof(UICtlRespHeader),
- _get_transfer_timeout(sizeof(UICtlRespHeader)));
- // Write response data (if any).
- if (status > 0 && resp_data != NULL && resp->resp_data_size != 0) {
- status = syncsocket_write(uictl->sync_writer, resp_data,
- resp->resp_data_size,
- _get_transfer_timeout(resp->resp_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(uictl->sync_writer);
- }
- if (status < 0) {
- derror("Unable to send UI control response: %s\n", errno_str);
- }
- return status;
-}
-
-/* Handles UI control request from the UI.
- * Param:
- * uictl - UICoreCtl instance that received the request.
- * req_header - Request header.
- * req_data - Request data.
- */
-static void
-_handle_uictl_request(UICoreCtl* uictl,
- const UICtlHeader* req_header,
- const uint8_t* req_data)
-{
- switch (req_header->msg_type) {
- case AUI_UICTL_SET_COARSE_ORIENTATION:
- {
- UICtlSetCoarseOrientation* req = (UICtlSetCoarseOrientation*)req_data;
- android_sensors_set_coarse_orientation(req->orient);
- break;
- }
-
- case AUI_UICTL_TOGGLE_NETWORK:
- qemu_net_disable = !qemu_net_disable;
- if (android_modem) {
- amodem_set_data_registration(
- android_modem,
- qemu_net_disable ? A_REGISTRATION_UNREGISTERED
- : A_REGISTRATION_HOME);
- }
- break;
-
- case AUI_UICTL_TRACE_CONTROL:
- {
- UICtlTraceControl* req = (UICtlTraceControl*)req_data;
- if (req->start) {
- start_tracing();
- } else {
- stop_tracing();
- }
- break;
- }
-
- case AUI_UICTL_CHK_NETWORK_DISABLED:
- {
- UICtlRespHeader resp;
- resp.resp_data_size = 0;
- resp.result = qemu_net_disable;
- _uicorectl_send_response(uictl, &resp, NULL);
- break;
- }
-
- case AUI_UICTL_GET_NETSPEED:
- {
- UICtlRespHeader resp;
- UICtlGetNetSpeedResp* resp_data = NULL;
- UICtlGetNetSpeed* req = (UICtlGetNetSpeed*)req_data;
-
- resp.resp_data_size = 0;
- resp.result = 0;
-
- if (req->index >= android_netspeeds_count ||
- android_netspeeds[req->index].name == NULL) {
- resp.result = -1;
- } else {
- const NetworkSpeed* netspeed = &android_netspeeds[req->index];
- // Calculate size of the response data:
- // fixed header + zero-terminated netspeed name.
- resp.resp_data_size = sizeof(UICtlGetNetSpeedResp) +
- strlen(netspeed->name) + 1;
- // Count in zero-terminated netspeed display.
- if (netspeed->display != NULL) {
- resp.resp_data_size += strlen(netspeed->display) + 1;
- } else {
- resp.resp_data_size++;
- }
- // Allocate and initialize response data buffer.
- resp_data =
- (UICtlGetNetSpeedResp*)qemu_malloc(resp.resp_data_size);
- resp_data->upload = netspeed->upload;
- resp_data->download = netspeed->download;
- strcpy(resp_data->name, netspeed->name);
- if (netspeed->display != NULL) {
- strcpy(resp_data->name + strlen(resp_data->name) + 1,
- netspeed->display);
- } else {
- strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
- }
- }
- _uicorectl_send_response(uictl, &resp, resp_data);
- if (resp_data != NULL) {
- qemu_free(resp_data);
- }
- break;
- }
-
- case AUI_UICTL_GET_NETDELAY:
- {
- UICtlRespHeader resp;
- UICtlGetNetDelayResp* resp_data = NULL;
- UICtlGetNetDelay* req = (UICtlGetNetDelay*)req_data;
-
- resp.resp_data_size = 0;
- resp.result = 0;
-
- if (req->index >= android_netdelays_count ||
- android_netdelays[req->index].name == NULL) {
- resp.result = -1;
- } else {
- const NetworkLatency* netdelay = &android_netdelays[req->index];
- // Calculate size of the response data:
- // fixed header + zero-terminated netdelay name.
- resp.resp_data_size = sizeof(UICtlGetNetDelayResp) +
- strlen(netdelay->name) + 1;
- // Count in zero-terminated netdelay display.
- if (netdelay->display != NULL) {
- resp.resp_data_size += strlen(netdelay->display) + 1;
- } else {
- resp.resp_data_size++;
- }
- // Allocate and initialize response data buffer.
- resp_data =
- (UICtlGetNetDelayResp*)qemu_malloc(resp.resp_data_size);
- resp_data->min_ms = netdelay->min_ms;
- resp_data->max_ms = netdelay->max_ms;
- strcpy(resp_data->name, netdelay->name);
- if (netdelay->display != NULL) {
- strcpy(resp_data->name + strlen(resp_data->name) + 1,
- netdelay->display);
- } else {
- strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
- }
- }
- _uicorectl_send_response(uictl, &resp, resp_data);
- if (resp_data != NULL) {
- qemu_free(resp_data);
- }
- break;
- }
-
- case AUI_UICTL_GET_QEMU_PATH:
- {
- UICtlRespHeader resp;
- UICtlGetQemuPath* req = (UICtlGetQemuPath*)req_data;
- char* filepath = NULL;
-
- resp.resp_data_size = 0;
- resp.result = -1;
- filepath = qemu_find_file(req->type, req->filename);
- if (filepath != NULL) {
- resp.resp_data_size = strlen(filepath) + 1;
- }
- _uicorectl_send_response(uictl, &resp, filepath);
- if (filepath != NULL) {
- qemu_free(filepath);
- }
- break;
- }
-
- default:
- derror("Unknown UI control request %d\n", req_header->msg_type);
- break;
- }
-}
-
-/* Asynchronous read I/O callback launched when reading UI control requests.
- */
-static void
-_uicorectl_io_read(UICoreCtl* uictl)
-{
- // Read whatever is expected from the socket.
- const AsyncStatus status =
- asyncReader_read(&uictl->async_reader, &uictl->io);
-
- switch (status) {
- case ASYNC_COMPLETE:
- switch (uictl->in_req_state) {
- case UI_STATE_EXPECT_HEADER:
- // We just read the request header. Now we expect the data.
- if (uictl->req_header.msg_data_size != 0) {
- uictl->in_req_state = UI_STATE_EXPECT_DATA;
- // Setup the reader to read expected amount of the data.
- _alloc_req_data_buffer(uictl,
- uictl->req_header.msg_data_size);
- asyncReader_init(&uictl->async_reader,
- uictl->req_data_buffer,
- uictl->req_header.msg_data_size,
- &uictl->io);
- } else {
- // Request doesn't contain data. Go ahead and handle it.
- _handle_uictl_request(uictl, &uictl->req_header,
- uictl->req_data_buffer);
- // Prepare for the next header.
- asyncReader_init(&uictl->async_reader,
- &uictl->req_header,
- sizeof(uictl->req_header), &uictl->io);
- }
- break;
-
- case UI_STATE_EXPECT_DATA:
- // Request header and data are received. Handle the request.
- _handle_uictl_request(uictl, &uictl->req_header,
- uictl->req_data_buffer);
- _free_req_data_buffer(uictl);
- // Prepare for the next request.
- uictl->in_req_state = UI_STATE_EXPECT_HEADER;
- asyncReader_init(&uictl->async_reader, &uictl->req_header,
- sizeof(uictl->req_header), &uictl->io);
- break;
- }
- break;
- case ASYNC_ERROR:
- loopIo_dontWantRead(&uictl->io);
- if (errno == ECONNRESET) {
- // UI has exited. We need to destroy the service.
- destroy_ui_core_ctl_client();
- }
- break;
-
- case ASYNC_NEED_MORE:
- // Transfer will eventually come back into this routine.
- return;
- }
-}
-
-/*
- * Asynchronous I/O callback launched when UI control is received from the UI.
- * Param:
- * opaque - UICoreCtl instance.
- */
-static void
-_uicorectl_io_func(void* opaque, int fd, unsigned events)
-{
- if (events & LOOP_IO_READ) {
- _uicorectl_io_read((UICoreCtl*)opaque);
- } else 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 _uicorectl_io_func\n");
- }
-}
-
-int
-uicorectl_create(int fd)
-{
- _ui_core_ctl.sock = fd;
- _ui_core_ctl.looper = looper_newCore();
- loopIo_init(&_ui_core_ctl.io, _ui_core_ctl.looper, _ui_core_ctl.sock,
- _uicorectl_io_func, &_ui_core_ctl);
- _ui_core_ctl.in_req_state = UI_STATE_EXPECT_HEADER;
- _ui_core_ctl.req_data_buffer = &_ui_core_ctl.req_data[0];
- asyncReader_init(&_ui_core_ctl.async_reader, &_ui_core_ctl.req_header,
- sizeof(_ui_core_ctl.req_header), &_ui_core_ctl.io);
- _ui_core_ctl.sync_writer = syncsocket_init(fd);
- if (_ui_core_ctl.sync_writer == NULL) {
- derror("Unable to create writer for UICoreCtl instance: %s\n", errno_str);
- return -1;
- }
- return 0;
-}
-
-void
-uicorectl_destroy()
-{
- if (_ui_core_ctl.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_ui_core_ctl.io);
- looper_free(_ui_core_ctl.looper);
- _ui_core_ctl.looper = NULL;
- }
- if (_ui_core_ctl.sync_writer != NULL) {
- syncsocket_close(_ui_core_ctl.sync_writer);
- syncsocket_free(_ui_core_ctl.sync_writer);
- }
- _free_req_data_buffer(&_ui_core_ctl);
-}
diff --git a/android/ui-ctl-core.h b/android/ui-ctl-core.h
deleted file mode 100644
index f7d7ecf..0000000
--- a/android/ui-ctl-core.h
+++ /dev/null
@@ -1,63 +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.
-*/
-
-#ifndef _ANDROID_UI_CONTROL_CORE_H
-#define _ANDROID_UI_CONTROL_CORE_H
-
-/*
- * Contains core-side of UI control protocols. For the simplicity of the
- * implementation there are two UI control services: "ui-core-control" that
- * handle UI controls initiated in the UI, and "core-ui-control" that handle UI
- * controls initiated in the core. The reason for hawing two services is that
- * some of the UI controls expect the core to respond with some data. The
- * simplest way to differentiate core commands from core responses to the UI
- * commands, is to have two separate services: one sends commands only, and
- * another sends only responses.
- */
-
-/*
- * Creates and initializes Core->UI UI control service.
- * Param:
- * fd - Socket descriptor for the service.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int coreuictl_create(int fd);
-
-/*
- * Destroys Core->UI UI control service.
- */
-extern void coreuictl_destroy();
-
-/* Changes the scale of the emulator window at runtime.
- * Param:
- * scale, is_dpi - New window scale parameters
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int coreuictl_set_window_scale(double scale, int is_dpi);
-
-/*
- * Creates and initializes UI->Core UI control instance.
- * Param:
- * fd - Socket descriptor for the service.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int uicorectl_create(int fd);
-
-/*
- * Destroys UI->Core UI control service.
- */
-extern void uicorectl_destroy();
-
-#endif /* _ANDROID_UI_CONTROL_CORE_H */
diff --git a/android/ui-ctl-ui.c b/android/ui-ctl-ui.c
deleted file mode 100644
index 47d0603..0000000
--- a/android/ui-ctl-ui.c
+++ /dev/null
@@ -1,568 +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 UI-side of UI control protocol.
- */
-
-#include "console.h"
-#include "android/android.h"
-#include "android/globals.h"
-#include "android/looper.h"
-#include "android/core-connection.h"
-#include "android/async-utils.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/sync-utils.h"
-#include "android/ui-ctl-common.h"
-#include "android/ui-ctl-ui.h"
-
-#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
- exit(1); \
- } while (0)
-
-
-/*
- * Enumerates states for the request reader in CoreUICtlClient instance.
- */
-typedef enum CoreUICtlClientState {
- /* The reader is waiting on request header. */
- WAIT_HEADER,
-
- /* The reader is waiting on request data. */
- WAIT_DATA,
-} CoreUICtlClientState;
-
-/* Common descriptor for UI control clients. */
-typedef struct UICtlCommon {
- /* Core connection instance for the UI control client. */
- CoreConnection* core_connection;
-
- /* Socket wrapper for sync writes. */
- SyncSocket* sync_writer;
-
- /* Socket descriptor for the UI control client. */
- int sock;
-} UICtlCommon;
-
-/* Descriptor for the Core->UI control client. */
-typedef struct CoreUICtlClient {
- /* Common UI control client descriptor. */
- UICtlCommon common;
-
- /* Current reader state. */
- CoreUICtlClientState reader_state;
-
- /* Incoming request header. */
- UICtlHeader req_header;
-
- /* Reader's buffer. */
- uint8_t* reader_buffer;
-
- /* Offset in the reader's buffer where to read next chunk of data. */
- size_t reader_offset;
-
- /* Total number of bytes the reader expects to read. */
- size_t reader_bytes;
-} CoreUICtlClient;
-
-/* Descriptor for the UI->Core control client. */
-typedef struct UICoreCtlClient {
- /* Common UI control client descriptor. */
- UICtlCommon common;
-
- /* Socket wrapper for sync reads. */
- SyncSocket* sync_reader;
-} UICoreCtlClient;
-
-/* One and only one Core->UI control client instance. */
-static CoreUICtlClient _core_ui_client;
-
-/* One and only one UI->Core control client instance. */
-static UICoreCtlClient _ui_core_client;
-
-/* Calculates timeout for transferring the given number of bytes via UI control
- * socket.
- * Return:
- * Number of milliseconds during which the entire number of bytes is expected
- * to be transferred.
- */
-static int
-_get_transfer_timeout(size_t data_size)
-{
- // Min 200 millisec + one millisec for each transferring byte.
- // TODO: Come up with a better arithmetics here.
- return 200 + data_size;
-}
-
-/* Initializes UICtlCommon instance.
- * Param:
- * console_socket - Addresses core's console service.
- * name - Name of the core's service to attach to ("ui-core client",
- * or "core-ui client").
- * uictl_common - UICtlCommon instance to initialize.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_clientuictl_create_client(SockAddress* console_socket,
- char* name,
- UICtlCommon* uictl_common)
-{
- char* connect_message = NULL;
- char switch_cmd[256];
-
- // Connect to the console service.
- uictl_common->core_connection = core_connection_create(console_socket);
- if (uictl_common->core_connection == NULL) {
- derror("UI control client %s is unable to connect to the console: %s\n",
- name, errno_str);
- return -1;
- }
- if (core_connection_open(uictl_common->core_connection)) {
- core_connection_free(uictl_common->core_connection);
- uictl_common->core_connection = NULL;
- derror("UI control client %s is unable to open the console: %s\n",
- name, errno_str);
- return -1;
- }
- snprintf(switch_cmd, sizeof(switch_cmd), "%s", name);
- if (core_connection_switch_stream(uictl_common->core_connection, switch_cmd,
- &connect_message)) {
- derror("Unable to connect to the UI control service %s: %s\n",
- name, connect_message ? connect_message : "");
- if (connect_message != NULL) {
- free(connect_message);
- }
- core_connection_close(uictl_common->core_connection);
- core_connection_free(uictl_common->core_connection);
- uictl_common->core_connection = NULL;
- return -1;
- }
- if (connect_message != NULL) {
- free(connect_message);
- }
-
- // Initialize UICtlCommon instance.
- uictl_common->sock = core_connection_get_socket(uictl_common->core_connection);
- uictl_common->sync_writer = syncsocket_init(uictl_common->sock);
- if (uictl_common->sync_writer == NULL) {
- derror("Unable to initialize sync writer for %s UI control client: %s\n",
- name, errno_str);
- return -1;
- }
- return 0;
-}
-
-/* Destroys UICtlCommon instance. */
-static void
-_uictlcommon_destroy(UICtlCommon* desc)
-{
- if (desc->core_connection != NULL) {
- // Disable I/O callbacks.
- qemu_set_fd_handler(desc->sock, NULL, NULL, NULL);
- syncsocket_close(desc->sync_writer);
- syncsocket_free(desc->sync_writer);
- core_connection_close(desc->core_connection);
- core_connection_free(desc->core_connection);
- desc->core_connection = NULL;
- }
-}
-
-/*
- * Core->UI control client implementation.
- */
-
-/* Implemented in android/qemulator.c */
-extern void android_emulator_set_window_scale( double scale, int is_dpi );
-
-/* Destroys CoreUICtlClient instance. */
-static void
-_core_ui_client_destroy()
-{
- _uictlcommon_destroy(&_core_ui_client.common);
- if (_core_ui_client.reader_buffer != NULL &&
- _core_ui_client.reader_buffer != (uint8_t*)&_core_ui_client.req_header) {
- free(_core_ui_client.reader_buffer);
- }
-}
-
-/*
- * Handles UI control request received from the core.
- * Param:
- * uictl - CoreUICtlClient instance that received the request.
- * header - UI control request header.
- * data - Request data formatted accordingly to the request type.
- */
-static void
-_core_ui_ctl_handle_request(CoreUICtlClient* uictl,
- UICtlHeader* header,
- uint8_t* data)
-{
- switch (header->msg_type) {
- case ACORE_UICTL_SET_WINDOWS_SCALE:
- {
- UICtlSetWindowsScale* req = (UICtlSetWindowsScale*)data;
- android_emulator_set_window_scale(req->scale, req->is_dpi);
- break;
- }
- default:
- derror("Unknown Core UI control %d\n", header->msg_type);
- break;
- }
-}
-
-/*
- * Asynchronous I/O callback launched when UI control requests received from the
- * core are ready to be read.
- * Param:
- * opaque - CoreUICtlClient instance.
- */
-static void
-_core_ui_client_read_cb(void* opaque)
-{
- CoreUICtlClient* uictl = opaque;
- int ret;
-
- // Read requests while they are immediately available.
- for (;;) {
- // Read next chunk of data.
- ret = read(uictl->common.sock,
- uictl->reader_buffer + uictl->reader_offset,
- uictl->reader_bytes - uictl->reader_offset);
- if (ret == 0) {
- /* disconnection ! */
- _core_ui_client_destroy();
- return;
- }
- if (ret < 0) {
- if (errno == EINTR) {
- /* loop on EINTR */
- continue;
- } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
- // Chunk is not avalable at this point. Come back later.
- return;
- }
- }
-
- uictl->reader_offset += ret;
- if (uictl->reader_offset != uictl->reader_bytes) {
- // There are still some data left in the pipe.
- continue;
- }
-
- // All expected data has been read. Time to change the state.
- if (uictl->reader_state == WAIT_HEADER) {
- // Header has been read. Prepare for the data.
- uictl->reader_state = WAIT_DATA;
- uictl->reader_offset = 0;
- uictl->reader_bytes = uictl->req_header.msg_data_size;
- uictl->reader_buffer = malloc(uictl->reader_bytes);
- if (uictl->reader_buffer == NULL) {
- PANIC("Unable to allocate memory for UI control request.\n");
- }
- } else {
- _core_ui_ctl_handle_request(uictl, &uictl->req_header,
- uictl->reader_buffer);
- free(uictl->reader_buffer);
- uictl->reader_state = WAIT_HEADER;
- uictl->reader_offset = 0;
- uictl->reader_bytes = sizeof(uictl->req_header);
- uictl->reader_buffer = (uint8_t*)&uictl->req_header;
- }
- }
-}
-
-/*
- * UI->Core control client implementation.
- */
-
-/* Sends UI request to the core.
- * Param:
- * msg_type, msg_data, msg_data_size - Define the request.
- * Return:
- * 0 On success, or < 0 on failure.
- */
-static int
-_ui_core_ctl_send_request(uint8_t msg_type,
- void* msg_data,
- uint32_t msg_data_size)
-{
- int status;
- UICtlHeader header;
-
- // Prepare and send the header.
- header.msg_type = msg_type;
- header.msg_data_size = msg_data_size;
- status = syncsocket_start_write(_ui_core_client.common.sync_writer);
- if (!status) {
- // Send the header.
- status = syncsocket_write(_ui_core_client.common.sync_writer, &header,
- sizeof(header),
- _get_transfer_timeout(sizeof(header)));
- // If there is request data, send it too.
- if (status > 0 && msg_data != NULL && msg_data_size > 0) {
- status = syncsocket_write(_ui_core_client.common.sync_writer, msg_data,
- msg_data_size,
- _get_transfer_timeout(msg_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(_ui_core_client.common.sync_writer);
- }
- if (status < 0) {
- derror("Unable to send UI control request: %s\n", errno_str);
- }
- return status;
-}
-
-/* Reads response to a UI control request from the core.
- * Param:
- * resp - Upon success contains response header.
- * resp_data - Upon success contains allocated reponse data (if any). The caller
- * is responsible for deallocating of the memory returned in this parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_ui_core_ctl_get_response(UICtlRespHeader* resp, void** resp_data)
-{
- int status = syncsocket_start_read(_ui_core_client.sync_reader);
- if (!status) {
- // Read the header.
- status = syncsocket_read(_ui_core_client.sync_reader, resp,
- sizeof(UICtlRespHeader),
- _get_transfer_timeout(sizeof(UICtlRespHeader)));
- // Read response data (if any).
- if (status > 0 && resp->resp_data_size) {
- *resp_data = malloc(resp->resp_data_size);
- if (*resp_data == NULL) {
- PANIC("Unable to allocate response data buffer\n");
- }
- status = syncsocket_read(_ui_core_client.sync_reader, *resp_data,
- resp->resp_data_size,
- _get_transfer_timeout(resp->resp_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_read(_ui_core_client.sync_reader);
- }
- if (status < 0) {
- derror("Unable to get UI control response: %s\n", errno_str);
- }
- return status;
-}
-
-int
-clientuictl_set_coarse_orientation(AndroidCoarseOrientation orient)
-{
- UICtlSetCoarseOrientation msg;
- msg.orient = orient;
- return _ui_core_ctl_send_request(AUI_UICTL_SET_COARSE_ORIENTATION,
- &msg, sizeof(msg));
-}
-
-int
-clientuictl_toggle_network()
-{
- return _ui_core_ctl_send_request(AUI_UICTL_TOGGLE_NETWORK, NULL, 0);
-}
-
-int
-clientuictl_trace_control(int start)
-{
- UICtlTraceControl msg;
- msg.start = start;
- return _ui_core_ctl_send_request(AUI_UICTL_TRACE_CONTROL,
- &msg, sizeof(msg));
-}
-
-int
-clientuictl_check_network_disabled()
-{
- UICtlRespHeader resp;
- void* tmp = NULL;
- int status;
-
- status = _ui_core_ctl_send_request(AUI_UICTL_CHK_NETWORK_DISABLED, NULL, 0);
- if (status < 0) {
- return status;
- }
- status = _ui_core_ctl_get_response(&resp, &tmp);
- if (status < 0) {
- return status;
- }
- return resp.result;
-}
-
-int
-clientuictl_get_netspeed(int index, NetworkSpeed** netspeed)
-{
- UICtlGetNetSpeed req;
- UICtlRespHeader resp;
- UICtlGetNetSpeedResp* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- req.index = index;
- status = _ui_core_ctl_send_request(AUI_UICTL_GET_NETSPEED, &req, sizeof(req));
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _ui_core_ctl_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result) {
- NetworkSpeed* ret;
- // Allocate memory for the returning NetworkSpeed instance.
- // It includes: NetworkSpeed structure +
- // size of zero-terminated "name" and "display" strings saved in
- // resp_data.
- *netspeed = malloc(sizeof(NetworkSpeed) + 1 +
- resp.resp_data_size - sizeof(UICtlGetNetSpeedResp));
- ret = *netspeed;
-
- // Copy data obtained from the core to the returning NetworkSpeed
- // instance.
- ret->upload = resp_data->upload;
- ret->download = resp_data->download;
- ret->name = (char*)ret + sizeof(NetworkSpeed);
- strcpy((char*)ret->name, resp_data->name);
- ret->display = ret->name + strlen(ret->name) + 1;
- strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-clientuictl_get_netdelay(int index, NetworkLatency** netdelay)
-{
- UICtlGetNetDelay req;
- UICtlRespHeader resp;
- UICtlGetNetDelayResp* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- req.index = index;
- status = _ui_core_ctl_send_request(AUI_UICTL_GET_NETDELAY, &req, sizeof(req));
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _ui_core_ctl_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result) {
- NetworkLatency* ret;
- // Allocate memory for the returning NetworkLatency instance.
- // It includes: NetworkLatency structure +
- // size of zero-terminated "name" and "display" strings saved in
- // resp_data.
- *netdelay = malloc(sizeof(NetworkLatency) + 1 +
- resp.resp_data_size - sizeof(UICtlGetNetDelayResp));
- ret = *netdelay;
-
- // Copy data obtained from the core to the returning NetworkLatency
- // instance.
- ret->min_ms = resp_data->min_ms;
- ret->max_ms = resp_data->max_ms;
- ret->name = (char*)ret + sizeof(NetworkLatency);
- strcpy((char*)ret->name, resp_data->name);
- ret->display = ret->name + strlen(ret->name) + 1;
- strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-clientuictl_get_qemu_path(int type, const char* filename, char** path)
-{
- UICtlRespHeader resp;
- char* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- uint32_t req_data_size = sizeof(UICtlGetQemuPath) + strlen(filename) + 1;
- UICtlGetQemuPath* req = (UICtlGetQemuPath*)malloc(req_data_size);
- if (req == NULL) {
- PANIC("Unable to allocate query qemu path request\n");
- }
- req->type = type;
- strcpy(req->filename, filename);
- status = _ui_core_ctl_send_request(AUI_UICTL_GET_QEMU_PATH, req,
- req_data_size);
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _ui_core_ctl_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result && resp_data != NULL) {
- *path = strdup(resp_data);
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-clientuictl_create(SockAddress* console_socket)
-{
- // Connect to Core->UI service
- if (_clientuictl_create_client(console_socket, "core-ui-control",
- &_core_ui_client.common)) {
- return -1;
- }
- _core_ui_client.reader_state = WAIT_HEADER;
- if (qemu_set_fd_handler(_core_ui_client.common.sock, _core_ui_client_read_cb,
- NULL, &_core_ui_client)) {
- derror("Unable to set up UI control read callback\n");
- core_connection_close(_core_ui_client.common.core_connection);
- core_connection_free(_core_ui_client.common.core_connection);
- _core_ui_client.common.core_connection = NULL;
- return -1;
- }
- fprintf(stdout, "Core->UI client is now attached to the core %s\n",
- sock_address_to_string(console_socket));
-
- // Connect to UI->Core service
- if (_clientuictl_create_client(console_socket, "ui-core-control",
- &_ui_core_client.common)) {
- _core_ui_client_destroy();
- return -1;
- }
- _ui_core_client.sync_reader = syncsocket_init(_ui_core_client.common.sock);
- if (_ui_core_client.sync_reader == NULL) {
- derror("Unable to create reader for CoreUICtlClient instance: %s\n",
- errno_str);
- _core_ui_client_destroy();
- return -1;
- }
-
- fprintf(stdout, "UI->Core client is now attached to the core %s\n",
- sock_address_to_string(console_socket));
-
- return 0;
-}
diff --git a/android/ui-ctl-ui.h b/android/ui-ctl-ui.h
deleted file mode 100644
index 4359ba1..0000000
--- a/android/ui-ctl-ui.h
+++ /dev/null
@@ -1,108 +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.
-*/
-
-#ifndef _ANDROID_UI_CONTROL_UI_H
-#define _ANDROID_UI_CONTROL_UI_H
-
-/*
- * Contains UI-side of UI control protocols. For the simplicity of implementation
- * there are two UI control services: "ui-core-control" that handle UI controls
- * initiated in the UI, and "core-ui-control" that handle UI controls initiated
- * in the core. The reason for hawing two services is that some of the UI
- * controls expect the core to respond with some data. The simplest way to
- * differentiate core commands from core responses to the UI commands, is to have
- * two separate services: one sends commands only, and another sends only
- * responses.
- */
-
-#include "sockets.h"
-#include "android/ui-ctl-common.h"
-
-/* Establishes connection with UI control services in the core.
- * Param:
- * console_socket Core's console socket.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_create(SockAddress* console_socket);
-
-/*
- * UI->Core API
- */
-
-/* Sends AUI_UICTL_SET_COARSE_ORIENTATION message to the core.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_set_coarse_orientation(AndroidCoarseOrientation orient);
-
-/* Sends AUI_UICTL_TOGGLE_NETWORK message to the core.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_toggle_network();
-
-/* Sends AUI_UICTL_TRACE_CONTROL message to the core.
- * Param:
- * start - Starts (> 0), or stops (== 0) tracing.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_trace_control(int start);
-
-/* Sends AUI_UICTL_CHK_NETWORK_DISABLED message to the core.
- * Return:
- * 0 if network is enabled, 1 if it is disabled, or < 0 on failure.
- */
-int clientuictl_check_network_disabled();
-
-/* Sends AUI_UICTL_GET_NETSPEED message to the core.
- * Param:
- * index - Index of an entry in the NetworkSpeed array.
- * netspeed - Upon success contains allocated and initialized NetworkSpeed
- * instance for the given index. Note that strings addressed by "name" and
- * "display" fileds in the returned NetworkSpeed instance are containd inside
- * the buffer allocated for the returned NetworkSpeed instance. Caller of this
- * routine must eventually free the buffer returned in this parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_get_netspeed(int index, NetworkSpeed** netspeed);
-
-/* Sends AUI_UICTL_GET_NETDELAY message to the core.
- * Param:
- * index - Index of an entry in the NetworkLatency array.
- * netdelay - Upon success contains allocated and initialized NetworkLatency
- * instance for the given index. Note that strings addressed by "name" and
- * "display" fileds in the returned NetworkLatency instance are containd inside
- * the buffer allocated for the returned NetworkLatency instance. Caller of this
- * routine must eventually free the buffer returned in this parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_get_netdelay(int index, NetworkLatency** netdelay);
-
-/* Sends AUI_UICTL_GET_QEMU_PATH message to the core.
- * Param:
- * type, filename - Query parameters
- * netdelay - Upon success contains allocated and initialized NetworkLatency
- * instance for the given index. Note that strings addressed by "name" and
- * "display" fileds in the returned NetworkLatency instance are containd inside
- * the buffer allocated for the returned NetworkLatency instance. Caller of this
- * routine must eventually free the buffer returned in this parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int clientuictl_get_qemu_path(int type, const char* filename, char** path);
-
-#endif /* _ANDROID_UI_CONTROL_UI_H */
-