AI 149397: ADT 1807821 and 1841824: Fixes in android tool
- Bug 1807821: create avd -f option does nothing. - Bug 1841824: NPE during AVD delete or update. BUG=1841824,1807821 Automated import of CL 149397
This commit is contained in:
committed by
The Android Open Source Project
parent
838143199e
commit
6f56ebc737
@@ -454,16 +454,18 @@ class Main {
|
||||
|
||||
// display some extra values.
|
||||
Map<String, String> properties = info.getProperties();
|
||||
String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
|
||||
if (skin != null) {
|
||||
mSdkLog.printf(" Skin: %s\n", skin);
|
||||
}
|
||||
String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
|
||||
if (sdcard == null) {
|
||||
sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
|
||||
}
|
||||
if (sdcard != null) {
|
||||
mSdkLog.printf(" Sdcard: %s\n", sdcard);
|
||||
if (properties != null) {
|
||||
String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
|
||||
if (skin != null) {
|
||||
mSdkLog.printf(" Skin: %s\n", skin);
|
||||
}
|
||||
String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
|
||||
if (sdcard == null) {
|
||||
sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
|
||||
}
|
||||
if (sdcard != null) {
|
||||
mSdkLog.printf(" Sdcard: %s\n", sdcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +510,7 @@ class Main {
|
||||
}
|
||||
|
||||
try {
|
||||
boolean removePrevious = false;
|
||||
boolean removePrevious = mSdkCommandLine.getFlagForce();
|
||||
AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
|
||||
|
||||
String avdName = mSdkCommandLine.getParamName();
|
||||
@@ -522,8 +524,7 @@ class Main {
|
||||
|
||||
AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
|
||||
if (info != null) {
|
||||
if (mSdkCommandLine.getFlagForce()) {
|
||||
removePrevious = true;
|
||||
if (removePrevious) {
|
||||
mSdkLog.warning(
|
||||
"Android Virtual Device '%s' already exists and will be replaced.",
|
||||
avdName);
|
||||
|
||||
@@ -44,7 +44,7 @@ import java.util.regex.Pattern;
|
||||
* Android Virtual Device Manager to manage AVDs.
|
||||
*/
|
||||
public final class AvdManager {
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown when something is wrong with a target path.
|
||||
*/
|
||||
@@ -55,16 +55,16 @@ public final class AvdManager {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final String AVD_FOLDER_EXTENSION = ".avd";
|
||||
|
||||
public final static String AVD_INFO_PATH = "path";
|
||||
public final static String AVD_INFO_TARGET = "target";
|
||||
|
||||
|
||||
/**
|
||||
* AVD/config.ini key name representing the SDK-relative path of the skin folder, if any,
|
||||
* or a 320x480 like constant for a numeric skin size.
|
||||
*
|
||||
*
|
||||
* @see #NUMERIC_SKIN_SIZE
|
||||
*/
|
||||
public final static String AVD_INI_SKIN_PATH = "skin.path";
|
||||
@@ -79,14 +79,14 @@ public final class AvdManager {
|
||||
* AVD/config.ini key name representing the path to the sdcard file.
|
||||
* If missing, the default name "sdcard.img" will be used for the sdcard, if there's such
|
||||
* a file.
|
||||
*
|
||||
*
|
||||
* @see #SDCARD_IMG
|
||||
*/
|
||||
public final static String AVD_INI_SDCARD_PATH = "sdcard.path";
|
||||
/**
|
||||
* AVD/config.ini key name representing the size of the SD card.
|
||||
* This property is for UI purposes only. It is not used by the emulator.
|
||||
*
|
||||
*
|
||||
* @see #SDCARD_SIZE_PATTERN
|
||||
*/
|
||||
public final static String AVD_INI_SDCARD_SIZE = "sdcard.size";
|
||||
@@ -101,7 +101,7 @@ public final class AvdManager {
|
||||
/**
|
||||
* AVD/config.ini key name representing the second path where the emulator looks
|
||||
* for system images. Typically this is the path to the platform system image.
|
||||
*
|
||||
*
|
||||
* @see #AVD_INI_IMAGES_1
|
||||
*/
|
||||
public final static String AVD_INI_IMAGES_2 = "image.sysdir.2";
|
||||
@@ -129,7 +129,7 @@ public final class AvdManager {
|
||||
|
||||
/** An immutable structure describing an Android Virtual Device. */
|
||||
public static final class AvdInfo {
|
||||
|
||||
|
||||
/**
|
||||
* Status for an {@link AvdInfo}. Indicates whether or not this AVD is valid.
|
||||
*/
|
||||
@@ -149,7 +149,7 @@ public final class AvdManager {
|
||||
/** System Image folder in config.ini doesn't exist */
|
||||
ERROR_IMAGE_DIR;
|
||||
}
|
||||
|
||||
|
||||
private final String mName;
|
||||
private final String mPath;
|
||||
private final String mTargetHash;
|
||||
@@ -158,11 +158,11 @@ public final class AvdManager {
|
||||
private final AvdStatus mStatus;
|
||||
|
||||
/**
|
||||
* Creates a new valid AVD info. Values are immutable.
|
||||
* Creates a new valid AVD info. Values are immutable.
|
||||
* <p/>
|
||||
* Such an AVD is available and can be used.
|
||||
* The error string is set to null.
|
||||
*
|
||||
*
|
||||
* @param name The name of the AVD (for display or reference)
|
||||
* @param path The path to the config.ini file
|
||||
* @param targetHash the target hash
|
||||
@@ -175,17 +175,17 @@ public final class AvdManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <em>invalid</em> AVD info. Values are immutable.
|
||||
* Creates a new <em>invalid</em> AVD info. Values are immutable.
|
||||
* <p/>
|
||||
* Such an AVD is not complete and cannot be used.
|
||||
* The error string must be non-null.
|
||||
*
|
||||
*
|
||||
* @param name The name of the AVD (for display or reference)
|
||||
* @param path The path to the config.ini file
|
||||
* @param targetHash the target hash
|
||||
* @param target The target. Can be null, if the target was not resolved.
|
||||
* @param properties The property map. Can be null.
|
||||
* @param error The error describing why this AVD is invalid. Cannot be null.
|
||||
* @param status The {@link AvdStatus} of this AVD. Cannot be null.
|
||||
*/
|
||||
public AvdInfo(String name, String path, String targetHash, IAndroidTarget target,
|
||||
Map<String, String> properties, AvdStatus status) {
|
||||
@@ -193,7 +193,7 @@ public final class AvdManager {
|
||||
mPath = path;
|
||||
mTargetHash = targetHash;
|
||||
mTarget = target;
|
||||
mProperties = Collections.unmodifiableMap(properties);
|
||||
mProperties = properties == null ? null : Collections.unmodifiableMap(properties);
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ public final class AvdManager {
|
||||
public String getPath() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the target hash string.
|
||||
*/
|
||||
@@ -214,7 +214,7 @@ public final class AvdManager {
|
||||
return mTargetHash;
|
||||
}
|
||||
|
||||
/** Returns the target of the AVD, or <code>null</code> if it has not been resolved */
|
||||
/** Returns the target of the AVD, or <code>null</code> if it has not been resolved. */
|
||||
public IAndroidTarget getTarget() {
|
||||
return mTarget;
|
||||
}
|
||||
@@ -224,8 +224,8 @@ public final class AvdManager {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns the .ini {@link File} for a given AVD name.
|
||||
/**
|
||||
* Helper method that returns the .ini {@link File} for a given AVD name.
|
||||
* @throws AndroidLocationException if there's a problem getting android root directory.
|
||||
*/
|
||||
public static File getIniFile(String name) throws AndroidLocationException {
|
||||
@@ -234,35 +234,35 @@ public final class AvdManager {
|
||||
return new File(avdRoot, name + INI_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the .ini {@link File} for this AVD.
|
||||
/**
|
||||
* Returns the .ini {@link File} for this AVD.
|
||||
* @throws AndroidLocationException if there's a problem getting android root directory.
|
||||
*/
|
||||
public File getIniFile() throws AndroidLocationException {
|
||||
return getIniFile(mName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns the Config {@link File} for a given AVD name.
|
||||
|
||||
/**
|
||||
* Helper method that returns the Config {@link File} for a given AVD name.
|
||||
*/
|
||||
public static File getConfigFile(String path) {
|
||||
return new File(path, CONFIG_INI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Config {@link File} for this AVD.
|
||||
|
||||
/**
|
||||
* Returns the Config {@link File} for this AVD.
|
||||
*/
|
||||
public File getConfigFile() {
|
||||
return getConfigFile(mPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of properties for the AVD.
|
||||
* Returns an unmodifiable map of properties for the AVD. This can be null.
|
||||
*/
|
||||
public Map<String, String> getProperties() {
|
||||
return mProperties;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the error message for the AVD or <code>null</code> if {@link #getStatus()}
|
||||
* returns {@link AvdStatus#OK}
|
||||
@@ -293,7 +293,7 @@ public final class AvdManager {
|
||||
} catch (AndroidLocationException e) {
|
||||
return "Unable to get HOME folder.";
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,7 @@ public final class AvdManager {
|
||||
list.add(avd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mValidAvdList = list.toArray(new AvdInfo[list.size()]);
|
||||
}
|
||||
return mValidAvdList;
|
||||
@@ -384,7 +384,7 @@ public final class AvdManager {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reloads the AVD list.
|
||||
* @throws AndroidLocationException if there was an error finding the location of the
|
||||
@@ -405,19 +405,20 @@ public final class AvdManager {
|
||||
|
||||
/**
|
||||
* Creates a new AVD. It is expected that there is no existing AVD with this name already.
|
||||
*
|
||||
* @param avdFolder the data folder for the AVD. It will be created as needed.
|
||||
* @param name the name of the AVD
|
||||
* @param target the target of the AVD
|
||||
* @param skinName the name of the skin. Can be null. Must have been verified by caller.
|
||||
* @param sdcard the parameter value for the sdCard. Can be null. This is either a path to
|
||||
* an existing sdcard image or a sdcard size (\d+, \d+K, \dM).
|
||||
* @param hardwareConfig the hardware setup for the AVD
|
||||
* @param hardwareConfig the hardware setup for the AVD. Can be null to use defaults.
|
||||
* @param removePrevious If true remove any previous files.
|
||||
*/
|
||||
public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
|
||||
String skinName, String sdcard, Map<String,String> hardwareConfig,
|
||||
boolean removePrevious) {
|
||||
|
||||
|
||||
File iniFile = null;
|
||||
boolean needCleanup = false;
|
||||
try {
|
||||
@@ -446,33 +447,33 @@ public final class AvdManager {
|
||||
// writes the userdata.img in it.
|
||||
String imagePath = target.getPath(IAndroidTarget.IMAGES);
|
||||
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) {
|
||||
mSdkLog.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, USERDATA_IMG);
|
||||
FileOutputStream fos = new FileOutputStream(userdataDest);
|
||||
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = fis.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, count);
|
||||
}
|
||||
|
||||
|
||||
fos.close();
|
||||
fis.close();
|
||||
|
||||
|
||||
// Config file.
|
||||
HashMap<String, String> values = new HashMap<String, String>();
|
||||
|
||||
@@ -480,9 +481,9 @@ public final class AvdManager {
|
||||
needCleanup = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Now the skin.
|
||||
if (skinName == null) {
|
||||
if (skinName == null || skinName.length() == 0) {
|
||||
skinName = target.getDefaultSkin();
|
||||
}
|
||||
|
||||
@@ -505,7 +506,7 @@ public final class AvdManager {
|
||||
values.put(AVD_INI_SKIN_NAME, skinName);
|
||||
}
|
||||
|
||||
if (sdcard != null) {
|
||||
if (sdcard != null && sdcard.length() > 0) {
|
||||
File sdcardFile = new File(sdcard);
|
||||
if (sdcardFile.isFile()) {
|
||||
// sdcard value is an external sdcard, so we put its path into the config.ini
|
||||
@@ -513,31 +514,31 @@ public final class AvdManager {
|
||||
} else {
|
||||
// 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);
|
||||
String path = sdcardFile.getAbsolutePath();
|
||||
|
||||
|
||||
// execute mksdcard with the proper parameters.
|
||||
File toolsFolder = new File(mSdk.getLocation(), SdkConstants.FD_TOOLS);
|
||||
File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
|
||||
|
||||
|
||||
if (mkSdCard.isFile() == false) {
|
||||
mSdkLog.error(null, "'%1$s' is missing from the SDK tools folder.",
|
||||
mkSdCard.getName());
|
||||
needCleanup = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path) == false) {
|
||||
needCleanup = true;
|
||||
return null; // mksdcard output has already been displayed, no need to
|
||||
// output anything else.
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
@@ -560,7 +561,7 @@ public final class AvdManager {
|
||||
|
||||
File configIniFile = new File(avdFolder, CONFIG_INI);
|
||||
writeIniFile(configIniFile, values);
|
||||
|
||||
|
||||
if (mSdkLog != null) {
|
||||
if (target.isPlatform()) {
|
||||
mSdkLog.printf("Created AVD '%1$s' based on %2$s\n", name, target.getName());
|
||||
@@ -569,17 +570,19 @@ public final class AvdManager {
|
||||
target.getVendor());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create the AvdInfo object, and add it to the list
|
||||
AvdInfo avdInfo = new AvdInfo(name, avdFolder.getAbsolutePath(), target.hashString(),
|
||||
AvdInfo newAvdInfo = new AvdInfo(name,
|
||||
avdFolder.getAbsolutePath(),
|
||||
target.hashString(),
|
||||
target, values);
|
||||
|
||||
|
||||
synchronized (mAllAvdList) {
|
||||
mAllAvdList.add(avdInfo);
|
||||
mAllAvdList.add(newAvdInfo);
|
||||
mValidAvdList = mBrokenAvdList = null;
|
||||
}
|
||||
|
||||
return avdInfo;
|
||||
|
||||
return newAvdInfo;
|
||||
} catch (AndroidLocationException e) {
|
||||
if (mSdkLog != null) {
|
||||
mSdkLog.error(e, null);
|
||||
@@ -593,12 +596,12 @@ public final class AvdManager {
|
||||
if (iniFile != null && iniFile.exists()) {
|
||||
iniFile.delete();
|
||||
}
|
||||
|
||||
|
||||
recursiveDelete(avdFolder);
|
||||
avdFolder.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -618,7 +621,7 @@ public final class AvdManager {
|
||||
assert false;
|
||||
throw new InvalidTargetPathException("Target location is not inside the SDK.");
|
||||
}
|
||||
|
||||
|
||||
File folder = new File(imageFullPath);
|
||||
if (folder.isDirectory()) {
|
||||
String[] list = folder.list(new FilenameFilter() {
|
||||
@@ -632,36 +635,36 @@ public final class AvdManager {
|
||||
if (imageFullPath.charAt(0) == File.separatorChar) {
|
||||
imageFullPath = imageFullPath.substring(1);
|
||||
}
|
||||
|
||||
|
||||
return imageFullPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the path to the skin, as a relative path to the SDK.
|
||||
*/
|
||||
private String getSkinRelativePath(String skinName, IAndroidTarget target) {
|
||||
// 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) {
|
||||
mSdkLog.error(null, "Skin '%1$s' does not exist.", skinName);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// get the skin path
|
||||
path = skin.getAbsolutePath();
|
||||
|
||||
@@ -683,7 +686,7 @@ public final class AvdManager {
|
||||
|
||||
/**
|
||||
* Creates the ini file for an AVD.
|
||||
*
|
||||
*
|
||||
* @param name of the AVD.
|
||||
* @param avdFolder path for the data folder of the AVD.
|
||||
* @param target of the AVD.
|
||||
@@ -700,10 +703,10 @@ public final class AvdManager {
|
||||
|
||||
return iniFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the ini file for an AVD.
|
||||
*
|
||||
*
|
||||
* @param info of the AVD.
|
||||
* @throws AndroidLocationException if there's a problem getting android root directory.
|
||||
* @throws IOException if {@link File#getAbsolutePath()} fails.
|
||||
@@ -722,13 +725,14 @@ public final class AvdManager {
|
||||
* could not be loaded due to some error. That means this method still tries to remove
|
||||
* the AVD ini file or its folder if it can be found. An error will be output if any of
|
||||
* these operations fail.
|
||||
*
|
||||
*
|
||||
* @param avdInfo the information on the AVD to delete
|
||||
* @return True if the AVD was deleted with no error.
|
||||
*/
|
||||
public void deleteAvd(AvdInfo avdInfo, ISdkLog log) {
|
||||
try {
|
||||
boolean error = false;
|
||||
|
||||
|
||||
File f = avdInfo.getIniFile();
|
||||
if (f != null && f.exists()) {
|
||||
log.warning("Deleting file %1$s", f.getCanonicalPath());
|
||||
@@ -766,22 +770,22 @@ public final class AvdManager {
|
||||
log.error(e, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves and/or rename an existing AVD and its files.
|
||||
* This also change it in the manager's list.
|
||||
* <p/>
|
||||
* The caller should make sure the name or path given are valid, do not exist and are
|
||||
* actually different than current values.
|
||||
*
|
||||
*
|
||||
* @param avdInfo the information on the AVD to move.
|
||||
* @param newName the new name of the AVD if non null.
|
||||
* @param paramFolderPath the new data folder if non null.
|
||||
* @return True if the move succeeded or there was nothing to do.
|
||||
* If false, this method will have had already output error in the log.
|
||||
* If false, this method will have had already output error in the log.
|
||||
*/
|
||||
public boolean moveAvd(AvdInfo avdInfo, String newName, String paramFolderPath, ISdkLog log) {
|
||||
|
||||
|
||||
try {
|
||||
if (paramFolderPath != null) {
|
||||
File f = new File(avdInfo.getPath());
|
||||
@@ -791,7 +795,7 @@ public final class AvdManager {
|
||||
avdInfo.getPath(), paramFolderPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// update AVD info
|
||||
AvdInfo info = new AvdInfo(avdInfo.getName(), paramFolderPath,
|
||||
avdInfo.getTargetHash(), avdInfo.getTarget(), avdInfo.getProperties());
|
||||
@@ -804,10 +808,10 @@ public final class AvdManager {
|
||||
if (newName != null) {
|
||||
File oldIniFile = avdInfo.getIniFile();
|
||||
File newIniFile = AvdInfo.getIniFile(newName);
|
||||
|
||||
|
||||
log.warning("Moving '%1$s' to '%2$s'.", oldIniFile.getPath(), newIniFile.getPath());
|
||||
if (!oldIniFile.renameTo(newIniFile)) {
|
||||
log.error(null, "Failed to move '%1$s' to '%2$s'.",
|
||||
log.error(null, "Failed to move '%1$s' to '%2$s'.",
|
||||
oldIniFile.getPath(), newIniFile.getPath());
|
||||
return false;
|
||||
}
|
||||
@@ -832,7 +836,7 @@ public final class AvdManager {
|
||||
|
||||
/**
|
||||
* Helper method to recursively delete a folder's content (but not the folder itself).
|
||||
*
|
||||
*
|
||||
* @throws SecurityException like {@link File#delete()} does if file/folder is not writable.
|
||||
*/
|
||||
public void recursiveDelete(File folder) {
|
||||
@@ -849,7 +853,7 @@ public final class AvdManager {
|
||||
* <p/>
|
||||
* This lists the $HOME/.android/avd/<name>.ini files.
|
||||
* Such files are properties file than then indicate where the AVD folder is located.
|
||||
*
|
||||
*
|
||||
* @return A new {@link File} array or null. The array might be empty.
|
||||
* @throws AndroidLocationException if there's a problem getting android root directory.
|
||||
*/
|
||||
@@ -867,7 +871,7 @@ public final class AvdManager {
|
||||
folder.mkdirs();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
File[] avds = folder.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File parent, String name) {
|
||||
if (INI_NAME_PATTERN.matcher(name).matches()) {
|
||||
@@ -879,14 +883,14 @@ public final class AvdManager {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return avds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the internal list of available AVDs
|
||||
* @param allList the list to contain all the AVDs
|
||||
*
|
||||
*
|
||||
* @throws AndroidLocationException if there's a problem getting android root directory.
|
||||
*/
|
||||
private void buildAvdList(ArrayList<AvdInfo> allList) throws AndroidLocationException {
|
||||
@@ -903,12 +907,10 @@ public final class AvdManager {
|
||||
|
||||
/**
|
||||
* Parses an AVD .ini file to create an {@link AvdInfo}.
|
||||
*
|
||||
*
|
||||
* @param path The path to the AVD .ini file
|
||||
* @param acceptError When false, an AVD that fails to load will be discarded and null will be
|
||||
* returned. When true, such an AVD will be returned with an error description.
|
||||
* @return A new {@link AvdInfo} or null if the file is not valid or null if the AVD is not
|
||||
* valid and acceptError is false.
|
||||
* @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is
|
||||
* valid or not.
|
||||
*/
|
||||
private AvdInfo parseAvdInfo(File path) {
|
||||
Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
|
||||
@@ -919,7 +921,7 @@ public final class AvdManager {
|
||||
IAndroidTarget target = null;
|
||||
File configIniFile = null;
|
||||
Map<String, String> properties = null;
|
||||
|
||||
|
||||
if (targetHash != null) {
|
||||
target = mSdk.getTargetFromHashString(targetHash);
|
||||
}
|
||||
@@ -928,7 +930,7 @@ public final class AvdManager {
|
||||
if (avdPath != null) {
|
||||
configIniFile = new File(avdPath, CONFIG_INI);
|
||||
}
|
||||
|
||||
|
||||
if (configIniFile != null) {
|
||||
properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog);
|
||||
}
|
||||
@@ -939,7 +941,7 @@ public final class AvdManager {
|
||||
if (matcher.matches()) {
|
||||
name = matcher.group(1);
|
||||
}
|
||||
|
||||
|
||||
// check the image.sysdir are valid
|
||||
boolean validImageSysdir = true;
|
||||
if (properties != null) {
|
||||
@@ -961,7 +963,7 @@ public final class AvdManager {
|
||||
}
|
||||
|
||||
AvdStatus status;
|
||||
|
||||
|
||||
if (avdPath == null) {
|
||||
status = AvdStatus.ERROR_PATH;
|
||||
} else if (configIniFile == null) {
|
||||
@@ -977,7 +979,7 @@ public final class AvdManager {
|
||||
} else {
|
||||
status = AvdStatus.OK;
|
||||
}
|
||||
|
||||
|
||||
AvdInfo info = new AvdInfo(
|
||||
name,
|
||||
avdPath,
|
||||
@@ -985,13 +987,13 @@ public final class AvdManager {
|
||||
target,
|
||||
properties,
|
||||
status);
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a .ini file from a set of properties.
|
||||
*
|
||||
*
|
||||
* @param iniFile The file to generate.
|
||||
* @param values THe properties to place in the ini file.
|
||||
* @throws IOException if {@link FileWriter} fails to open, write or close the file.
|
||||
@@ -999,20 +1001,19 @@ public final class AvdManager {
|
||||
private static void writeIniFile(File iniFile, Map<String, String> values)
|
||||
throws IOException {
|
||||
FileWriter writer = new FileWriter(iniFile);
|
||||
|
||||
|
||||
for (Entry<String, String> entry : values.entrySet()) {
|
||||
writer.write(String.format("%1$s=%2$s\n", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invokes the tool to create a new SD card image file.
|
||||
*
|
||||
*
|
||||
* @param toolLocation The path to the mksdcard tool.
|
||||
* @param size The size of the new SD Card, compatible with {@link #SDCARD_SIZE_PATTERN}.
|
||||
* @param location The path of the new sdcard image file to generate.
|
||||
* @param log The logger object, to report errors.
|
||||
* @return True if the sdcard could be created.
|
||||
*/
|
||||
private boolean createSdCard(String toolLocation, String size, String location) {
|
||||
@@ -1022,7 +1023,7 @@ public final class AvdManager {
|
||||
command[1] = size;
|
||||
command[2] = location;
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
|
||||
|
||||
ArrayList<String> errorOutput = new ArrayList<String>();
|
||||
ArrayList<String> stdOutput = new ArrayList<String>();
|
||||
int status = grabProcessOutput(process, errorOutput, stdOutput,
|
||||
@@ -1041,7 +1042,7 @@ public final class AvdManager {
|
||||
} catch (IOException e) {
|
||||
// pass, print error below
|
||||
}
|
||||
|
||||
|
||||
mSdkLog.error(null, "Failed to create the SD card.");
|
||||
return false;
|
||||
}
|
||||
@@ -1052,7 +1053,7 @@ public final class AvdManager {
|
||||
* @param process The process to get the ouput from
|
||||
* @param errorOutput The array to store the stderr output. cannot be null.
|
||||
* @param stdOutput The array to store the stdout output. cannot be null.
|
||||
* @param waitforReaders if true, this will wait for the reader threads.
|
||||
* @param waitforReaders if true, this will wait for the reader threads.
|
||||
* @return the process return code.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@@ -1129,7 +1130,7 @@ public final class AvdManager {
|
||||
|
||||
/**
|
||||
* Removes an {@link AvdInfo} from the internal list.
|
||||
*
|
||||
*
|
||||
* @param avdInfo The {@link AvdInfo} to remove.
|
||||
* @return true if this {@link AvdInfo} was present and has been removed.
|
||||
*/
|
||||
@@ -1140,15 +1141,15 @@ public final class AvdManager {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an AVD with new path to the system image folders.
|
||||
* @param name the name of the AVD to update.
|
||||
* @throws IOException
|
||||
* @throws AndroidLocationException
|
||||
* @throws IOException
|
||||
* @throws AndroidLocationException
|
||||
*/
|
||||
public void updateAvd(String name) throws IOException, AndroidLocationException {
|
||||
// find the AVD to update. It should be be in the broken list.
|
||||
@@ -1161,7 +1162,7 @@ public final class AvdManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (avd == null) {
|
||||
// not in the broken list, just return.
|
||||
mSdkLog.error(null, "There is no Android Virtual Device named '%s'.", name);
|
||||
@@ -1173,22 +1174,24 @@ public final class AvdManager {
|
||||
|
||||
// create a new map
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
properties.putAll(oldProperties);
|
||||
|
||||
if (oldProperties != null) {
|
||||
properties.putAll(oldProperties);
|
||||
}
|
||||
|
||||
AvdStatus status;
|
||||
|
||||
|
||||
// create the path to the new system images.
|
||||
if (setImagePathProperties(avd.getTarget(), properties)) {
|
||||
if (properties.containsKey(AVD_INI_IMAGES_1)) {
|
||||
mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_1,
|
||||
properties.get(AVD_INI_IMAGES_1));
|
||||
}
|
||||
|
||||
|
||||
if (properties.containsKey(AVD_INI_IMAGES_2)) {
|
||||
mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2,
|
||||
properties.get(AVD_INI_IMAGES_2));
|
||||
}
|
||||
|
||||
|
||||
status = AvdStatus.OK;
|
||||
} else {
|
||||
mSdkLog.error(null, "Unable to find non empty system images folders for %1$s", name);
|
||||
@@ -1211,7 +1214,7 @@ public final class AvdManager {
|
||||
avd.getTarget(),
|
||||
properties,
|
||||
status);
|
||||
|
||||
|
||||
replaceAvd(avd, newAvd);
|
||||
}
|
||||
|
||||
@@ -1224,18 +1227,18 @@ public final class AvdManager {
|
||||
private boolean setImagePathProperties(IAndroidTarget target, Map<String, String> properties) {
|
||||
properties.remove(AVD_INI_IMAGES_1);
|
||||
properties.remove(AVD_INI_IMAGES_2);
|
||||
|
||||
|
||||
try {
|
||||
String property = AVD_INI_IMAGES_1;
|
||||
|
||||
|
||||
// First the image folders of the target itself
|
||||
String imagePath = getImageRelativePath(target);
|
||||
if (imagePath != null) {
|
||||
properties.put(property, imagePath);
|
||||
property = AVD_INI_IMAGES_2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// If the target is an add-on we need to add the Platform image as a backup.
|
||||
IAndroidTarget parent = target.getParent();
|
||||
if (parent != null) {
|
||||
@@ -1244,16 +1247,16 @@ public final class AvdManager {
|
||||
properties.put(property, imagePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we need at least one path!
|
||||
return properties.containsKey(AVD_INI_IMAGES_1);
|
||||
} catch (InvalidTargetPathException e) {
|
||||
mSdkLog.error(e, e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces an old {@link AvdInfo} with a new one in the lists storing them.
|
||||
* @param oldAvd the {@link AvdInfo} to remove.
|
||||
|
||||
Reference in New Issue
Block a user