aboutsummaryrefslogtreecommitdiffstats
path: root/android/avd
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2011-03-25 10:34:47 +0100
committerDavid 'Digit' Turner <digit@android.com>2011-05-02 18:05:18 +0200
commit2d238fd9871687b1557f15b8878a6cf3e9634b57 (patch)
tree1ecdd74927037aea7bc899c78a9cdddefb38ff22 /android/avd
parentec1d38fbb171c45fc8b79734efb80e2c21db6ef8 (diff)
downloadexternal_qemu-2d238fd9871687b1557f15b8878a6cf3e9634b57.zip
external_qemu-2d238fd9871687b1557f15b8878a6cf3e9634b57.tar.gz
external_qemu-2d238fd9871687b1557f15b8878a6cf3e9634b57.tar.bz2
Add 'emulator' launcher program.
This patch renames the current ARM-specific emulator binary to 'emulator-arm' and introduces a new tiny (less than 20KB) 'emulator' launcher program. The role of 'emulator' is to launch either 'emulator-arm' or 'emulator-x86' based on the target AVD or platform build being used. This program will be replaced in the future by what is currently known as 'emulator-ui', but is a good placeholder until this work is completed. + Move some utility functions from android/avd/info.[hc] to android/avd/util.[hc] so that 'emulator' can use them directly. IMPORTANT: For platform builds, the target architecture is detected automatically by parsing the build.prop file. For SDK AVDs however, there is no easy way to determine the target architecture, so the patch adds a new hw.cpu.arch property which can have value 'arm' or 'x86' Change-Id: I0084c196695a75c8b9230ba716b3cd2e12610ded
Diffstat (limited to 'android/avd')
-rw-r--r--android/avd/hardware-properties.ini16
-rw-r--r--android/avd/hw-config-defs.h14
-rw-r--r--android/avd/info.c226
-rw-r--r--android/avd/util.c304
-rw-r--r--android/avd/util.h57
5 files changed, 397 insertions, 220 deletions
diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini
index 151d3df..65ba61d 100644
--- a/android/avd/hardware-properties.ini
+++ b/android/avd/hardware-properties.ini
@@ -23,6 +23,22 @@
# the emulator build.
#
+# CPU Architecture
+name = hw.cpu.arch
+type = string
+default = arm
+abstract = CPU Architecture
+description = The CPU Architecture to emulator
+
+# CPU Model
+# Leave it empty, and the default value will be computed from
+# hw.cpu.arch. This is only useful for experimentation for now.
+name = hw.cpu.model
+type = string
+default =
+abstract = CPU model
+description = The CPU model (QEMU-specific string)
+
# Ram size
# Default value will be computed based on screen pixels
# or skin version
diff --git a/android/avd/hw-config-defs.h b/android/avd/hw-config-defs.h
index 6308bd5..bb523d5 100644
--- a/android/avd/hw-config-defs.h
+++ b/android/avd/hw-config-defs.h
@@ -17,6 +17,20 @@
#error HWCFG_DOUBLE not defined
#endif
+HWCFG_STRING(
+ hw_cpu_arch,
+ "hw.cpu.arch",
+ "arm",
+ "CPU Architecture",
+ "The CPU Architecture to emulator")
+
+HWCFG_STRING(
+ hw_cpu_model,
+ "hw.cpu.model",
+ "",
+ "CPU model",
+ "The CPU model (QEMU-specific string)")
+
HWCFG_INT(
hw_ramSize,
"hw.ramSize",
diff --git a/android/avd/info.c b/android/avd/info.c
index 6f7c904..a9fc711 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -10,6 +10,7 @@
** GNU General Public License for more details.
*/
#include "android/avd/info.h"
+#include "android/avd/util.h"
#include "android/config/config.h"
#include "android/utils/path.h"
#include "android/utils/bufprint.h"
@@ -63,12 +64,6 @@ AvdInfo* android_avdInfo;
* with one of the usual options.
*/
-/* this is the subdirectory of $HOME/.android where all
- * root configuration files (and default content directories)
- * are located.
- */
-#define ANDROID_AVD_DIR "avd"
-
/* the prefix of config.ini keys that will be used for search directories
* of system images.
*/
@@ -230,50 +225,6 @@ static const char* const _imageFileText[ AVD_IMAGE_MAX ] = {
*****
*****/
-/* Return the path to the Android SDK root installation.
- *
- * (*pFromEnv) will be set to 1 if it comes from the $ANDROID_SDK_ROOT
- * environment variable, or 0 otherwise.
- *
- * Caller must free() returned string.
- */
-static char*
-_getSdkRoot( char *pFromEnv )
-{
- const char* env;
- char* sdkPath;
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
- /* If ANDROID_SDK_ROOT is defined is must point to a directory
- * containing a valid SDK installation.
- */
-#define SDK_ROOT_ENV "ANDROID_SDK_ROOT"
-
- env = getenv(SDK_ROOT_ENV);
- if (env != NULL && env[0] != 0) {
- if (path_exists(env)) {
- D("found " SDK_ROOT_ENV ": %s", env);
- *pFromEnv = 1;
- return ASTRDUP(env);
- }
- D(SDK_ROOT_ENV " points to unknown directory: %s", env);
- }
-
- *pFromEnv = 0;
-
- /* We assume the emulator binary is under tools/ so use its
- * parent as the Android SDK root.
- */
- (void) bufprint_app_dir(temp, end);
- sdkPath = path_parent(temp, 1);
- if (sdkPath == NULL) {
- derror("can't find root of SDK directory");
- return NULL;
- }
- D("found SDK root at %s", sdkPath);
- return sdkPath;
-}
-
/* Parse a given config.ini file and extract the list of SDK search paths
* from it. Returns the number of valid paths stored in 'searchPaths', or -1
* in case of problem.
@@ -326,171 +277,6 @@ _checkAvdName( const char* name )
return (len == len2);
}
-/* Return the path to the AVD's root configuration .ini file. it is located in
- * ~/.android/avd/<name>.ini or Windows equivalent
- *
- * This file contains the path to the AVD's content directory, which
- * includes its own config.ini.
- */
-static char*
-_getRootIniPath( const char* avdName )
-{
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
- p = bufprint_config_path(temp, end);
- p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", avdName);
- if (p >= end) {
- return NULL;
- }
- if (!path_exists(temp)) {
- return NULL;
- }
- return ASTRDUP(temp);
-}
-
-
-/* Retrieves the value of a given system property defined in a .prop
- * file. This is a text file that contains definitions of the format:
- * <name>=<value>
- *
- * Returns NULL if property <name> is undefined or empty.
- * Returned string must be freed by the caller.
- */
-static char*
-_getSystemProperty( const char* propFile, const char* propName )
-{
- FILE* file;
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
- int propNameLen = strlen(propName);
- char* result = NULL;
-
- file = fopen(propFile, "rb");
- if (file == NULL) {
- D("Could not open file: %s: %s", temp, strerror(errno));
- return NULL;
- }
-
- while (fgets(temp, sizeof temp, file) != NULL) {
- /* Trim trailing newlines, if any */
- p = memchr(temp, '\0', sizeof temp);
- if (p == NULL)
- p = end;
- if (p > temp && p[-1] == '\n') {
- *--p = '\0';
- }
- if (p > temp && p[-1] == '\r') {
- *--p = '\0';
- }
- /* force zero-termination in case of full-buffer */
- if (p == end)
- *--p = '\0';
-
- /* check that the line starts with the property name */
- if (memcmp(temp, propName, propNameLen) != 0) {
- continue;
- }
- p = temp + propNameLen;
-
- /* followed by an equal sign */
- if (p >= end || *p != '=')
- continue;
- p++;
-
- /* followed by something */
- if (p >= end || !*p)
- break;
-
- result = ASTRDUP(p);
- break;
- }
- fclose(file);
- return result;
-}
-
-/* Return a build property. This is a system property defined in a file
- * named $ANDROID_PRODUCT_OUT/system/build.prop
- *
- * Returns NULL if undefined or empty. Returned string must be freed
- * by the caller.
- */
-static char*
-_getBuildProperty( const char* androidOut, const char* propName )
-{
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
- p = bufprint(temp, end, "%s/system/build.prop", androidOut);
- if (p >= end) {
- D("%s: ANDROID_PRODUCT_OUT too long: %s", __FUNCTION__, androidOut);
- return NULL;
- }
- return _getSystemProperty(temp, propName);
-}
-
-/* Retrieves a string corresponding to the target architecture
- * when in the Android platform tree. The only way to do that
- * properly for now is to look at $OUT/system/build.prop:
- *
- * ro.product.cpu-abi=<abi>
- *
- * Where <abi> can be 'armeabi', 'armeabi-v7a' or 'x86'.
- */
-static char*
-_getBuildTargetArch( const char* androidOut )
-{
- const char* defaultArch = "arm";
- char* result = NULL;
- char* cpuAbi = _getBuildProperty(androidOut, "ro.product.cpu.abi");
-
- if (cpuAbi == NULL) {
- D("Coult not find CPU ABI in build properties!");
- D("Default target architecture=%s", defaultArch);
- result = ASTRDUP(defaultArch);
- } else {
- /* Translate ABI to cpu arch if necessary */
- if (!strcmp("armeabi",cpuAbi))
- result = "arm";
- else if (!strcmp("armeabi-v7a", cpuAbi))
- result = "arm";
- else
- result = cpuAbi;
-
- D("Found target ABI=%s, architecture=%s", cpuAbi, result);
- result = ASTRDUP(result);
- AFREE(cpuAbi);
- }
- return result;
-}
-
-static int
-_getBuildTargetApiLevel( const char* androidOut )
-{
- const int defaultLevel = 1000;
- int level = defaultLevel;
- char* sdkVersion = _getBuildProperty(androidOut, "ro.build.version.sdk");
-
- if (sdkVersion != NULL) {
- long value;
- char* end;
- value = strtol(sdkVersion, &end, 10);
- if (end == NULL || *end != '\0' || value != (int)value) {
- D("Invalid SDK version build property: '%s'", sdkVersion);
- D("Defaulting to target API level %d", level);
- } else {
- level = (int)value;
- /* Sanity check, the Android SDK doesn't support anything
- * before Android 1.5, a.k.a API level 3 */
- if (level < 3)
- level = 3;
- D("Found target API level: %d", level);
- }
- AFREE(sdkVersion);
- } else {
- D("Could not find target API level / SDK version in build properties!");
- D("Default target API level: %d", level);
- }
- return level;
-}
-
/* Returns the full path of a given file.
*
* If 'fileName' is an absolute path, this returns a simple copy.
@@ -536,7 +322,7 @@ _checkSkinPath( const char* skinPath )
*/
static char*
_checkSkinSkinsDir( const char* skinDirRoot,
- const char* skinName )
+ const char* skinName )
{
DirScanner* scanner;
char* result;
@@ -649,7 +435,7 @@ static int
_avdInfo_getSdkRoot( AvdInfo* i )
{
- i->sdkRootPath = _getSdkRoot(&i->sdkRootPathFromEnv);
+ i->sdkRootPath = path_getSdkRoot(&i->sdkRootPathFromEnv);
if (i->sdkRootPath == NULL)
return -1;
@@ -662,7 +448,7 @@ _avdInfo_getSdkRoot( AvdInfo* i )
static int
_avdInfo_getRootIni( AvdInfo* i )
{
- char* iniPath = _getRootIniPath( i->deviceName );
+ char* iniPath = path_getRootIniPath( i->deviceName );
if (iniPath == NULL) {
derror("unknown virtual device name: '%s'", i->deviceName);
@@ -1027,8 +813,8 @@ avdInfo_newForAndroidBuild( const char* androidBuildRoot,
i->androidBuildRoot = ASTRDUP(androidBuildRoot);
i->androidOut = ASTRDUP(androidOut);
i->contentPath = ASTRDUP(androidOut);
- i->targetArch = _getBuildTargetArch(i->androidOut);
- i->apiLevel = _getBuildTargetApiLevel(i->androidOut);
+ i->targetArch = path_getBuildTargetArch(i->androidOut);
+ i->apiLevel = path_getBuildTargetApiLevel(i->androidOut);
/* TODO: find a way to provide better information from the build files */
i->deviceName = ASTRDUP("<build>");
diff --git a/android/avd/util.c b/android/avd/util.c
new file mode 100644
index 0000000..fdeb0fe
--- /dev/null
+++ b/android/avd/util.c
@@ -0,0 +1,304 @@
+/* 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.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include "android/utils/debug.h"
+#include "android/utils/bufprint.h"
+#include "android/utils/ini.h"
+#include "android/utils/panic.h"
+#include "android/utils/path.h"
+#include "android/utils/system.h"
+#include "android/avd/util.h"
+
+#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
+
+/* this is the subdirectory of $HOME/.android where all
+ * root configuration files (and default content directories)
+ * are located.
+ */
+#define ANDROID_AVD_DIR "avd"
+
+
+/* Return the path to the Android SDK root installation.
+ *
+ * (*pFromEnv) will be set to 1 if it comes from the $ANDROID_SDK_ROOT
+ * environment variable, or 0 otherwise.
+ *
+ * Caller must free() returned string.
+ */
+char*
+path_getSdkRoot( char *pFromEnv )
+{
+ const char* env;
+ char* sdkPath;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+
+ /* If ANDROID_SDK_ROOT is defined is must point to a directory
+ * containing a valid SDK installation.
+ */
+#define SDK_ROOT_ENV "ANDROID_SDK_ROOT"
+
+ env = getenv(SDK_ROOT_ENV);
+ if (env != NULL && env[0] != 0) {
+ if (path_exists(env)) {
+ D("found " SDK_ROOT_ENV ": %s", env);
+ *pFromEnv = 1;
+ return ASTRDUP(env);
+ }
+ D(SDK_ROOT_ENV " points to unknown directory: %s", env);
+ }
+
+ *pFromEnv = 0;
+
+ /* We assume the emulator binary is under tools/ so use its
+ * parent as the Android SDK root.
+ */
+ (void) bufprint_app_dir(temp, end);
+ sdkPath = path_parent(temp, 1);
+ if (sdkPath == NULL) {
+ derror("can't find root of SDK directory");
+ return NULL;
+ }
+ D("found SDK root at %s", sdkPath);
+ return sdkPath;
+}
+
+
+/* Return the path to the AVD's root configuration .ini file. it is located in
+ * ~/.android/avd/<name>.ini or Windows equivalent
+ *
+ * This file contains the path to the AVD's content directory, which
+ * includes its own config.ini.
+ */
+char*
+path_getRootIniPath( const char* avdName )
+{
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+
+ p = bufprint_config_path(temp, end);
+ p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", avdName);
+ if (p >= end) {
+ return NULL;
+ }
+ if (!path_exists(temp)) {
+ return NULL;
+ }
+ return ASTRDUP(temp);
+}
+
+
+char*
+path_getSdkHome(void)
+{
+ const char* sdkHome = getenv("ANDROID_SDK_HOME");
+
+ if (sdkHome == NULL || *sdkHome == '\0') {
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+ p = bufprint_config_path(temp, end);
+ if (p >= end) {
+ APANIC("User path too long!: %s\n", temp);
+ }
+ sdkHome = strdup(temp);
+ } else {
+ sdkHome = strdup(sdkHome);
+ }
+ return (char*)sdkHome;
+}
+
+
+static char*
+_getAvdContentPath(const char* avdName)
+{
+ char* sdkHome = path_getSdkHome();
+ char* avdPath = NULL;
+ IniFile* ini;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+
+ /* Look for the root .ini file */
+ p = bufprint(temp, end, "%s/avd/%s.ini", sdkHome, avdName);
+ if (p >= end) {
+ APANIC("AVD Name too long: %s\n", avdName);
+ }
+
+ ini = iniFile_newFromFile(temp);
+ if (ini == NULL) {
+ APANIC("Could not open: %s", temp);
+ }
+
+ avdPath = iniFile_getString(ini, "path", NULL);
+
+ iniFile_free(ini);
+ AFREE(sdkHome);
+
+ return avdPath;
+}
+
+
+static char*
+_getAvdTargetArch(const char* avdPath)
+{
+ IniFile* ini;
+ char* targetArch = NULL;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+ p = bufprint(temp, end, "%s/config.ini", avdPath);
+ if (p >= end) {
+ APANIC("AVD path too long: %s\n", avdPath);
+ }
+ ini = iniFile_newFromFile(temp);
+ if (ini == NULL) {
+ APANIC("Could not open AVD config file: %s", temp);
+ }
+ targetArch = iniFile_getString(ini, "hw.cpu.arch", "arm");
+ iniFile_free(ini);
+
+ return targetArch;
+}
+
+char*
+path_getAvdTargetArch( const char* avdName )
+{
+ char* avdPath = _getAvdContentPath(avdName);
+ char* avdArch = _getAvdTargetArch(avdPath);
+
+ return avdArch;
+}
+
+/* Retrieves the value of a given system property defined in a .prop
+ * file. This is a text file that contains definitions of the format:
+ * <name>=<value>
+ *
+ * Returns NULL if property <name> is undefined or empty.
+ * Returned string must be freed by the caller.
+ */
+static char*
+_getSystemProperty( const char* propFile, const char* propName )
+{
+ FILE* file;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+ int propNameLen = strlen(propName);
+ char* result = NULL;
+
+ file = fopen(propFile, "rb");
+ if (file == NULL) {
+ D("Could not open file: %s: %s", temp, strerror(errno));
+ return NULL;
+ }
+
+ while (fgets(temp, sizeof temp, file) != NULL) {
+ /* Trim trailing newlines, if any */
+ p = memchr(temp, '\0', sizeof temp);
+ if (p == NULL)
+ p = end;
+ if (p > temp && p[-1] == '\n') {
+ *--p = '\0';
+ }
+ if (p > temp && p[-1] == '\r') {
+ *--p = '\0';
+ }
+ /* force zero-termination in case of full-buffer */
+ if (p == end)
+ *--p = '\0';
+
+ /* check that the line starts with the property name */
+ if (memcmp(temp, propName, propNameLen) != 0) {
+ continue;
+ }
+ p = temp + propNameLen;
+
+ /* followed by an equal sign */
+ if (p >= end || *p != '=')
+ continue;
+ p++;
+
+ /* followed by something */
+ if (p >= end || !*p)
+ break;
+
+ result = ASTRDUP(p);
+ break;
+ }
+ fclose(file);
+ return result;
+}
+
+static char*
+_getBuildProperty( const char* androidOut, const char* propName )
+{
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+
+ p = bufprint(temp, end, "%s/system/build.prop", androidOut);
+ if (p >= end) {
+ D("%s: ANDROID_PRODUCT_OUT too long: %s", __FUNCTION__, androidOut);
+ return NULL;
+ }
+ return _getSystemProperty(temp, propName);
+}
+
+char*
+path_getBuildTargetArch( const char* androidOut )
+{
+ const char* defaultArch = "arm";
+ char* result = NULL;
+ char* cpuAbi = _getBuildProperty(androidOut, "ro.product.cpu.abi");
+
+ if (cpuAbi == NULL) {
+ D("Coult not find CPU ABI in build properties!");
+ D("Default target architecture=%s", defaultArch);
+ result = ASTRDUP(defaultArch);
+ } else {
+ /* Translate ABI to cpu arch if necessary */
+ if (!strcmp("armeabi",cpuAbi))
+ result = "arm";
+ else if (!strcmp("armeabi-v7a", cpuAbi))
+ result = "arm";
+ else
+ result = cpuAbi;
+
+ D("Found target ABI=%s, architecture=%s", cpuAbi, result);
+ result = ASTRDUP(result);
+ AFREE(cpuAbi);
+ }
+ return result;
+}
+
+
+int
+path_getBuildTargetApiLevel( const char* androidOut )
+{
+ const int defaultLevel = 1000;
+ int level = defaultLevel;
+ char* sdkVersion = _getBuildProperty(androidOut, "ro.build.version.sdk");
+
+ if (sdkVersion != NULL) {
+ long value;
+ char* end;
+ value = strtol(sdkVersion, &end, 10);
+ if (end == NULL || *end != '\0' || value != (int)value) {
+ D("Invalid SDK version build property: '%s'", sdkVersion);
+ D("Defaulting to target API level %d", level);
+ } else {
+ level = (int)value;
+ /* Sanity check, the Android SDK doesn't support anything
+ * before Android 1.5, a.k.a API level 3 */
+ if (level < 3)
+ level = 3;
+ D("Found target API level: %d", level);
+ }
+ AFREE(sdkVersion);
+ } else {
+ D("Could not find target API level / SDK version in build properties!");
+ D("Default target API level: %d", level);
+ }
+ return level;
+}
+
diff --git a/android/avd/util.h b/android/avd/util.h
new file mode 100644
index 0000000..27f8f28
--- /dev/null
+++ b/android/avd/util.h
@@ -0,0 +1,57 @@
+/* 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.
+*/
+#ifndef _ANDROID_AVD_UTIL_H
+#define _ANDROID_AVD_UTIL_H
+
+/* A collection of simple functions to extract relevant AVD-related
+ * information either from an SDK AVD or a platform build.
+ */
+
+/* Return the path to the Android SDK root installation.
+ *
+ * (*pFromEnv) will be set to 1 if it comes from the $ANDROID_SDK_ROOT
+ * environment variable, or 0 otherwise.
+ *
+ * Caller must free() returned string.
+ */
+char* path_getSdkRoot( char *pFromEnv );
+
+/* Return the path to the AVD's root configuration .ini file. it is located in
+ * ~/.android/avd/<name>.ini or Windows equivalent
+ *
+ * This file contains the path to the AVD's content directory, which
+ * includes its own config.ini.
+ */
+char* path_getRootIniPath( const char* avdName );
+
+/* Return the target architecture for a given AVD.
+ * Called must free() returned string.
+ */
+char* path_getAvdTargetArch( const char* avdName );
+
+/* Retrieves a string corresponding to the target architecture
+ * when in the Android platform tree. The only way to do that
+ * properly for now is to look at $OUT/system/build.prop:
+ *
+ * ro.product.cpu-abi=<abi>
+ *
+ * Where <abi> can be 'armeabi', 'armeabi-v7a' or 'x86'.
+ */
+char* path_getBuildTargetArch( const char* androidOut );
+
+/* Retrieve the target API level when in the Android platform tree.
+ * This can be a very large number like 1000 if the value cannot
+ * be extracted from the appropriate file
+ */
+int path_getBuildTargetApiLevel( const char* androidOut );
+
+#endif /* _ANDROID_AVD_UTIL_H */