SDK emulator: support relative path in avd root ini files.
Change-Id: I0488a930c0975dfb605fddba857739c36477286f
diff --git a/Makefile.android b/Makefile.android
index 4faea98..78dad44 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -86,12 +86,10 @@
# itself only works on GCC 4.x anyway.
GCC_W_NO_MISSING_FIELD_INITIALIZERS := -Wno-missing-field-initializers
ifeq ($(HOST_OS),windows)
- ifeq ($(USE_MINGW),)
ifeq (,$(shell gcc -Q --help=warnings 2>/dev/null | grep missing-field-initializers))
$(info emulator: Ignoring unsupported GCC flag $(GCC_W_NO_MISSING_FIELD_INITIALIZERS))
GCC_W_NO_MISSING_FIELD_INITIALIZERS :=
endif
- endif
endif
# BUILD_STANDALONE_EMULATOR is only defined when building with
diff --git a/android/avd/info.c b/android/avd/info.c
index 0f43de6..7d4191d 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -11,6 +11,7 @@
*/
#include "android/avd/info.h"
#include "android/avd/util.h"
+#include "android/avd/keys.h"
#include "android/config/config.h"
#include "android/utils/path.h"
#include "android/utils/bufprint.h"
@@ -64,38 +65,6 @@
* with one of the usual options.
*/
-/* the prefix of config.ini keys that will be used for search directories
- * of system images.
- */
-#define SEARCH_PREFIX "image.sysdir."
-
-/* the maximum number of search path keys we're going to read from the
- * config.ini file
- */
-#define MAX_SEARCH_PATHS 2
-
-/* the config.ini key that will be used to indicate the full relative
- * path to the skin directory (including the skin name).
- */
-#define SKIN_PATH "skin.path"
-
-/* the config.ini key that will be used to indicate the default skin's name.
- * this is ignored if there is a valid SKIN_PATH entry in the file.
- */
-#define SKIN_NAME "skin.name"
-
-/* the config.ini key that specifies if this AVD should use a dynamic skin */
-#define SKIN_DYNAMIC "skin.dynamic"
-
-/* default skin name */
-#define SKIN_DEFAULT "HVGA"
-
-/* the config.ini key that is used to indicate the absolute path
- * to the SD Card image file, if you don't want to place it in
- * the content directory.
- */
-#define SDCARD_PATH "sdcard.path"
-
/* the name of the .ini file that will contain the complete hardware
* properties for the AVD. This will be used to launch the corresponding
* core from the UI.
@@ -479,15 +448,30 @@
static int
_avdInfo_getContentPath( AvdInfo* i )
{
-# define ROOT_PATH_KEY "path"
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
- i->contentPath = iniFile_getString(i->rootIni, ROOT_PATH_KEY, NULL);
+ i->contentPath = iniFile_getString(i->rootIni, ROOT_ABS_PATH_KEY, NULL);
if (i->contentPath == NULL) {
derror("bad config: %s",
- "virtual device file lacks a "ROOT_PATH_KEY" entry");
+ "virtual device file lacks a "ROOT_ABS_PATH_KEY" entry");
return -1;
}
+
+ if (!path_is_dir(i->contentPath)) {
+ // If the absolute path doesn't match an actual directory, try
+ // the relative path if present.
+ const char* relPath = iniFile_getString(i->rootIni, ROOT_REL_PATH_KEY, NULL);
+ if (relPath != NULL) {
+ p = bufprint_config_path(temp, end);
+ p = bufprint(p, end, PATH_SEP "%s", relPath);
+ if (p < end && path_is_dir(temp)) {
+ AFREE(i->contentPath);
+ i->contentPath = ASTRDUP(temp);
+ }
+ }
+ }
+
D("virtual device content at %s", i->contentPath);
return 0;
}
diff --git a/android/avd/keys.h b/android/avd/keys.h
new file mode 100755
index 0000000..9f4aff6
--- /dev/null
+++ b/android/avd/keys.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2012 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_KEYS_H
+#define _ANDROID_AVD_KEYS_H
+
+/* Keys of the properties found in avd/name.ini and config.ini files.
+ *
+ * These keys must match their counterpart defined in
+ * sdk/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
+ */
+
+
+/* -- Keys used in avd/name.ini -- */
+
+/* Absolute path of the AVD content directory.
+ */
+#define ROOT_ABS_PATH_KEY "path"
+
+/* Relative path of the AVD content directory.
+ * Path is relative to the bufprint_config_path().
+ */
+#define ROOT_REL_PATH_KEY "path.rel"
+
+
+/* -- Keys used in config.ini -- */
+
+/* the prefix of config.ini keys that will be used for search directories
+ * of system images.
+ */
+#define SEARCH_PREFIX "image.sysdir."
+
+/* the maximum number of search path keys we're going to read from the
+ * config.ini file
+ */
+#define MAX_SEARCH_PATHS 2
+
+/* the config.ini key that will be used to indicate the full relative
+ * path to the skin directory (including the skin name).
+ */
+#define SKIN_PATH "skin.path"
+
+/* the config.ini key that will be used to indicate the default skin's name.
+ * this is ignored if there is a valid SKIN_PATH entry in the file.
+ */
+#define SKIN_NAME "skin.name"
+
+/* the config.ini key that specifies if this AVD should use a dynamic skin */
+#define SKIN_DYNAMIC "skin.dynamic"
+
+/* default skin name */
+#define SKIN_DEFAULT "HVGA"
+
+/* the config.ini key that is used to indicate the absolute path
+ * to the SD Card image file, if you don't want to place it in
+ * the content directory.
+ */
+#define SDCARD_PATH "sdcard.path"
+
+
+
+#endif /* _ANDROID_AVD_KEYS_H */
diff --git a/android/avd/util.c b/android/avd/util.c
index cc51e0f..75263a3 100644
--- a/android/avd/util.c
+++ b/android/avd/util.c
@@ -19,6 +19,7 @@
#include "android/utils/path.h"
#include "android/utils/system.h"
#include "android/avd/util.h"
+#include "android/avd/keys.h"
#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
@@ -86,7 +87,7 @@
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);
+ p = bufprint(p, end, PATH_SEP ANDROID_AVD_DIR PATH_SEP "%s.ini", avdName);
if (p >= end) {
return NULL;
}
@@ -112,26 +113,37 @@
static char*
_getAvdContentPath(const char* avdName)
{
- char* sdkHome = path_getSdkHome();
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+ IniFile* ini = NULL;
+ char* iniPath = path_getRootIniPath(avdName);
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);
+ if (iniPath != NULL) {
+ ini = iniFile_newFromFile(iniPath);
+ AFREE(iniPath);
}
- ini = iniFile_newFromFile(temp);
if (ini == NULL) {
- APANIC("Could not open: %s", temp);
+ APANIC("Could not open: %s\n", iniPath == NULL ? avdName : iniPath);
}
- avdPath = iniFile_getString(ini, "path", NULL);
+ avdPath = iniFile_getString(ini, ROOT_ABS_PATH_KEY, NULL);
+
+ if (!path_is_dir(avdPath)) {
+ // If the absolute path doesn't match an actual directory, try
+ // the relative path if present.
+ const char* relPath = iniFile_getString(ini, ROOT_REL_PATH_KEY, NULL);
+ if (relPath != NULL) {
+ p = bufprint_config_path(temp, end);
+ p = bufprint(p, end, PATH_SEP "%s", relPath);
+ if (p < end && path_is_dir(temp)) {
+ AFREE(avdPath);
+ avdPath = ASTRDUP(temp);
+ }
+ }
+ }
iniFile_free(ini);
- AFREE(sdkHome);
return avdPath;
}
@@ -143,13 +155,13 @@
IniFile* ini;
char* targetArch = NULL;
char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
- p = bufprint(temp, end, "%s/config.ini", avdPath);
+ p = bufprint(temp, end, "%s" PATH_SEP "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);
+ APANIC("Could not open AVD config file: %s\n", temp);
}
targetArch = iniFile_getString(ini, "hw.cpu.arch", "arm");
iniFile_free(ini);
diff --git a/android/utils/path.c b/android/utils/path.c
index 3e9d97b..95c9c2e 100644
--- a/android/utils/path.c
+++ b/android/utils/path.c
@@ -219,6 +219,8 @@
path_exists( const char* path )
{
int ret;
+ if (path == NULL)
+ return 0;
CHECKED(ret, access(path, F_OK));
return (ret == 0) || (errno != ENOENT);
}
@@ -230,6 +232,8 @@
int ret;
struct stat st;
+ if (path == NULL)
+ return 0;
CHECKED(ret, stat(path, &st));
if (ret < 0)
return 0;
@@ -245,6 +249,8 @@
int ret;
struct stat st;
+ if (path == NULL)
+ return 0;
CHECKED(ret, stat(path, &st));
if (ret < 0)
return 0;
@@ -257,6 +263,8 @@
path_can_read( const char* path )
{
int ret;
+ if (path == NULL)
+ return 0;
CHECKED(ret, access(path, R_OK));
return (ret == 0);
}
@@ -265,6 +273,8 @@
path_can_write( const char* path )
{
int ret;
+ if (path == NULL)
+ return 0;
CHECKED(ret, access(path, R_OK));
return (ret == 0);
}
@@ -273,6 +283,8 @@
path_can_exec( const char* path )
{
int ret;
+ if (path == NULL)
+ return 0;
CHECKED(ret, access(path, X_OK));
return (ret == 0);
}