auto import from //branches/cupcake/...@132276

This commit is contained in:
The Android Open Source Project
2009-02-19 10:57:29 -08:00
parent 87a88c4f03
commit ff4b5f241f
37 changed files with 961 additions and 505 deletions

View File

@@ -69,6 +69,7 @@ final class AddOnTarget implements IAndroidTarget {
private final String mVendor;
private final String mDescription;
private String[] mSkins;
private String mDefaultSkin;
private IOptionalLibrary[] mLibraries;
/**
@@ -141,6 +142,10 @@ final class AddOnTarget implements IAndroidTarget {
return false;
}
public IAndroidTarget getParent() {
return mBasePlatform;
}
public String getPath(int pathId) {
switch (pathId) {
case IMAGES:
@@ -157,6 +162,10 @@ final class AddOnTarget implements IAndroidTarget {
public String[] getSkins() {
return mSkins;
}
public String getDefaultSkin() {
return mDefaultSkin;
}
public IOptionalLibrary[] getOptionalLibraries() {
return mLibraries;
@@ -236,7 +245,9 @@ final class AddOnTarget implements IAndroidTarget {
// ---- local methods.
public void setSkins(String[] skins) {
public void setSkins(String[] skins, String defaultSkin) {
mDefaultSkin = defaultSkin;
// we mix the add-on and base platform skins
HashSet<String> skinSet = new HashSet<String>();
skinSet.addAll(Arrays.asList(skins));

View File

@@ -60,6 +60,14 @@ public interface IAndroidTarget extends Comparable<IAndroidTarget> {
public static int SOURCES = 18;
/** OS Path to the target specific docs */
public static int DOCS = 19;
/** OS Path to the target's version of the aapt tool. */
public static int AAPT = 20;
/** OS Path to the target's version of the aidl tool. */
public static int AIDL = 21;
/** OS Path to the target's version of the dx too. */
public static int DX = 22;
/** OS Path to the target's version of the dx.jar file. */
public static int DX_JAR = 23;
public interface IOptionalLibrary {
String getName();
@@ -108,6 +116,12 @@ public interface IAndroidTarget extends Comparable<IAndroidTarget> {
*/
boolean isPlatform();
/**
* Returns the parent target. This is likely to only be non <code>null</code> if
* {@link #isPlatform()} returns <code>false</code>
*/
IAndroidTarget getParent();
/**
* Returns the path of a platform component.
* @param pathId the id representing the path to return. Any of the constants defined in the
@@ -120,6 +134,11 @@ public interface IAndroidTarget extends Comparable<IAndroidTarget> {
*/
String[] getSkins();
/**
* Returns the default skin for this target.
*/
String getDefaultSkin();
/**
* Returns the available optional libraries for this target.
* @return an array of optional libraries or <code>null</code> if there is none.

View File

@@ -75,8 +75,13 @@ final class PlatformTarget implements IAndroidTarget {
SdkConstants.FN_INTENT_ACTIONS_SERVICE);
mPaths.put(CATEGORIES, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
SdkConstants.FN_INTENT_CATEGORIES);
mPaths.put(AAPT, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT);
mPaths.put(AIDL, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL);
mPaths.put(DX, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX);
mPaths.put(DX_JAR, mLocation + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER +
SdkConstants.FN_DX_JAR);
}
public String getLocation() {
return mLocation;
}
@@ -123,6 +128,10 @@ final class PlatformTarget implements IAndroidTarget {
return true;
}
public IAndroidTarget getParent() {
return null;
}
public String getPath(int pathId) {
return mPaths.get(pathId);
}
@@ -130,6 +139,11 @@ final class PlatformTarget implements IAndroidTarget {
public String[] getSkins() {
return mSkins;
}
public String getDefaultSkin() {
// at this time, this is the default skin for all the platform.
return "HVGA";
}
/*
* Always returns null, as a standard platforms have no optional libraries.

View File

@@ -30,7 +30,18 @@ import java.io.File;
*
*/
public final class SdkConstants {
public final static int PLATFORM_UNKNOWN = 0;
public final static int PLATFORM_LINUX = 1;
public final static int PLATFORM_WINDOWS = 2;
public final static int PLATFORM_DARWIN = 3;
/**
* Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
*/
public final static int CURRENT_PLATFORM = currentPlatform();
/** An SDK Project's AndroidManifest.xml file */
public static final String FN_ANDROID_MANIFEST_XML= "AndroidManifest.xml";
/** An SDK Project's build.xml file */
@@ -69,6 +80,21 @@ public final class SdkConstants {
/** Skin layout file */
public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$
/** dex.jar file */
public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
/** dx executable */
public final static String FN_DX = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"dx.bat" : "dx"; //$NON-NLS-1$ //$NON-NLS-2$
/** aapt executable */
public final static String FN_AAPT = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"aapt.exe" : "aapt"; //$NON-NLS-1$ //$NON-NLS-2$
/** aidl executable */
public final static String FN_AIDL = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
"aidl.exe" : "aidl"; //$NON-NLS-1$ //$NON-NLS-2$
/* Folder Names for Android Projects . */
/** Resources folder name, i.e. "res". */
@@ -142,11 +168,11 @@ public final class SdkConstants {
* This is an OS path, ending with a separator. */
public final static String OS_SDK_DOCS_FOLDER = FD_DOCS + File.separator;
/** Path of the tools directory relative to the sdk folder.
/** Path of the tools directory relative to the sdk folder, or to a platform folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_TOOLS_FOLDER = FD_TOOLS + File.separator;
/** Path of the lib directory relative to the sdk folder.
/** Path of the lib directory relative to the sdk folder, or to a platform folder.
* This is an OS path, ending with a separator. */
public final static String OS_SDK_TOOLS_LIB_FOLDER =
OS_SDK_TOOLS_FOLDER + FD_LIB + File.separator;
@@ -233,4 +259,22 @@ public final class SdkConstants {
return cmd;
}
/**
* Returns current platform
*
* @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
* {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
*/
private static int currentPlatform() {
String os = System.getProperty("os.name"); //$NON-NLS-1$
if (os.startsWith("Mac OS")) { //$NON-NLS-1$
return PLATFORM_DARWIN;
} else if (os.startsWith("Windows")) { //$NON-NLS-1$
return PLATFORM_WINDOWS;
} else if (os.startsWith("Linux")) { //$NON-NLS-1$
return PLATFORM_LINUX;
}
return PLATFORM_UNKNOWN;
}
}

View File

@@ -44,6 +44,7 @@ public final class SdkManager {
private final static String ADDON_API = "api";
private final static String ADDON_DESCRIPTION = "description";
private final static String ADDON_LIBRARIES = "libraries";
private final static String ADDON_DEFAULT_SKIN = "skin";
private final static Pattern PATTERN_PROP = Pattern.compile(
"^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$");
@@ -51,6 +52,17 @@ public final class SdkManager {
private final static Pattern PATTERN_LIB_DATA = Pattern.compile(
"^([a-zA-Z0-9._-]+\\.jar);(.*)$", Pattern.CASE_INSENSITIVE);
/** List of items in the platform to check when parsing it. These paths are relative to the
* platform root folder. */
private final static String[] sPlatformContentList = new String[] {
SdkConstants.FN_FRAMEWORK_LIBRARY,
SdkConstants.FN_FRAMEWORK_AIDL,
SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT,
SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL,
SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX,
SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + SdkConstants.FN_DX_JAR,
};
/** the location of the SDK */
private final String mSdkLocation;
private IAndroidTarget[] mTargets;
@@ -176,6 +188,10 @@ public final class SdkManager {
String apiNumber = map.get(PROP_VERSION_SDK);
String apiName = map.get(PROP_VERSION_RELEASE);
if (apiNumber != null && apiName != null) {
// api number and name looks valid, perform a few more checks
if (checkPlatformContent(platform, log) == false) {
return null;
}
// create the target.
PlatformTarget target = new PlatformTarget(
platform.getAbsolutePath(),
@@ -351,7 +367,19 @@ public final class SdkManager {
// need to parse the skins.
String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
target.setSkins(skins);
// get the default skin, or take it from the base platform if needed.
String defaultSkin = propertyMap.get(ADDON_DEFAULT_SKIN);
if (defaultSkin == null) {
if (skins.length == 1) {
defaultSkin = skins[1];
} else {
defaultSkin = baseTarget.getDefaultSkin();
}
}
target.setSkins(skins, defaultSkin);
return target;
}
@@ -369,7 +397,28 @@ public final class SdkManager {
addonName, valueName, SdkConstants.FN_MANIFEST_INI);
}
}
/**
* Checks the given platform has all the required files, and returns true if they are all
* present.
* <p/>This checks the presence of the following files: android.jar, framework.aidl, aapt(.exe),
* aidl(.exe), dx(.bat), and dx.jar
*/
private boolean checkPlatformContent(File platform, ISdkLog log) {
for (String relativePath : sPlatformContentList) {
File f = new File(platform, relativePath);
if (f.exists() == false) {
log.error(null,
"Ignoring platform '%1$s': %2$s is missing.",
platform.getName(), relativePath);
return false;
}
}
return true;
}
/**
* Parses a property file and returns
* @param buildProp the property file to parse

View File

@@ -44,28 +44,42 @@ import java.util.regex.Pattern;
public final class AvdManager {
public static final String AVD_FOLDER_EXTENSION = ".avd";
private final static String AVD_INFO_PATH = "path";
private final static String AVD_INFO_TARGET = "target";
public final static String AVD_INI_SKIN_PATH = "skin.path";
public final static String AVD_INI_SKIN_NAME = "skin.name";
public final static String AVD_INI_SDCARD_PATH = "sdcard.path";
public final static String AVD_INI_SDCARD_SIZE = "sdcard.size";
public final static String AVD_INI_IMAGES_1 = "image.sysdir.1";
public final static String AVD_INI_IMAGES_2 = "image.sysdir.2";
private final static String IMAGE_USERDATA = "userdata.img";
private final static String USERDATA_IMG = "userdata.img";
private final static String CONFIG_INI = "config.ini";
private final static String SDCARD_IMG = "sdcard.img";
private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\.ini$",
private final static String INI_EXTENSION = ".ini";
private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\" + INI_EXTENSION + "$",
Pattern.CASE_INSENSITIVE);
private final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("\\d+[MK]?");
/** An immutable structure describing an Android Virtual Device. */
public static final class AvdInfo {
private String mName;
private String mPath;
private IAndroidTarget mTarget;
private final String mName;
private final String mPath;
private final IAndroidTarget mTarget;
private final Map<String, String> mProperties;
/** Creates a new AVD info. Valures are immutable. */
public AvdInfo(String name, String path, IAndroidTarget target) {
/** Creates a new AVD info. Valures are immutable.
* @param properties */
public AvdInfo(String name, String path, IAndroidTarget target,
Map<String, String> properties) {
mName = name;
mPath = path;
mTarget = target;
mProperties = properties;
}
/** Returns the name of the AVD. */
@@ -90,7 +104,7 @@ public final class AvdManager {
public static File getIniFile(String name) throws AndroidLocationException {
String avdRoot;
avdRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
return new File(avdRoot, name + ".ini");
return new File(avdRoot, name + INI_EXTENSION);
}
/**
@@ -100,6 +114,13 @@ public final class AvdManager {
public File getIniFile() throws AndroidLocationException {
return getIniFile(mName);
}
/**
* Returns a map of properties for the AVD.
*/
public Map<String, String> getProperties() {
return mProperties;
}
}
private final ArrayList<AvdInfo> mAvdList = new ArrayList<AvdInfo>();
@@ -149,6 +170,8 @@ public final class AvdManager {
String skinName, String sdcard, Map<String,String> hardwareConfig,
boolean removePrevious, ISdkLog log) {
File iniFile = null;
boolean needCleanup = false;
try {
if (avdFolder.exists()) {
if (removePrevious) {
@@ -170,14 +193,27 @@ public final class AvdManager {
}
// actually write the ini file
createAvdIniFile(name, avdFolder, target);
iniFile = createAvdIniFile(name, avdFolder, target);
// writes the userdata.img in it.
String imagePath = target.getPath(IAndroidTarget.IMAGES);
File userdataSrc = new File(imagePath, IMAGE_USERDATA);
File userdataSrc = new File(imagePath, USERDATA_IMG);
if (userdataSrc.exists() == false && target.isPlatform() == false) {
imagePath = target.getParent().getPath(IAndroidTarget.IMAGES);
userdataSrc = new File(imagePath, USERDATA_IMG);
}
if (userdataSrc.exists() == false) {
log.error(null, "Unable to find a '%1$s' file to copy into the AVD folder.",
USERDATA_IMG);
needCleanup = true;
return null;
}
FileInputStream fis = new FileInputStream(userdataSrc);
File userdataDest = new File(avdFolder, IMAGE_USERDATA);
File userdataDest = new File(avdFolder, USERDATA_IMG);
FileOutputStream fos = new FileOutputStream(userdataDest);
byte[] buffer = new byte[4096];
@@ -189,23 +225,61 @@ public final class AvdManager {
fos.close();
fis.close();
// Config file
// Config file.
HashMap<String, String> values = new HashMap<String, String>();
if (skinName != null) {
// assume skin name is valid
values.put("skin", skinName);
// First the image folders of the target itself
imagePath = getImageRelativePath(target, log);
if (imagePath == null) {
needCleanup = true;
return null;
}
values.put(AVD_INI_IMAGES_1, imagePath);
// If the target is an add-on we need to add the Platform image as a backup.
IAndroidTarget parent = target.getParent();
if (parent != null) {
imagePath = getImageRelativePath(parent, log);
if (imagePath == null) {
needCleanup = true;
return null;
}
values.put(AVD_INI_IMAGES_2, imagePath);
}
// Now the skin.
if (skinName == null) {
skinName = target.getDefaultSkin();
}
// get the path of the skin (relative to the SDK)
// assume skin name is valid
String skinPath = getSkinRelativePath(skinName, target, log);
if (skinPath == null) {
needCleanup = true;
return null;
}
values.put(AVD_INI_SKIN_PATH, skinPath);
values.put(AVD_INI_SKIN_NAME, skinName);
if (sdcard != null) {
File sdcardFile = new File(sdcard);
if (sdcardFile.isFile()) {
values.put("sdcard", sdcard);
// sdcard value is an external sdcard, so we put its path into the config.ini
values.put(AVD_INI_SDCARD_PATH, sdcard);
} else {
// check that it matches the pattern for sdcard size
// Sdcard is possibly a size. In that case we create a file called 'sdcard.img'
// in the AVD folder, and do not put any value in config.ini.
// First, check that it matches the pattern for sdcard size
Matcher m = SDCARD_SIZE_PATTERN.matcher(sdcard);
if (m.matches()) {
// create the sdcard.
sdcardFile = new File(avdFolder, "sdcard.img");
sdcardFile = new File(avdFolder, SDCARD_IMG);
String path = sdcardFile.getAbsolutePath();
// execute mksdcard with the proper parameters.
@@ -215,18 +289,27 @@ public final class AvdManager {
if (mkSdCard.isFile() == false) {
log.error(null, "'%1$s' is missing from the SDK tools folder.",
mkSdCard.getName());
needCleanup = true;
return null;
}
if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) {
needCleanup = true;
return null; // mksdcard output has already been displayed, no need to
// output anything else.
}
// add its path to the values.
values.put("sdcard", path);
// add a property containing the size of the sdcard for display purpose
// only when the dev does 'android list avd'
values.put(AVD_INI_SDCARD_SIZE, sdcard);
} else {
log.error(null, "'%1$s' is not recognized as a valid sdcard value", sdcard);
log.error(null,
"'%1$s' is not recognized as a valid sdcard value.\n" +
"Value should be:\n" +
"1. path to an sdcard.\n" +
"2. size of the sdcard to create: <size>[K|M]",
sdcard);
needCleanup = true;
return null;
}
}
@@ -249,7 +332,7 @@ public final class AvdManager {
}
// create the AvdInfo object, and add it to the list
AvdInfo avdInfo = new AvdInfo(name, avdFolder.getAbsolutePath(), target);
AvdInfo avdInfo = new AvdInfo(name, avdFolder.getAbsolutePath(), target, values);
mAvdList.add(avdInfo);
@@ -262,11 +345,83 @@ public final class AvdManager {
if (log != null) {
log.error(e, null);
}
} finally {
if (needCleanup) {
if (iniFile != null && iniFile.exists()) {
iniFile.delete();
}
recursiveDelete(avdFolder);
avdFolder.delete();
}
}
return null;
}
/**
* Returns the path to the target images folder as a relative path to the SDK.
*/
private String getImageRelativePath(IAndroidTarget target, ISdkLog log) {
String imageFullPath = target.getPath(IAndroidTarget.IMAGES);
// make this path relative to the SDK location
String sdkLocation = mSdk.getLocation();
if (imageFullPath.startsWith(sdkLocation) == false) {
// this really really should not happen.
log.error(null, "Target location is not inside the SDK.");
assert false;
return null;
}
imageFullPath = imageFullPath.substring(sdkLocation.length());
if (imageFullPath.charAt(0) == File.separatorChar) {
imageFullPath = imageFullPath.substring(1);
}
return imageFullPath;
}
/**
* Returns the path to the skin, as a relative path to the SDK.
*/
private String getSkinRelativePath(String skinName, IAndroidTarget target, ISdkLog log) {
// first look to see if the skin is in the target
String path = target.getPath(IAndroidTarget.SKINS);
File skin = new File(path, skinName);
if (skin.exists() == false && target.isPlatform() == false) {
target = target.getParent();
path = target.getPath(IAndroidTarget.SKINS);
skin = new File(path, skinName);
}
// skin really does not exist!
if (skin.exists() == false) {
log.error(null, "Skin '%1$s' does not exist.", skinName);
return null;
}
// get the skin path
path = skin.getAbsolutePath();
// make this path relative to the SDK location
String sdkLocation = mSdk.getLocation();
if (path.startsWith(sdkLocation) == false) {
// this really really should not happen.
log.error(null, "Target location is not inside the SDK.");
assert false;
return null;
}
path = path.substring(sdkLocation.length());
if (path.charAt(0) == File.separatorChar) {
path = path.substring(1);
}
return path;
}
/**
* Creates the ini file for an AVD.
*
@@ -276,13 +431,15 @@ public final class AvdManager {
* @throws AndroidLocationException if there's a problem getting android root directory.
* @throws IOException if {@link File#getAbsolutePath()} fails.
*/
private void createAvdIniFile(String name, File avdFolder, IAndroidTarget target)
private File createAvdIniFile(String name, File avdFolder, IAndroidTarget target)
throws AndroidLocationException, IOException {
HashMap<String, String> values = new HashMap<String, String>();
File iniFile = AvdInfo.getIniFile(name);
values.put(AVD_INFO_PATH, avdFolder.getAbsolutePath());
values.put(AVD_INFO_TARGET, target.hashString());
createConfigIni(iniFile, values);
return iniFile;
}
/**
@@ -292,8 +449,8 @@ public final class AvdManager {
* @throws AndroidLocationException if there's a problem getting android root directory.
* @throws IOException if {@link File#getAbsolutePath()} fails.
*/
private void createAvdIniFile(AvdInfo info) throws AndroidLocationException, IOException {
createAvdIniFile(info.getName(), new File(info.getPath()), info.getTarget());
private File createAvdIniFile(AvdInfo info) throws AndroidLocationException, IOException {
return createAvdIniFile(info.getName(), new File(info.getPath()), info.getTarget());
}
/**
@@ -306,8 +463,6 @@ public final class AvdManager {
*/
public void deleteAvd(AvdInfo avdInfo, ISdkLog log) {
try {
String avdRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
File f = avdInfo.getIniFile();
if (f.exists()) {
log.warning("Deleting file %s", f.getCanonicalPath());
@@ -359,7 +514,8 @@ public final class AvdManager {
}
// update avd info
AvdInfo info = new AvdInfo(avdInfo.getName(), paramFolderPath, avdInfo.getTarget());
AvdInfo info = new AvdInfo(avdInfo.getName(), paramFolderPath, avdInfo.getTarget(),
avdInfo.getProperties());
mAvdList.remove(avdInfo);
mAvdList.add(info);
avdInfo = info;
@@ -380,7 +536,8 @@ public final class AvdManager {
}
// update avd info
AvdInfo info = new AvdInfo(newName, avdInfo.getPath(), avdInfo.getTarget());
AvdInfo info = new AvdInfo(newName, avdInfo.getPath(), avdInfo.getTarget(),
avdInfo.getProperties());
mAvdList.remove(avdInfo);
mAvdList.add(info);
}
@@ -458,18 +615,22 @@ public final class AvdManager {
if (target == null) {
return null;
}
// load the avd properties.
File configIniFile = new File(avdPath, CONFIG_INI);
Map<String, String> properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog);
Matcher matcher = INI_NAME_PATTERN.matcher(path.getName());
AvdInfo info = new AvdInfo(
matcher.matches() ? matcher.group(1) : path.getName(), // should not happen
avdPath,
target
);
target,
properties);
return info;
}
private static void createConfigIni(File iniFile, Map<String, String> values)
throws IOException {
FileWriter writer = new FileWriter(iniFile);

View File

@@ -33,6 +33,7 @@ import java.util.Map.Entry;
public final class ProjectProperties {
/** The property name for the project target */
public final static String PROPERTY_TARGET = "target";
public final static String PROPERTY_CONFIGS = "configs";
public final static String PROPERTY_SDK = "sdk-location";
public static enum PropertyType {
@@ -201,6 +202,14 @@ public final class ProjectProperties {
public String getProperty(String name) {
return mProperties.get(name);
}
/**
* Removes a property and returns its previous value (or null if the property did not exist).
* @param name the name of the property to remove.
*/
public String removeProperty(String name) {
return mProperties.remove(name);
}
/**
* Saves the property file.