From bdb6f2dd35a4c749186e665d55d7b76375d7e71d Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Wed, 23 Feb 2011 15:57:25 +0100 Subject: Remove android/main-ui.c The differences between android/main.c and android/main-ui.c are now minimal, so remove the latter source file by moving the corresponding code into android/main-common.c Also add a -snapshot-no-time-update core option to implement the emulator-ui -no-snapshot-update-time option. We're probably going to clean this up a little in the future, but this is enough for now. Change-Id: I868bb4e47c3d106ae7436ee3f5b2c0ff5fb6ea5c --- Makefile.android | 2 +- android/main-common.c | 239 +++++++++++ android/main-common.h | 10 + android/main-ui.c | 1094 ------------------------------------------------- android/main.c | 32 +- qemu-options.hx | 3 + vl-android.c | 5 + 7 files changed, 278 insertions(+), 1107 deletions(-) delete mode 100644 android/main-ui.c diff --git a/Makefile.android b/Makefile.android index 1b44140..a6dd83a 100644 --- a/Makefile.android +++ b/Makefile.android @@ -1288,7 +1288,7 @@ VL_SOURCES := android/framebuffer.c \ android/looper-generic.c \ android/snapshot.c \ android/main-common.c \ - android/main-ui.c \ + android/main.c \ vl-android-ui.c \ iolooper-select.c \ android/protocol/core-connection.c \ diff --git a/android/main-common.c b/android/main-common.c index 2a73808..5987f55 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -1089,3 +1089,242 @@ updateHwConfigFromAVD(AndroidHwConfig* hwConfig, } } } + + + +#ifdef CONFIG_STANDALONE_UI + +#include "android/protocol/core-connection.h" +#include "android/protocol/fb-updates-impl.h" +#include "android/protocol/user-events-proxy.h" +#include "android/protocol/core-commands-proxy.h" +#include "android/protocol/ui-commands-impl.h" +#include "android/protocol/attach-ui-impl.h" + +/* Emulator's core port. */ +int android_base_port = 0; + +// Base console port +#define CORE_BASE_PORT 5554 + +// Maximum number of core porocesses running simultaneously on a machine. +#define MAX_CORE_PROCS 16 + +// Socket timeout in millisec (set to 5 seconds) +#define CORE_PORT_TIMEOUT_MS 5000 + +#include "android/async-console.h" + +typedef struct { + LoopIo io[1]; + int port; + int ok; + AsyncConsoleConnector connector[1]; +} CoreConsole; + +static void +coreconsole_io_func(void* opaque, int fd, unsigned events) +{ + CoreConsole* cc = opaque; + AsyncStatus status; + status = asyncConsoleConnector_run(cc->connector, cc->io); + if (status == ASYNC_COMPLETE) { + cc->ok = 1; + } +} + +static void +coreconsole_init(CoreConsole* cc, const SockAddress* address, Looper* looper) +{ + int fd = socket_create_inet(SOCKET_STREAM); + AsyncStatus status; + cc->port = sock_address_get_port(address); + cc->ok = 0; + loopIo_init(cc->io, looper, fd, coreconsole_io_func, cc); + if (fd >= 0) { + status = asyncConsoleConnector_connect(cc->connector, address, cc->io); + if (status == ASYNC_ERROR) { + cc->ok = 0; + } + } +} + +static void +coreconsole_done(CoreConsole* cc) +{ + socket_close(cc->io->fd); + loopIo_done(cc->io); +} + +/* List emulator core processes running on the given machine. + * This routine is called from main() if -list-cores parameter is set in the + * command line. + * Param: + * host Value passed with -list-core parameter. Must be either "localhost", or + * an IP address of a machine where core processes must be enumerated. + */ +static void +list_running_cores(const char* host) +{ + Looper* looper; + CoreConsole cores[MAX_CORE_PROCS]; + SockAddress address; + int nn, found; + + if (sock_address_init_resolve(&address, host, CORE_BASE_PORT, 0) < 0) { + derror("Unable to resolve hostname %s: %s", host, errno_str); + return; + } + + looper = looper_newGeneric(); + + for (nn = 0; nn < MAX_CORE_PROCS; nn++) { + int port = CORE_BASE_PORT + nn*2; + sock_address_set_port(&address, port); + coreconsole_init(&cores[nn], &address, looper); + } + + looper_runWithTimeout(looper, CORE_PORT_TIMEOUT_MS*2); + + found = 0; + for (nn = 0; nn < MAX_CORE_PROCS; nn++) { + int port = CORE_BASE_PORT + nn*2; + if (cores[nn].ok) { + if (found == 0) { + fprintf(stdout, "Running emulator core processes:\n"); + } + fprintf(stdout, "Emulator console port %d\n", port); + found++; + } + coreconsole_done(&cores[nn]); + } + looper_free(looper); + + if (found == 0) { + fprintf(stdout, "There were no running emulator core processes found on %s.\n", + host); + } +} + +/* Attaches starting UI to a running core process. + * This routine is called from main() when -attach-core parameter is set, + * indicating that this UI instance should attach to a running core, rather than + * start a new core process. + * Param: + * opts Android options containing non-NULL attach_core. + * Return: + * 0 on success, or -1 on failure. + */ +static int +attach_to_core(AndroidOptions* opts) { + int iter; + SockAddress console_socket; + SockAddress** sockaddr_list; + QEmulator* emulator; + + // Parse attach_core param extracting the host name, and the port name. + char* console_address = strdup(opts->attach_core); + char* host_name = console_address; + char* port_num = strchr(console_address, ':'); + if (port_num == NULL) { + // The host name is ommited, indicating the localhost + host_name = "localhost"; + port_num = console_address; + } else if (port_num == console_address) { + // Invalid. + derror("Invalid value %s for -attach-core parameter\n", + opts->attach_core); + return -1; + } else { + *port_num = '\0'; + port_num++; + if (*port_num == '\0') { + // Invalid. + derror("Invalid value %s for -attach-core parameter\n", + opts->attach_core); + return -1; + } + } + + /* Create socket address list for the given address, and pull appropriate + * address to use for connection. Note that we're fine copying that address + * out of the list, since INET and IN6 will entirely fit into SockAddress + * structure. */ + sockaddr_list = + sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET); + free(console_address); + if (sockaddr_list == NULL) { + derror("Unable to resolve address %s: %s\n", + opts->attach_core, errno_str); + return -1; + } + for (iter = 0; sockaddr_list[iter] != NULL; iter++) { + if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET || + sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) { + memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress)); + break; + } + } + if (sockaddr_list[iter] == NULL) { + derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n" + "must be resolvable into an IP address.\n", opts->attach_core); + sock_address_list_free(sockaddr_list); + return -1; + } + sock_address_list_free(sockaddr_list); + + if (attachUiImpl_create(&console_socket)) { + return -1; + } + + // Save core's port, and set the title. + android_base_port = sock_address_get_port(&console_socket); + emulator = qemulator_get(); + qemulator_set_title(emulator); + + return 0; +} + + +void handle_ui_options( AndroidOptions* opts ) +{ + // Lets see if user just wants to list core process. + if (opts->list_cores) { + fprintf(stdout, "Enumerating running core processes.\n"); + list_running_cores(opts->list_cores); + exit(0); + } +} + +int attach_ui_to_core( AndroidOptions* opts ) +{ + // Lets see if we're attaching to a running core process here. + if (opts->attach_core) { + if (attach_to_core(opts)) { + return -1; + } + // Connect to the core's UI control services. + if (coreCmdProxy_create(attachUiImpl_get_console_socket())) { + return -1; + } + // Connect to the core's user events service. + if (userEventsProxy_create(attachUiImpl_get_console_socket())) { + return -1; + } + } + return 0; +} + +#else /* !CONFIG_STANDALONE_UI */ + +void handle_ui_options( AndroidOptions* opts ) +{ + return; +} + +int attach_ui_to_core( AndroidOptions* opts ) +{ + return 0; +} + +#endif /* CONFIG_STANDALONE_UI */ diff --git a/android/main-common.h b/android/main-common.h index 102d4e4..c26b9b9 100644 --- a/android/main-common.h +++ b/android/main-common.h @@ -78,4 +78,14 @@ struct AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild); void updateHwConfigFromAVD(AndroidHwConfig* hwConfig, struct AvdInfo* avd, AndroidOptions* opts, int inAndroidBuild); +/* Called from android/main.c to handle options specific to the standalone + * UI program. This is a no-op otherwise. + */ +void handle_ui_options( AndroidOptions* opts ); + +/* Called from android/main.c to potentially attach to a core from the + * standalone UI program. This is a no-op otherwise. + */ +int attach_ui_to_core( AndroidOptions* opts ); + #endif /* ANDROID_MAIN_COMMON_H */ diff --git a/android/main-ui.c b/android/main-ui.c deleted file mode 100644 index e9973b0..0000000 --- a/android/main-ui.c +++ /dev/null @@ -1,1094 +0,0 @@ -/* Copyright (C) 2006-2008 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 -#include -#include -#include -#ifdef _WIN32 -#include -#endif - -#include "sockets.h" - -#include "android/android.h" -#include "qemu-common.h" -#include "sysemu.h" -#include "console.h" -#include "user-events.h" - -#include -#include - -#include "math.h" - -#include "android/charmap.h" -#include "android/utils/debug.h" -#include "android/config.h" -#include "android/config/config.h" - -#include "android/user-config.h" -#include "android/utils/bufprint.h" -#include "android/utils/path.h" -#include "android/utils/tempfile.h" - -#include "android/main-common.h" -#include "android/help.h" -#include "hw/goldfish_nand.h" - -#include "android/globals.h" - -#include "android/qemulator.h" -#include "android/display.h" - -#include "android/snapshot.h" -#include "android/protocol/core-connection.h" -#include "android/protocol/fb-updates-impl.h" -#include "android/protocol/user-events-proxy.h" -#include "android/protocol/core-commands-proxy.h" -#include "android/protocol/ui-commands-impl.h" -#include "android/protocol/attach-ui-impl.h" - -#include "android/framebuffer.h" -#include "iolooper.h" - -AndroidRotation android_framebuffer_rotation; - -#define STRINGIFY(x) _STRINGIFY(x) -#define _STRINGIFY(x) #x - -#ifdef ANDROID_SDK_TOOLS_REVISION -# define VERSION_STRING STRINGIFY(ANDROID_SDK_TOOLS_REVISION)".0" -#else -# define VERSION_STRING "standalone" -#endif - -#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0) - -extern int control_console_start( int port ); /* in control.c */ - -extern int qemu_milli_needed; - -/* the default device DPI if none is specified by the skin - */ -#define DEFAULT_DEVICE_DPI 165 - -#if 0 -static int opts->flashkeys; /* forward */ -#endif - -#ifdef CONFIG_TRACE -extern void start_tracing(void); -extern void stop_tracing(void); -#endif - -unsigned long android_verbose; - -/* -ui-settings parameters received from the core on UI attachment. */ -char* core_ui_settings = ""; - -/* Emulator's core port. */ -int android_base_port = 0; - -/* this is used by hw/events_device.c to send the charmap name to the system */ -extern const char* android_skin_keycharmap; - - -int qemu_main(int argc, char **argv); - -/* this function dumps the QEMU help */ -extern void help( void ); -extern void emulator_help( void ); - -#define VERBOSE_OPT(str,var) { str, &var } - -#define _VERBOSE_TAG(x,y) { #x, VERBOSE_##x, y }, -static const struct { const char* name; int flag; const char* text; } -verbose_options[] = { - VERBOSE_TAG_LIST - { 0, 0, 0 } -}; - -void emulator_help( void ) -{ - STRALLOC_DEFINE(out); - android_help_main(out); - printf( "%.*s", out->n, out->s ); - stralloc_reset(out); - exit(1); -} - -// Base console port -#define CORE_BASE_PORT 5554 - -// Maximum number of core porocesses running simultaneously on a machine. -#define MAX_CORE_PROCS 16 - -// Socket timeout in millisec (set to 5 seconds) -#define CORE_PORT_TIMEOUT_MS 5000 - -#include "android/async-console.h" - -typedef struct { - LoopIo io[1]; - int port; - int ok; - AsyncConsoleConnector connector[1]; -} CoreConsole; - -static void -coreconsole_io_func(void* opaque, int fd, unsigned events) -{ - CoreConsole* cc = opaque; - AsyncStatus status; - status = asyncConsoleConnector_run(cc->connector, cc->io); - if (status == ASYNC_COMPLETE) { - cc->ok = 1; - } -} - -static void -coreconsole_init(CoreConsole* cc, const SockAddress* address, Looper* looper) -{ - int fd = socket_create_inet(SOCKET_STREAM); - AsyncStatus status; - cc->port = sock_address_get_port(address); - cc->ok = 0; - loopIo_init(cc->io, looper, fd, coreconsole_io_func, cc); - if (fd >= 0) { - status = asyncConsoleConnector_connect(cc->connector, address, cc->io); - if (status == ASYNC_ERROR) { - cc->ok = 0; - } - } -} - -static void -coreconsole_done(CoreConsole* cc) -{ - socket_close(cc->io->fd); - loopIo_done(cc->io); -} - -/* List emulator core processes running on the given machine. - * This routine is called from main() if -list-cores parameter is set in the - * command line. - * Param: - * host Value passed with -list-core parameter. Must be either "localhost", or - * an IP address of a machine where core processes must be enumerated. - */ -static void -list_running_cores(const char* host) -{ - Looper* looper; - CoreConsole cores[MAX_CORE_PROCS]; - SockAddress address; - int nn, found; - - if (sock_address_init_resolve(&address, host, CORE_BASE_PORT, 0) < 0) { - derror("Unable to resolve hostname %s: %s", host, errno_str); - return; - } - - looper = looper_newGeneric(); - - for (nn = 0; nn < MAX_CORE_PROCS; nn++) { - int port = CORE_BASE_PORT + nn*2; - sock_address_set_port(&address, port); - coreconsole_init(&cores[nn], &address, looper); - } - - looper_runWithTimeout(looper, CORE_PORT_TIMEOUT_MS*2); - - found = 0; - for (nn = 0; nn < MAX_CORE_PROCS; nn++) { - int port = CORE_BASE_PORT + nn*2; - if (cores[nn].ok) { - if (found == 0) { - fprintf(stdout, "Running emulator core processes:\n"); - } - fprintf(stdout, "Emulator console port %d\n", port); - found++; - } - coreconsole_done(&cores[nn]); - } - looper_free(looper); - - if (found == 0) { - fprintf(stdout, "There were no running emulator core processes found on %s.\n", - host); - } -} - -/* Attaches starting UI to a running core process. - * This routine is called from main() when -attach-core parameter is set, - * indicating that this UI instance should attach to a running core, rather than - * start a new core process. - * Param: - * opts Android options containing non-NULL attach_core. - * Return: - * 0 on success, or -1 on failure. - */ -static int -attach_to_core(AndroidOptions* opts) { - int iter; - SockAddress console_socket; - SockAddress** sockaddr_list; - QEmulator* emulator; - - // Parse attach_core param extracting the host name, and the port name. - char* console_address = strdup(opts->attach_core); - char* host_name = console_address; - char* port_num = strchr(console_address, ':'); - if (port_num == NULL) { - // The host name is ommited, indicating the localhost - host_name = "localhost"; - port_num = console_address; - } else if (port_num == console_address) { - // Invalid. - derror("Invalid value %s for -attach-core parameter\n", - opts->attach_core); - return -1; - } else { - *port_num = '\0'; - port_num++; - if (*port_num == '\0') { - // Invalid. - derror("Invalid value %s for -attach-core parameter\n", - opts->attach_core); - return -1; - } - } - - /* Create socket address list for the given address, and pull appropriate - * address to use for connection. Note that we're fine copying that address - * out of the list, since INET and IN6 will entirely fit into SockAddress - * structure. */ - sockaddr_list = - sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET); - free(console_address); - if (sockaddr_list == NULL) { - derror("Unable to resolve address %s: %s\n", - opts->attach_core, errno_str); - return -1; - } - for (iter = 0; sockaddr_list[iter] != NULL; iter++) { - if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET || - sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) { - memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress)); - break; - } - } - if (sockaddr_list[iter] == NULL) { - derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n" - "must be resolvable into an IP address.\n", opts->attach_core); - sock_address_list_free(sockaddr_list); - return -1; - } - sock_address_list_free(sockaddr_list); - - if (attachUiImpl_create(&console_socket)) { - return -1; - } - - // Save core's port, and set the title. - android_base_port = sock_address_get_port(&console_socket); - emulator = qemulator_get(); - qemulator_set_title(emulator); - - return 0; -} - -int main(int argc, char **argv) -{ - char tmp[MAX_PATH]; - char* tmpend = tmp + sizeof(tmp); - char* args[128]; - int n; - char* opt; - int use_sdcard_img = 0; - int serial = 0; - int gps_serial = 0; - int radio_serial = 0; - int qemud_serial = 0; - int shell_serial = 0; - unsigned cachePartitionSize = 0; - - AndroidHwConfig* hw; - AvdInfo* avd; - AConfig* skinConfig; - char* skinPath; - int inAndroidBuild; - - AndroidOptions opts[1]; - /* net.shared_net_ip boot property value. */ - char boot_prop_ip[64]; - boot_prop_ip[0] = '\0'; - - args[0] = argv[0]; - - if ( android_parse_options( &argc, &argv, opts ) < 0 ) { - exit(1); - } - -#ifdef _WIN32 - socket_init(); -#endif - - // Lets see if user just wants to list core process. - if (opts->list_cores) { - fprintf(stdout, "Enumerating running core processes.\n"); - list_running_cores(opts->list_cores); - exit(0); - } - - while (argc-- > 1) { - opt = (++argv)[0]; - - if(!strcmp(opt, "-qemu")) { - argc--; - argv++; - break; - } - - if (!strcmp(opt, "-help")) { - emulator_help(); - } - - if (!strncmp(opt, "-help-",6)) { - STRALLOC_DEFINE(out); - opt += 6; - - if (!strcmp(opt, "all")) { - android_help_all(out); - } - else if (android_help_for_option(opt, out) == 0) { - /* ok */ - } - else if (android_help_for_topic(opt, out) == 0) { - /* ok */ - } - if (out->n > 0) { - printf("\n%.*s", out->n, out->s); - exit(0); - } - - fprintf(stderr, "unknown option: -help-%s\n", opt); - fprintf(stderr, "please use -help for a list of valid topics\n"); - exit(1); - } - - if (opt[0] == '-') { - fprintf(stderr, "unknown option: %s\n", opt); - fprintf(stderr, "please use -help for a list of valid options\n"); - exit(1); - } - - fprintf(stderr, "invalid command-line parameter: %s.\n", opt); - fprintf(stderr, "Hint: use '@foo' to launch a virtual device named 'foo'.\n"); - fprintf(stderr, "please use -help for more information\n"); - exit(1); - } - - if (opts->version) { - printf("Android emulator version %s\n" - "Copyright (C) 2006-2008 The Android Open Source Project and many others.\n" - "This program is a derivative of the QEMU CPU emulator (www.qemu.org).\n\n", -#if defined ANDROID_BUILD_ID - VERSION_STRING " (build_id " STRINGIFY(ANDROID_BUILD_ID) ")" ); -#else - VERSION_STRING); -#endif - printf(" This software is licensed under the terms of the GNU General Public\n" - " License version 2, as published by the Free Software Foundation, and\n" - " may be copied, distributed, and modified under those terms.\n\n" - " This program is distributed in the hope that it will be useful,\n" - " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - " GNU General Public License for more details.\n\n"); - - exit(0); - } - - /* Initialization of UI started with -attach-core should work differently - * than initialization of UI that starts the core. In particular.... - */ - - /* -charmap is incompatible with -attach-core, because particular - * charmap gets set up in the running core. */ - if (android_charmap_setup(opts->charmap)) { - exit(1); - } - - if (opts->nojni) - opts->no_jni = opts->nojni; - - if (opts->nocache) - opts->no_cache = opts->nocache; - - if (opts->noaudio) - opts->no_audio = opts->noaudio; - - if (opts->noskin) - opts->no_skin = opts->noskin; - - /* Parses options and builds an appropriate AVD. */ - avd = android_avdInfo = createAVD(opts, &inAndroidBuild); - - /* get the skin from the virtual device configuration */ - opts->skin = (char*) avdInfo_getSkinName( avd ); - opts->skindir = (char*) avdInfo_getSkinDir( avd ); - - if (opts->skin) { - D("autoconfig: -skin %s", opts->skin); - } - if (opts->skindir) { - D("autoconfig: -skindir %s", opts->skindir); - } - - /* Read hardware configuration */ - hw = android_hw; - if (avdInfo_getHwConfig(avd, hw) < 0) { - derror("could not read hardware configuration ?"); - exit(1); - } - - /* Update HW config with the AVD information. */ - updateHwConfigFromAVD(hw, avd, opts, inAndroidBuild); - - if (opts->keyset) { - parse_keyset(opts->keyset, opts); - if (!android_keyset) { - fprintf(stderr, - "emulator: WARNING: could not find keyset file named '%s'," - " using defaults instead\n", - opts->keyset); - } - } - if (!android_keyset) { - parse_keyset("default", opts); - if (!android_keyset) { - android_keyset = skin_keyset_new_from_text( skin_keyset_get_default() ); - if (!android_keyset) { - fprintf(stderr, "PANIC: default keyset file is corrupted !!\n" ); - fprintf(stderr, "PANIC: please update the code in android/skin/keyset.c\n" ); - exit(1); - } - if (!opts->keyset) - write_default_keyset(); - } - } - - if (opts->shared_net_id) { - char* end; - long shared_net_id = strtol(opts->shared_net_id, &end, 0); - if (end == NULL || *end || shared_net_id < 1 || shared_net_id > 255) { - fprintf(stderr, "option -shared-net-id must be an integer between 1 and 255\n"); - exit(1); - } - snprintf(boot_prop_ip, sizeof(boot_prop_ip), - "net.shared_net_ip=10.1.2.%ld", shared_net_id); - } - - - user_config_init(); - parse_skin_files(opts->skindir, opts->skin, opts, hw, - &skinConfig, &skinPath); - - if (!opts->netspeed) { - if (skin_network_speed) - D("skin network speed: '%s'", skin_network_speed); - opts->netspeed = (char*)skin_network_speed; - } - if (!opts->netdelay) { - if (skin_network_delay) - D("skin network delay: '%s'", skin_network_delay); - opts->netdelay = (char*)skin_network_delay; - } - - if (opts->trace) { - char* tracePath = avdInfo_getTracePath(avd, opts->trace); - int ret; - - if (tracePath == NULL) { - derror( "bad -trace parameter" ); - exit(1); - } - ret = path_mkdir_if_needed( tracePath, 0755 ); - if (ret < 0) { - fprintf(stderr, "could not create directory '%s'\n", tmp); - exit(2); - } - opts->trace = tracePath; - } - - if (opts->no_cache) - opts->cache = 0; - - n = 1; - /* generate arguments for the underlying qemu main() */ - { - const char* kernelFile = avdInfo_getImageFile(avd, AVD_IMAGE_KERNEL); - int kernelFileLen = strlen(kernelFile); - - args[n++] = "-kernel"; - args[n++] = (char*)kernelFile; - - /* If the kernel image name ends in "-armv7", then change the cpu - * type automatically. This is a poor man's approach to configuration - * management, but should allow us to get past building ARMv7 - * system images with dex preopt pass without introducing too many - * changes to the emulator sources. - * - * XXX: - * A 'proper' change would require adding some sort of hardware-property - * to each AVD config file, then automatically determine its value for - * full Android builds (depending on some environment variable), plus - * some build system changes. I prefer not to do that for now for reasons - * of simplicity. - */ - if (kernelFileLen > 6 && !memcmp(kernelFile + kernelFileLen - 6, "-armv7", 6)) { - args[n++] = "-cpu"; - args[n++] = "cortex-a8"; - } - } - - if (boot_prop_ip[0]) { - args[n++] = "-boot-property"; - args[n++] = boot_prop_ip; - } - - if (opts->tcpdump) { - args[n++] = "-tcpdump"; - args[n++] = opts->tcpdump; - } - -#ifdef CONFIG_NAND_LIMITS - if (opts->nand_limits) { - args[n++] = "-nand-limits"; - args[n++] = opts->nand_limits; - } -#endif - - if (opts->timezone) { - args[n++] = "-timezone"; - args[n++] = opts->timezone; - } - - if (opts->netspeed) { - args[n++] = "-netspeed"; - args[n++] = opts->netspeed; - } - if (opts->netdelay) { - args[n++] = "-netdelay"; - args[n++] = opts->netdelay; - } - if (opts->netfast) { - args[n++] = "-netfast"; - } - - /* the purpose of -no-audio is to disable sound output from the emulator, - * not to disable Audio emulation. So simply force the 'none' backends */ - if (opts->no_audio) - opts->audio = "none"; - - if (opts->audio) { - args[n++] = "-audio"; - args[n++] = opts->audio; - } - - if (opts->cpu_delay) { - args[n++] = "-cpu-delay"; - args[n++] = opts->cpu_delay; - } - - if (opts->dns_server) { - args[n++] = "-dns-server"; - args[n++] = opts->dns_server; - } - - args[n++] = "-initrd"; - args[n++] = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_RAMDISK); - - { - const char* filetype = "file"; - - // TODO: This should go to core - if (avdInfo_isImageReadOnly(avd, AVD_IMAGE_INITSYSTEM)) - filetype = "initfile"; - - bufprint(tmp, tmpend, - "system,size=0x%x,%s=%s", (uint32_t)hw->disk_systemPartition_size, - filetype, avdInfo_getImageFile(avd, AVD_IMAGE_INITSYSTEM)); - - args[n++] = "-nand"; - args[n++] = strdup(tmp); - } - - bufprint(tmp, tmpend, - "userdata,size=0x%x,file=%s", - (uint32_t)hw->disk_dataPartition_size, - avdInfo_getImageFile(avd, AVD_IMAGE_USERDATA)); - - args[n++] = "-nand"; - args[n++] = strdup(tmp); - - if (hw->disk_cachePartition) { - // TODO: This should go to core - opts->cache = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_CACHE); - cachePartitionSize = hw->disk_cachePartition_size; - } - else if (opts->cache) { - dwarning( "Emulated hardware doesn't support a cache partition" ); - opts->cache = NULL; - opts->no_cache = 1; - } - - if (opts->cache) { - /* use a specific cache file */ - sprintf(tmp, "cache,size=0x%0x,file=%s", cachePartitionSize, opts->cache); - args[n++] = "-nand"; - args[n++] = strdup(tmp); - } - else if (!opts->no_cache) { - /* create a temporary cache partition file */ - sprintf(tmp, "cache,size=0x%0x", cachePartitionSize); - args[n++] = "-nand"; - args[n++] = strdup(tmp); - } - - // TODO: This should go to core - if (hw->hw_sdCard != 0) - opts->sdcard = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_SDCARD); - else if (opts->sdcard) { - dwarning( "Emulated hardware doesn't support SD Cards" ); - opts->sdcard = NULL; - } - - if(opts->sdcard) { - uint64_t size; - if (path_get_size(opts->sdcard, &size) == 0) { - /* see if we have an sdcard image. get its size if it exists */ - /* due to what looks like limitations of the MMC protocol, one has - * to use an SD Card image that is equal or larger than 9 MB - */ - if (size < 9*1024*1024ULL) { - fprintf(stderr, "### WARNING: SD Card files must be at least 9MB, ignoring '%s'\n", opts->sdcard); - } else { - args[n++] = "-hda"; - args[n++] = opts->sdcard; - use_sdcard_img = 1; - } - } else { - D("no SD Card image at '%s'", opts->sdcard); - } - } - -#if CONFIG_ANDROID_SNAPSHOTS - if (!opts->no_snapstorage) { - // TODO: This should go to core - opts->snapstorage = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_SNAPSHOTS); - if(opts->snapstorage) { - if (path_exists(opts->snapstorage)) { - args[n++] = "-hdb"; - args[n++] = opts->snapstorage; - } else { - D("no image at '%s', state snapshots disabled", opts->snapstorage); - } - } - - if (!opts->no_snapshot) { - char* snapshot_name = - opts->snapshot ? opts->snapshot : "default-boot"; - if (!opts->no_snapshot_load) { - args[n++] = "-loadvm"; - args[n++] = snapshot_name; - } - if (!opts->no_snapshot_save) { - args[n++] = "-savevm-on-exit"; - args[n++] = snapshot_name; - } - } else if (opts->snapshot) { - dwarning("option '-no-snapshot' overrides '-snapshot', continuing with boot sequence"); - } else if (opts->no_snapshot_load || opts->no_snapshot_save) { - D("ignoring redundant option(s) '-no-snapshot-load' and/or '-no-snapshot-save' implied by '-no-snapshot'"); - } - // TODO: Convey -no-snapshot-time-update to core subprocess (?) - } else if (opts->snapshot || opts->snapstorage) { - dwarning("option '-no-snapstorage' overrides '-snapshot' and '-snapstorage', " - "continuing with full boot, state snapshots are disabled"); - } else if (opts->no_snapshot) { - D("ignoring redundant option '-no-snapshot' implied by '-no-snapstorage'"); - } - - if (opts->snapshot_list) { - snapshot_print_and_exit(opts->snapstorage); - } -#endif // CONFIG_ANDROID_SNAPSHOTS - - if (!opts->logcat || opts->logcat[0] == 0) { - opts->logcat = getenv("ANDROID_LOG_TAGS"); - if (opts->logcat && opts->logcat[0] == 0) - opts->logcat = NULL; - } - -#if 0 - if (opts->console) { - derror( "option -console is obsolete. please use -shell instead" ); - exit(1); - } -#endif - - /* we always send the kernel messages from ttyS0 to android_kmsg */ - { - if (opts->show_kernel) { - args[n++] = "-show-kernel"; - } - - args[n++] = "-serial"; - args[n++] = "android-kmsg"; - serial++; - } - - /* XXXX: TODO: implement -shell and -logcat through qemud instead */ - if (!opts->shell_serial) { -#ifdef _WIN32 - opts->shell_serial = "con:"; -#else - opts->shell_serial = "stdio"; -#endif - } - else - opts->shell = 1; - - if (opts->shell || opts->logcat) { - args[n++] = "-serial"; - args[n++] = opts->shell_serial; - shell_serial = serial++; - } - - if (opts->old_system) - { - if (opts->radio) { - args[n++] = "-serial"; - args[n++] = opts->radio; - radio_serial = serial++; - } - else { - args[n++] = "-serial"; - args[n++] = "android-modem"; - radio_serial = serial++; - } - if (opts->gps) { - args[n++] = "-serial"; - args[n++] = opts->gps; - gps_serial = serial++; - } - } - else /* !opts->old_system */ - { - args[n++] = "-serial"; - args[n++] = "android-qemud"; - qemud_serial = serial++; - - if (opts->radio) { - args[n++] = "-radio"; - args[n++] = opts->radio; - } - - if (opts->gps) { - args[n++] = "-gps"; - args[n++] = opts->gps; - } - } - - if (opts->memory) { - char* end; - long ramSize = strtol(opts->memory, &end, 0); - if (ramSize < 0 || *end != 0) { - derror( "-memory must be followed by a positive integer" ); - exit(1); - } - if (ramSize < 32 || ramSize > 4096) { - derror( "physical memory size must be between 32 and 4096 MB" ); - exit(1); - } - hw->hw_ramSize = ramSize; - } - if (!opts->memory) { - int ramSize = hw->hw_ramSize; - if (ramSize <= 0) { - /* Compute the default RAM size based on the size of screen. - * This is only used when the skin doesn't provide the ram - * size through its hardware.ini (i.e. legacy ones) or when - * in the full Android build system. - */ - int64_t pixels = hw->hw_lcd_width * hw->hw_lcd_height; - /* The following thresholds are a bit liberal, but we - * essentially want to ensure the following mappings: - * - * 320x480 -> 96 - * 800x600 -> 128 - * 1024x768 -> 256 - * - * These are just simple heuristics, they could change in - * the future. - */ - if (pixels <= 250000) - ramSize = 96; - else if (pixels <= 500000) - ramSize = 128; - else - ramSize = 256; - } - hw->hw_ramSize = ramSize; - } - - D("Physical RAM size: %dMB\n", hw->hw_ramSize); - - if (hw->vm_heapSize == 0) { - /* Compute the default heap size based on the RAM size. - * Essentially, we want to ensure the following liberal mappings: - * - * 96MB RAM -> 16MB heap - * 128MB RAM -> 24MB heap - * 256MB RAM -> 48MB heap - */ - int ramSize = hw->hw_ramSize; - int heapSize; - - if (ramSize < 100) - heapSize = 16; - else if (ramSize < 192) - heapSize = 24; - else - heapSize = 48; - - hw->vm_heapSize = heapSize; - } - - if (opts->trace) { - args[n++] = "-trace"; - args[n++] = opts->trace; - args[n++] = "-tracing"; - args[n++] = "off"; - } - - /* Pass boot properties to the core. */ - if (opts->prop != NULL) { - ParamList* pl = opts->prop; - for ( ; pl != NULL; pl = pl->next ) { - args[n++] = "-boot-property"; - args[n++] = pl->param; - } - } - - args[n++] = "-append"; - - if (opts->bootchart) { - char* end; - int timeout = strtol(opts->bootchart, &end, 10); - if (timeout == 0) - opts->bootchart = NULL; - else if (timeout < 0 || timeout > 15*60) { - derror( "timeout specified for -bootchart option is invalid.\n" - "please use integers between 1 and 900\n"); - exit(1); - } - } - - /* Setup the kernel init options - */ - { - static char params[1024]; - char *p = params, *end = p + sizeof(params); - - p = bufprint(p, end, "qemu=1 console=ttyS0" ); - - if (opts->shell || opts->logcat) { - p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial ); - } - - if (opts->trace) { - p = bufprint(p, end, " android.tracing=1"); - } - - if (!opts->no_jni) { - p = bufprint(p, end, " android.checkjni=1"); - } - - if (opts->no_boot_anim) { - p = bufprint( p, end, " android.bootanim=0" ); - } - - if (opts->logcat) { - char* q = bufprint(p, end, " androidboot.logcat=%s", opts->logcat); - - if (q < end) { - /* replace any space by a comma ! */ - { - int nn; - for (nn = 1; p[nn] != 0; nn++) - if (p[nn] == ' ' || p[nn] == '\t') - p[nn] = ','; - p += nn; - } - } - p = q; - } - - if (opts->old_system) - { - p = bufprint(p, end, " android.ril=ttyS%d", radio_serial); - - if (opts->gps) { - p = bufprint(p, end, " android.gps=ttyS%d", gps_serial); - } - } - else - { - p = bufprint(p, end, " android.qemud=ttyS%d", qemud_serial); - } - - if (opts->bootchart) { - p = bufprint(p, end, " androidboot.bootchart=%s", opts->bootchart); - } - - if (p >= end) { - fprintf(stderr, "### ERROR: kernel parameters too long\n"); - exit(1); - } - - args[n++] = strdup(params); - } - - if (opts->ports) { - args[n++] = "-android-ports"; - args[n++] = opts->ports; - } - - if (opts->port) { - args[n++] = "-android-port"; - args[n++] = opts->port; - } - - if (opts->report_console) { - args[n++] = "-android-report-console"; - args[n++] = opts->report_console; - } - - if (opts->http_proxy) { - args[n++] = "-http-proxy"; - args[n++] = opts->http_proxy; - } - - if (opts->charmap) { - args[n++] = "-charmap"; - args[n++] = opts->charmap; - } - - if (opts->memcheck) { - args[n++] = "-android-memcheck"; - args[n++] = opts->memcheck; - } - - /* physical memory */ - args[n++] = "-m"; - args[n++] = opts->memory; - - /* on Linux, the 'dynticks' clock sometimes doesn't work - * properly. this results in the UI freezing while emulation - * continues, for several seconds... - */ -#ifdef __linux__ - args[n++] = "-clock"; - args[n++] = "unix"; -#endif - - args[n++] = "-android-avdname"; - args[n++] = (char*) avdInfo_getName(avd); - - /* Set up the interfaces for inter-emulator networking */ - if (opts->shared_net_id) { - unsigned int shared_net_id = atoi(opts->shared_net_id); - char nic[37]; - - args[n++] = "-net"; - args[n++] = "nic,vlan=0"; - args[n++] = "-net"; - args[n++] = "user,vlan=0"; - - args[n++] = "-net"; - snprintf(nic, sizeof nic, "nic,vlan=1,macaddr=52:54:00:12:34:%02x", shared_net_id); - args[n++] = strdup(nic); - args[n++] = "-net"; - args[n++] = "socket,vlan=1,mcast=230.0.0.10:1234"; - } - - while(argc-- > 0) { - args[n++] = *argv++; - } - args[n] = 0; - - /* Generate a temporary hardware.ini for this AVD. The real hardware - * configuration is ususally stored in several files, e.g. the AVD's - * config.ini plus the skin-specific hardware.ini. - * - * The new temp file will group all definitions and will be used to - * launch the core with the -android-hw option. - */ - { - const char* coreHwIniPath = avdInfo_getCoreHwIniPath(avd); - IniFile* hwIni = iniFile_newFromMemory("", NULL); - androidHwConfig_write(hw, hwIni); - if (iniFile_saveToFile(hwIni, coreHwIniPath) < 0) { - derror("Could not write hardware.ini to %s: %s", coreHwIniPath, strerror(errno)); - exit(2); - } - args[n++] = "-android-hw"; - args[n++] = strdup(coreHwIniPath); - } - - if(VERBOSE_CHECK(init)) { - int i; - printf("QEMU options list:\n"); - for(i = 0; i < n; i++) { - printf("emulator: argv[%02d] = \"%s\"\n", i, args[i]); - } - /* Dump final command-line option to make debugging the core easier */ - printf("Concatenated QEMU options:\n"); - for (i = 0; i < n; i++) { - printf(" %s", args[i]); - } - printf("\n"); - } - - /* Setup SDL UI just before calling the code */ - init_sdl_ui(skinConfig, skinPath, opts); - - // Lets see if we're attaching to a running core process here. - if (opts->attach_core) { - if (attach_to_core(opts)) { - return -1; - } - // Connect to the core's UI control services. - if (coreCmdProxy_create(attachUiImpl_get_console_socket())) { - return -1; - } - // Connect to the core's user events service. - if (userEventsProxy_create(attachUiImpl_get_console_socket())) { - return -1; - } - } - - return qemu_main(n, args); -} diff --git a/android/main.c b/android/main.c index 40f4b9b..a061ecf 100644 --- a/android/main.c +++ b/android/main.c @@ -55,11 +55,6 @@ #include "android/framebuffer.h" #include "iolooper.h" -#ifdef TARGET_I386 -nand_threshold android_nand_read_threshold; -nand_threshold android_nand_write_threshold; -#endif - AndroidRotation android_framebuffer_rotation; #define STRINGIFY(x) _STRINGIFY(x) @@ -81,10 +76,6 @@ extern int qemu_milli_needed; */ #define DEFAULT_DEVICE_DPI 165 -#if 0 -static int opts->flashkeys; /* forward */ -#endif - #ifdef CONFIG_TRACE extern void start_tracing(void); extern void stop_tracing(void); @@ -148,6 +139,12 @@ int main(int argc, char **argv) exit(1); } +#ifdef _WIN32 + socket_init(); +#endif + + handle_ui_options(opts); + while (argc-- > 1) { opt = (++argv)[0]; @@ -216,6 +213,12 @@ int main(int argc, char **argv) exit(0); } + /* Initialization of UI started with -attach-core should work differently + * than initialization of UI that starts the core. In particular.... + */ + + /* -charmap is incompatible with -attach-core, because particular + * charmap gets set up in the running core. */ if (android_charmap_setup(opts->charmap)) { exit(1); } @@ -413,7 +416,7 @@ int main(int argc, char **argv) { const char* filetype = "file"; - // TODO: This should go to core! + // TODO: This should go to core if (avdInfo_isImageReadOnly(avd, AVD_IMAGE_INITSYSTEM)) filetype = "initfile"; @@ -457,7 +460,7 @@ int main(int argc, char **argv) args[n++] = strdup(tmp); } - // TODO: This should go to core + // TODO: This should go to core if (hw->hw_sdCard != 0) opts->sdcard = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_SDCARD); else if (opts->sdcard) { @@ -514,7 +517,7 @@ int main(int argc, char **argv) D("ignoring redundant option(s) '-no-snapshot-load' and/or '-no-snapshot-save' implied by '-no-snapshot'"); } if (opts->no_snapshot_update_time) { - android_snapshot_update_time = 0; + args[n++] = "-snapshot-no-time-update"; } } else if (opts->snapshot || opts->snapstorage) { dwarning("option '-no-snapstorage' overrides '-snapshot' and '-snapstorage', " @@ -870,5 +873,10 @@ int main(int argc, char **argv) /* Setup SDL UI just before calling the code */ init_sdl_ui(skinConfig, skinPath, opts); + if (attach_ui_to_core(opts) < 0) { + derror("Can't attach to core!"); + exit(1); + } + return qemu_main(n, args); } diff --git a/qemu-options.hx b/qemu-options.hx index 80efaa6..f35b4d0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1782,4 +1782,7 @@ DEF("ui-settings", HAS_ARG, QEMU_OPTION_ui_settings, \ DEF("audio-test-out", 0, QEMU_OPTION_audio_test_out, \ "-audio-test-out Test audio output\n") +DEF("snapshot-no-time-update", 0, QEMU_OPTION_snapshot_no_time_update, \ + "-snapshot-no-time-update Disable time update when restoring snapshots\n") + #endif /* ANDROID */ diff --git a/vl-android.c b/vl-android.c index 1afc8d2..85971b9 100644 --- a/vl-android.c +++ b/vl-android.c @@ -58,6 +58,7 @@ #include "android/utils/bufprint.h" #include "android/display-core.h" #include "android/utils/timezone.h" +#include "android/snapshot.h" #include "targphys.h" #include "tcpdump.h" @@ -4800,6 +4801,10 @@ int main(int argc, char **argv, char **envp) append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append)); break; #endif // CONFIG_MEMCHECK + + case QEMU_OPTION_snapshot_no_time_update: + android_snapshot_update_time = 0; + break; } } } -- cgit v1.1