aboutsummaryrefslogtreecommitdiffstats
path: root/android/main-emulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/main-emulator.c')
-rw-r--r--android/main-emulator.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/android/main-emulator.c b/android/main-emulator.c
new file mode 100644
index 0000000..211291b
--- /dev/null
+++ b/android/main-emulator.c
@@ -0,0 +1,169 @@
+/* Copyright (C) 2011 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 is the source code to the tiny "emulator" launcher program
+ * that is in charge of starting the target-specific emulator binary
+ * for a given AVD, i.e. either 'emulator-arm' or 'emulator-x86'
+ *
+ * This program will be replaced in the future by what is currently
+ * known as 'emulator-ui', but is a good placeholder until this
+ * migration is completed.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <android/utils/panic.h>
+#include <android/utils/path.h>
+#include <android/utils/bufprint.h>
+#include <android/avd/util.h>
+
+/* Required by android/utils/debug.h */
+int android_verbose;
+
+
+#define DEBUG 1
+
+#if DEBUG
+# define D(...) do { if (android_verbose) printf("emulator:" __VA_ARGS__); } while (0)
+#else
+# define D(...) do{}while(0)
+#endif
+
+/* Forward declarations */
+static char* getTargetEmulatorPath(const char* progName, const char* avdArch);
+
+/* Main routine */
+int main(int argc, char** argv)
+{
+ const char* avdName = NULL;
+ char* avdArch = NULL;
+ char* emulatorPath;
+
+ /* Define ANDROID_EMULATOR_DEBUG to 1 in your environment if you want to
+ * see the debug messages from this launcher program.
+ */
+ const char* debug = getenv("ANDROID_EMULATOR_DEBUG");
+
+ if (debug != NULL && *debug && *debug != '0')
+ android_verbose = 1;
+
+ /* Parse command-line and look for an avd name
+ * Either in the form or '-avd <name>' or '@<name>'
+ */
+ int nn;
+ for (nn = 1; nn < argc; nn++) {
+ const char* opt = argv[nn];
+
+ if (!strcmp(opt,"-qemu"))
+ break;
+
+ if (!strcmp(opt,"-avd") && nn+1 < argc) {
+ avdName = argv[nn+1];
+ break;
+ }
+ else if (opt[0] == '@' && opt[1] != '\0') {
+ avdName = opt+1;
+ break;
+ }
+ }
+
+ /* If there is an AVD name, we're going to extract its target architecture
+ * by looking at its config.ini
+ */
+ if (avdName != NULL) {
+ D("Found AVD name '%s'\n", avdName);
+ avdArch = path_getAvdTargetArch(avdName);
+ D("Found AVD target architecture: %s\n", avdArch);
+ } else {
+ /* Otherwise, using the ANDROID_PRODUCT_OUT directory */
+ const char* androidOut = getenv("ANDROID_PRODUCT_OUT");
+
+ if (androidOut != NULL && *androidOut != '\0') {
+ D("Found ANDROID_PRODUCT_OUT: %s\n", androidOut);
+ avdArch = path_getBuildTargetArch(androidOut);
+ D("Found build target architecture: %s\n", avdArch);
+ }
+ }
+
+ if (avdArch == NULL) {
+ avdArch = "arm";
+ D("Can't determine target AVD architecture: defaulting to %s\n", avdArch);
+ }
+
+ /* Find the architecture-specific program in the same directory */
+ emulatorPath = getTargetEmulatorPath(argv[0], avdArch);
+ D("Found target-specific emulator binary: %s\n", emulatorPath);
+
+ /* Replace it in our command-line */
+ argv[0] = emulatorPath;
+
+ /* Launch it with the same set of options ! */
+ /* execv() should be available on Windows with mingw32 */
+ execv(emulatorPath, argv);
+
+ /* We could not launch the program ! */
+ fprintf(stderr, "Could not launch '%s': %s\n", emulatorPath, strerror(errno));
+ return errno;
+}
+
+
+/* Find the target-specific emulator binary. This will be something
+ * like <programDir>/emulator-<targetArch>, where <programDir> is
+ * the directory of the current program.
+ */
+static char*
+getTargetEmulatorPath(const char* progName, const char* avdArch)
+{
+ char* progDir;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+#ifdef _WIN32
+ const char* exeExt = ".exe";
+#else
+ const char* exeExt = "";
+#endif
+
+ /* Get program's directory name in progDir */
+ path_split(progName, &progDir, NULL);
+
+ p = bufprint(temp, end, "%s/emulator-%s%s", progDir, avdArch, exeExt);
+ free(progDir);
+ if (p >= end) {
+ APANIC("Path too long: %s\n", progName);
+ }
+
+ if (path_exists(temp)) {
+ return strdup(temp);
+ }
+
+ /* Mmm, the file doesn't exist, If there is no slash / backslash
+ * in our path, we're going to try to search it in our path.
+ */
+#ifdef _WIN32
+ if (strchr(progName, '/') == NULL && strchr(progName, '\\') == NULL) {
+#else
+ if (strchr(progName, '/') == NULL) {
+#endif
+ p = bufprint(temp, end, "emulator-%s%s", avdArch, exeExt);
+ if (p < end) {
+ char* resolved = path_search_exec(temp);
+ if (resolved != NULL)
+ return resolved;
+ }
+ }
+
+ /* Otherwise, the program is missing */
+ APANIC("Missing arch-specific emulator program: %s\n", temp);
+ return NULL;
+}