aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2011-02-28 14:11:44 -0800
committerRaphael Moll <ralf@android.com>2011-03-04 13:39:40 -0800
commit4b108747f5c837bb3d149551e9bb94bed0f83424 (patch)
tree2a149b2048d5574a669deb11ef55a1e200290392 /sdkmanager
parentbf5bf083f5d7cc95e0351fdda4038f7806ffbebf (diff)
downloadsdk-4b108747f5c837bb3d149551e9bb94bed0f83424.zip
sdk-4b108747f5c837bb3d149551e9bb94bed0f83424.tar.gz
sdk-4b108747f5c837bb3d149551e9bb94bed0f83424.tar.bz2
Don't erase SDCard when editing existing AVD.
SDK Bug 14162 Change-Id: I22493443e706bda830916ed0fc09741a1d6d1f15
Diffstat (limited to 'sdkmanager')
-rw-r--r--sdkmanager/app/src/com/android/sdkmanager/Main.java19
-rw-r--r--sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java28
-rw-r--r--sdkmanager/app/tests/com/android/sdkmanager/MainTest.java29
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java274
-rw-r--r--sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java141
5 files changed, 328 insertions, 163 deletions
diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java
index 8cb88ae..4b0581f 100644
--- a/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -985,15 +985,16 @@ public class Main {
String preferredAbi = SdkConstants.ABI_ARMEABI;
@SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging
AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
- avdName,
- target,
- preferredAbi,
- skin,
- mSdkCommandLine.getParamSdCard(),
- hardwareConfig,
- removePrevious,
- mSdkCommandLine.getFlagSnapshot(),
- mSdkLog);
+ avdName,
+ target,
+ preferredAbi,
+ skin,
+ mSdkCommandLine.getParamSdCard(),
+ hardwareConfig,
+ mSdkCommandLine.getFlagSnapshot(),
+ removePrevious,
+ false, //edit existing
+ mSdkLog);
} catch (AndroidLocationException e) {
errorAndExit(e.getMessage());
diff --git a/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java b/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java
index cc8d6a4..9579bf5 100644
--- a/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java
+++ b/sdkmanager/app/tests/com/android/sdkmanager/AvdManagerTest.java
@@ -59,8 +59,18 @@ public class AvdManagerTest extends TestCase {
public void testCreateAvdWithoutSnapshot() {
mAvdManager.createAvd(
- mAvdFolder, this.getName(), mTarget, SdkConstants.ABI_ARMEABI,
- null, null, null, false, false, mLog);
+ mAvdFolder,
+ this.getName(),
+ mTarget,
+ SdkConstants.ABI_ARMEABI,
+ null, // skinName
+ null, // sdName
+ null, // properties
+ false, // createSnapshot
+ false, // removePrevious
+ false, // editExisting
+ mLog);
+
assertEquals("[P Created AVD '" + this.getName() + "' based on Android 0.0, ARM (armeabi) processor\n]",
mLog.toString());
assertTrue("Expected config.ini in " + mAvdFolder,
@@ -78,9 +88,19 @@ public class AvdManagerTest extends TestCase {
}
public void testCreateAvdWithSnapshot() {
+
mAvdManager.createAvd(
- mAvdFolder, this.getName(), mTarget, SdkConstants.ABI_ARMEABI,
- null, null, null, false, true, mLog);
+ mAvdFolder,
+ this.getName(),
+ mTarget,
+ SdkConstants.ABI_ARMEABI,
+ null, // skinName
+ null, // sdName
+ null, // properties
+ true, // createSnapshot
+ false, // removePrevious
+ false, // editExisting
+ mLog);
assertEquals("[P Created AVD '" + this.getName() + "' based on Android 0.0, ARM (armeabi) processor\n]",
mLog.toString());
diff --git a/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java b/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java
index e4352ff..c4a7a53 100644
--- a/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java
+++ b/sdkmanager/app/tests/com/android/sdkmanager/MainTest.java
@@ -69,8 +69,18 @@ public class MainTest extends TestCase {
Main main = new Main();
main.setLogger(mLog);
mAvdManager.createAvd(
- mAvdFolder, this.getName(), mTarget, SdkConstants.ABI_ARMEABI,
- null, null, null, false, false, mLog);
+ mAvdFolder,
+ this.getName(),
+ mTarget,
+ SdkConstants.ABI_ARMEABI,
+ null, // skinName
+ null, // sdName
+ null, // properties
+ false, // createSnapshot
+ false, // removePrevious
+ false, // editExisting
+ mLog);
+
mLog.clear();
main.displayAvdList(mAvdManager);
assertEquals(
@@ -86,9 +96,20 @@ public class MainTest extends TestCase {
public void testDisplayAvdListOfOneSnapshot() {
Main main = new Main();
main.setLogger(mLog);
+
mAvdManager.createAvd(
- mAvdFolder, this.getName(), mTarget, SdkConstants.ABI_ARMEABI,
- null, null, null, false, true, mLog);
+ mAvdFolder,
+ this.getName(),
+ mTarget,
+ SdkConstants.ABI_ARMEABI,
+ null, // skinName
+ null, // sdName
+ null, // properties
+ true, // createSnapshot
+ false, // removePrevious
+ false, // editExisting
+ mLog);
+
mLog.clear();
main.displayAvdList(mAvdManager);
assertEquals(
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
index fefe891..038a59e 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
@@ -100,6 +100,7 @@ public final class AvdManager {
* This property is for UI purposes only. It is not used by the emulator.
*
* @see #SDCARD_SIZE_PATTERN
+ * @see #parseSdcardSize(String, String[])
*/
public final static String AVD_INI_SDCARD_SIZE = "sdcard.size"; //$NON-NLS-1$
/**
@@ -145,18 +146,27 @@ public final class AvdManager {
/**
* Pattern for matching SD Card sizes, e.g. "4K" or "16M".
+ * Callers should use {@link #parseSdcardSize(String, String[])} instead of using this directly.
*/
- public final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("(\\d+)([KMG])"); //$NON-NLS-1$
+ private final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("(\\d+)([KMG])"); //$NON-NLS-1$
/**
* Minimal size of an SDCard image file in bytes. Currently 9 MiB.
*/
+
public static final long SDCARD_MIN_BYTE_SIZE = 9<<20;
/**
* Maximal size of an SDCard image file in bytes. Currently 1023 GiB.
*/
public static final long SDCARD_MAX_BYTE_SIZE = 1023L<<30;
+ /** The sdcard string represents a valid number but the size is outside of the allowed range. */
+ public final static int SDCARD_SIZE_NOT_IN_RANGE = 0;
+ /** The sdcard string looks like a size number+suffix but the number failed to decode. */
+ public final static int SDCARD_SIZE_INVALID = -1;
+ /** The sdcard string doesn't look like a size, it might be a path instead. */
+ public final static int SDCARD_NOT_SIZE_PATTERN = -2;
+
/** Regex used to validate characters that compose an AVD name. */
public final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+"); //$NON-NLS-1$
@@ -487,6 +497,71 @@ public final class AvdManager {
}
/**
+ * Parse the sdcard string to decode the size.
+ * Returns:
+ * <ul>
+ * <li> The size in bytes > 0 if the sdcard string is a valid size in the allowed range.
+ * <li> {@link #SDCARD_SIZE_NOT_IN_RANGE} (0)
+ * if the sdcard string is a valid size NOT in the allowed range.
+ * <li> {@link #SDCARD_SIZE_INVALID} (-1)
+ * if the sdcard string is number that fails to parse correctly.
+ * <li> {@link #SDCARD_NOT_SIZE_PATTERN} (-2)
+ * if the sdcard string is not a number, in which case it's probably a file path.
+ * </ul>
+ *
+ * @param sdcard The sdcard string, which can be a file path, a size string or something else.
+ * @param parsedStrings If non-null, an array of 2 strings. The first string will be
+ * filled with the parsed numeric size and the second one will be filled with the
+ * parsed suffix. This is filled even if the returned size is deemed out of range or
+ * failed to parse. The values are null if the sdcard is not a size pattern.
+ * @return A size in byte if > 0, or {@link #SDCARD_SIZE_NOT_IN_RANGE},
+ * {@link #SDCARD_SIZE_INVALID} or {@link #SDCARD_NOT_SIZE_PATTERN} as error codes.
+ */
+ public static long parseSdcardSize(String sdcard, String[] parsedStrings) {
+
+ if (parsedStrings != null) {
+ assert parsedStrings.length == 2;
+ parsedStrings[0] = null;
+ parsedStrings[1] = null;
+ }
+
+ Matcher m = SDCARD_SIZE_PATTERN.matcher(sdcard);
+ if (m.matches()) {
+ if (parsedStrings != null) {
+ assert parsedStrings.length == 2;
+ parsedStrings[0] = m.group(1);
+ parsedStrings[1] = m.group(2);
+ }
+
+ // get the sdcard values for checks
+ try {
+ long sdcardSize = Long.parseLong(m.group(1));
+
+ String sdcardSizeModifier = m.group(2);
+ if ("K".equals(sdcardSizeModifier)) { //$NON-NLS-1$
+ sdcardSize <<= 10;
+ } else if ("M".equals(sdcardSizeModifier)) { //$NON-NLS-1$
+ sdcardSize <<= 20;
+ } else if ("G".equals(sdcardSizeModifier)) { //$NON-NLS-1$
+ sdcardSize <<= 30;
+ }
+
+ if (sdcardSize < SDCARD_MIN_BYTE_SIZE ||
+ sdcardSize > SDCARD_MAX_BYTE_SIZE) {
+ return SDCARD_SIZE_NOT_IN_RANGE;
+ }
+
+ return sdcardSize;
+ } catch (NumberFormatException e) {
+ // This could happen if the number is too large to fit in a long.
+ return SDCARD_SIZE_INVALID;
+ }
+ }
+
+ return SDCARD_NOT_SIZE_PATTERN;
+ }
+
+ /**
* Returns all the existing AVDs.
* @return a newly allocated array containing all the AVDs.
*/
@@ -636,22 +711,6 @@ public final class AvdManager {
}
/**
- * Creates a new AVD, but with no snapshot.
- *
- * See {@link #createAvd(File, String, IAndroidTarget,
- * String, String,
- * Map, boolean, boolean, ISdkLog)}
- **/
- @Deprecated
- public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
- String abiType, String skinName,
- String sdcard, Map<String, String> hardwareConfig, boolean removePrevious,
- ISdkLog log) {
- return createAvd(avdFolder, name, target, abiType, skinName, sdcard,
- hardwareConfig, removePrevious, false, log);
- }
-
- /**
* 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.
@@ -662,15 +721,26 @@ public final class AvdManager {
* @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. Can be null to use defaults.
- * @param removePrevious If true remove any previous files.
* @param createSnapshot If true copy a blank snapshot image into the AVD.
+ * @param removePrevious If true remove any previous files.
+ * @param editExisting If true, edit an existing AVD, changing only the minimum required.
+ * This won't remove files unless required or unless {@code removePrevious} is set.
* @param log the log object to receive action logs. Cannot be null.
* @return The new {@link AvdInfo} in case of success (which has just been added to the
* internal list) or null in case of failure.
*/
- public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
- String abiType, String skinName, String sdcard, Map<String,String> hardwareConfig,
- boolean removePrevious, boolean createSnapshot, ISdkLog log){
+ public AvdInfo createAvd(
+ File avdFolder,
+ String name,
+ IAndroidTarget target,
+ String abiType,
+ String skinName,
+ String sdcard,
+ Map<String,String> hardwareConfig,
+ boolean createSnapshot,
+ boolean removePrevious,
+ boolean editExisting,
+ ISdkLog log) {
if (log == null) {
throw new IllegalArgumentException("log cannot be null");
}
@@ -687,8 +757,9 @@ public final class AvdManager {
} catch (SecurityException e) {
log.error(e, "Failed to delete %1$s", avdFolder.getAbsolutePath());
}
- } else {
- // AVD shouldn't already exist if removePrevious is false.
+ } else if (!editExisting) {
+ // AVD shouldn't already exist if removePrevious is false and
+ // we're not editing an existing AVD.
log.error(null,
"Folder %1$s is in the way. Use --force if you want to overwrite.",
avdFolder.getAbsolutePath());
@@ -697,6 +768,8 @@ public final class AvdManager {
} else {
// create the AVD folder.
avdFolder.mkdir();
+ // We're not editing an existing AVD.
+ editExisting = false;
}
// actually write the ini file
@@ -742,17 +815,24 @@ public final class AvdManager {
// Create the snapshot file
if (createSnapshot) {
- String toolsLib = mSdkManager.getLocation() + File.separator
- + SdkConstants.OS_SDK_TOOLS_LIB_EMULATOR_FOLDER;
- File snapshotBlank = new File(toolsLib, SNAPSHOTS_IMG);
- if (snapshotBlank.exists() == false) {
- log.error(null, "Unable to find a '%2$s%1$s' file to copy into the AVD folder.",
- SNAPSHOTS_IMG, toolsLib);
- needCleanup = true;
- return null;
- }
File snapshotDest = new File(avdFolder, SNAPSHOTS_IMG);
- copyImageFile(snapshotBlank, snapshotDest);
+ if (snapshotDest.isFile() && editExisting) {
+ log.printf("Snapshot image already present, was not changed.");
+
+ } else {
+ String toolsLib = mSdkManager.getLocation() + File.separator
+ + SdkConstants.OS_SDK_TOOLS_LIB_EMULATOR_FOLDER;
+ File snapshotBlank = new File(toolsLib, SNAPSHOTS_IMG);
+ if (snapshotBlank.exists() == false) {
+ log.error(null,
+ "Unable to find a '%2$s%1$s' file to copy into the AVD folder.",
+ SNAPSHOTS_IMG, toolsLib);
+ needCleanup = true;
+ return null;
+ }
+
+ copyImageFile(snapshotBlank, snapshotDest);
+ }
values.put(AVD_INI_SNAPSHOT_PRESENT, "true");
}
@@ -785,46 +865,48 @@ public final class AvdManager {
}
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
- values.put(AVD_INI_SDCARD_PATH, sdcard);
+ // 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.
+
+ long sdcardSize = parseSdcardSize(sdcard, null/*parsedStrings*/);
+
+ if (sdcardSize == SDCARD_SIZE_NOT_IN_RANGE) {
+ log.error(null, "SD Card size must be in the range 9 MiB..1023 GiB.");
+ needCleanup = true;
+ return null;
+
+ } else if (sdcardSize == SDCARD_SIZE_INVALID) {
+ log.error(null, "Unable to parse SD Card size");
+ needCleanup = true;
+ return null;
+
+ } else if (sdcardSize == SDCARD_NOT_SIZE_PATTERN) {
+ File sdcardFile = new File(sdcard);
+ if (sdcardFile.isFile()) {
+ // sdcard value is an external sdcard, so we put its path into the config.ini
+ values.put(AVD_INI_SDCARD_PATH, sdcard);
+ } else {
+ 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;
+ }
} 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()) {
- // get the sdcard values for checks
- try {
- long sdcardSize = Long.parseLong(m.group(1));
-
- String sdcardSizeModifier = m.group(2);
- if ("K".equals(sdcardSizeModifier)) { //$NON-NLS-1$
- sdcardSize <<= 10;
- } else if ("M".equals(sdcardSizeModifier)) { //$NON-NLS-1$
- sdcardSize <<= 20;
- } else if ("G".equals(sdcardSizeModifier)) { //$NON-NLS-1$
- sdcardSize <<= 30;
- }
-
- if (sdcardSize < SDCARD_MIN_BYTE_SIZE ||
- sdcardSize > SDCARD_MAX_BYTE_SIZE) {
- log.error(null, "SD Card size must be in the range 9 MiB..1023 GiB.");
- needCleanup = true;
- return null;
- }
- } catch (NumberFormatException e) {
- // this should never happen since the string is validated
- // by the regexp
- log.error(null, "Unable to parse SD Card size");
- needCleanup = true;
- return null;
+ // create the sdcard.
+ File sdcardFile = new File(avdFolder, SDCARD_IMG);
+
+ boolean runMkSdcard = true;
+ if (sdcardFile.exists()) {
+ if (sdcardFile.length() == sdcardSize && editExisting) {
+ // There's already an sdcard file with the right size and we're
+ // not overriding it... so don't remove it.
+ runMkSdcard = false;
+ log.printf("SD Card already present with same size, was not changed.");
}
+ }
- // create the sdcard.
- sdcardFile = new File(avdFolder, SDCARD_IMG);
+ if (runMkSdcard) {
String path = sdcardFile.getAbsolutePath();
// execute mksdcard with the proper parameters.
@@ -845,17 +927,11 @@ public final class AvdManager {
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);
- } else {
- 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;
}
+
+ // 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);
}
}
@@ -910,11 +986,21 @@ public final class AvdManager {
StringBuilder report = new StringBuilder();
if (target.isPlatform()) {
- report.append(String.format("Created AVD '%1$s' based on %2$s",
- name, target.getName()));
+ if (editExisting) {
+ report.append(String.format("Updated AVD '%1$s' based on %2$s",
+ name, target.getName()));
+ } else {
+ report.append(String.format("Created AVD '%1$s' based on %2$s",
+ name, target.getName()));
+ }
} else {
- report.append(String.format("Created AVD '%1$s' based on %2$s (%3$s)", name,
- target.getName(), target.getVendor()));
+ if (editExisting) {
+ report.append(String.format("Updated AVD '%1$s' based on %2$s (%3$s)", name,
+ target.getName(), target.getVendor()));
+ } else {
+ report.append(String.format("Created AVD '%1$s' based on %2$s (%3$s)", name,
+ target.getName(), target.getVendor()));
+ }
}
report.append(String.format(", %s processor", AvdInfo.getPrettyAbiType(abiType)));
@@ -939,14 +1025,14 @@ public final class AvdManager {
AvdInfo oldAvdInfo = getAvd(name, false /*validAvdOnly*/);
synchronized (mAllAvdList) {
- if (oldAvdInfo != null && removePrevious) {
+ if (oldAvdInfo != null && (removePrevious || editExisting)) {
mAllAvdList.remove(oldAvdInfo);
}
mAllAvdList.add(newAvdInfo);
mValidAvdList = mBrokenAvdList = null;
}
- if (removePrevious &&
+ if ((removePrevious || editExisting) &&
newAvdInfo != null &&
oldAvdInfo != null &&
!oldAvdInfo.getPath().equals(newAvdInfo.getPath())) {
@@ -1120,14 +1206,18 @@ public final class AvdManager {
IAndroidTarget target,
boolean removePrevious)
throws AndroidLocationException, IOException {
- HashMap<String, String> values = new HashMap<String, String>();
File iniFile = AvdInfo.getIniFile(name);
- if (iniFile.isFile()) {
- iniFile.delete();
- } else if (iniFile.isDirectory()) {
- deleteContentOf(iniFile);
- iniFile.delete();
+
+ if (removePrevious) {
+ if (iniFile.isFile()) {
+ iniFile.delete();
+ } else if (iniFile.isDirectory()) {
+ deleteContentOf(iniFile);
+ iniFile.delete();
+ }
}
+
+ HashMap<String, String> values = new HashMap<String, String>();
values.put(AVD_INFO_PATH, avdFolder.getAbsolutePath());
values.put(AVD_INFO_TARGET, target.hashString());
writeIniFile(iniFile, values);
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
index db6034a..8955c52 100644
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java
@@ -98,6 +98,10 @@ final class AvdCreationDialog extends GridDialog {
private final ArrayList<String> mEditedProperties = new ArrayList<String>();
private final ImageFactory mImageFactory;
private final ISdkLog mSdkLog;
+ /**
+ * The original AvdInfo if we're editing an existing AVD.
+ * Null when we're creating a new AVD.
+ */
private final AvdInfo mEditAvdInfo;
private Text mAvdName;
@@ -157,6 +161,9 @@ final class AvdCreationDialog extends GridDialog {
public void modifyText(ModifyEvent e) {
String name = mAvdName.getText().trim();
if (mEditAvdInfo == null || !name.equals(mEditAvdInfo.getName())) {
+ // Case where we're creating a new AVD or editing an existing one
+ // and the AVD name has been changed... check for name uniqueness.
+
Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name);
if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) {
// If we're changing the state from disabled to enabled, make sure
@@ -172,8 +179,10 @@ final class AvdCreationDialog extends GridDialog {
mForceCreation.setSelection(false);
}
} else {
+ // Case where we're editing an existing AVD with the name unchanged.
+
mForceCreation.setEnabled(false);
- mForceCreation.setSelection(true);
+ mForceCreation.setSelection(false);
}
validatePage();
}
@@ -714,71 +723,78 @@ final class AvdCreationDialog extends GridDialog {
}
Map<String, String> props = mEditAvdInfo.getProperties();
-
- // First try the skin name and if it doesn't work fallback on the skin path
- nextSkin: for (int s = 0; s < 2; s++) {
- String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME
- : AvdManager.AVD_INI_SKIN_PATH);
- if (skin != null && skin.length() > 0) {
- Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin);
- if (m.matches() && m.groupCount() == 2) {
- enableSkinWidgets(false);
- mSkinListRadio.setSelection(false);
- mSkinSizeRadio.setSelection(true);
- mSkinSizeWidth.setText(m.group(1));
- mSkinSizeHeight.setText(m.group(2));
- break nextSkin;
- } else {
- enableSkinWidgets(true);
- mSkinSizeRadio.setSelection(false);
- mSkinListRadio.setSelection(true);
-
- int n = mSkinCombo.getItemCount();
- for (int i = 0; i < n; i++) {
- if (skin.equals(mSkinCombo.getItem(i))) {
- mSkinCombo.select(i);
- break nextSkin;
+ if (props != null) {
+ // First try the skin name and if it doesn't work fallback on the skin path
+ nextSkin: for (int s = 0; s < 2; s++) {
+ String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME
+ : AvdManager.AVD_INI_SKIN_PATH);
+ if (skin != null && skin.length() > 0) {
+ Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin);
+ if (m.matches() && m.groupCount() == 2) {
+ enableSkinWidgets(false);
+ mSkinListRadio.setSelection(false);
+ mSkinSizeRadio.setSelection(true);
+ mSkinSizeWidth.setText(m.group(1));
+ mSkinSizeHeight.setText(m.group(2));
+ break nextSkin;
+ } else {
+ enableSkinWidgets(true);
+ mSkinSizeRadio.setSelection(false);
+ mSkinListRadio.setSelection(true);
+
+ int n = mSkinCombo.getItemCount();
+ for (int i = 0; i < n; i++) {
+ if (skin.equals(mSkinCombo.getItem(i))) {
+ mSkinCombo.select(i);
+ break nextSkin;
+ }
}
}
}
}
- }
- String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH);
- if (sdcard != null && sdcard.length() > 0) {
- enableSdCardWidgets(false);
- mSdCardSizeRadio.setSelection(false);
- mSdCardFileRadio.setSelection(true);
- mSdCardFile.setText(sdcard);
- }
+ String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH);
+ if (sdcard != null && sdcard.length() > 0) {
+ enableSdCardWidgets(false);
+ mSdCardSizeRadio.setSelection(false);
+ mSdCardFileRadio.setSelection(true);
+ mSdCardFile.setText(sdcard);
+ }
+
+ sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE);
+ if (sdcard != null && sdcard.length() > 0) {
- sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE);
- if (sdcard != null && sdcard.length() > 0) {
- Matcher m = AvdManager.SDCARD_SIZE_PATTERN.matcher(sdcard);
- if (m.matches() && m.groupCount() == 2) {
- enableSdCardWidgets(true);
- mSdCardFileRadio.setSelection(false);
- mSdCardSizeRadio.setSelection(true);
-
- mSdCardSize.setText(m.group(1));
-
- String suffix = m.group(2);
- int n = mSdCardSizeCombo.getItemCount();
- for (int i = 0; i < n; i++) {
- if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) {
- mSdCardSizeCombo.select(i);
+ String[] values = new String[2];
+ long sdcardSize = AvdManager.parseSdcardSize(sdcard, values);
+
+ if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) {
+ enableSdCardWidgets(true);
+ mSdCardFileRadio.setSelection(false);
+ mSdCardSizeRadio.setSelection(true);
+
+ mSdCardSize.setText(values[0]);
+
+ String suffix = values[1];
+ int n = mSdCardSizeCombo.getItemCount();
+ for (int i = 0; i < n; i++) {
+ if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) {
+ mSdCardSizeCombo.select(i);
+ }
}
}
}
- }
- String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT);
- if (snapshots != null && snapshots.length() > 0) {
- mSnapshotCheck.setSelection(snapshots.equals("true"));
+ String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT);
+ if (snapshots != null && snapshots.length() > 0) {
+ mSnapshotCheck.setSelection(snapshots.equals("true"));
+ }
}
mProperties.clear();
- mProperties.putAll(props);
+
+ if (props != null) {
+ mProperties.putAll(props);
+ }
// Cleanup known non-hardware properties
mProperties.remove(AvdManager.AVD_INI_ABI_TYPE);
@@ -1030,6 +1046,22 @@ final class AvdCreationDialog extends GridDialog {
}
if (value <= 0) {
error = "SD Card size is invalid. Range is 9 MiB..1023 GiB.";
+ } else if (mEditAvdInfo != null) {
+ // When editing an existing AVD, compare with the existing
+ // sdcard size, if any. It only matters if there was an sdcard setting
+ // before.
+ Map<String, String> props = mEditAvdInfo.getProperties();
+ if (props != null) {
+ String original =
+ mEditAvdInfo.getProperties().get(AvdManager.AVD_INI_SDCARD_SIZE);
+ if (original != null && original.length() > 0) {
+ long originalSize =
+ AvdManager.parseSdcardSize(original, null/*parsedStrings*/);
+ if (originalSize > 0 && value != originalSize) {
+ warning = "A new SD Card file will be created.\nThe current SD Card file will be lost.";
+ }
+ }
+ }
}
}
}
@@ -1298,8 +1330,9 @@ final class AvdCreationDialog extends GridDialog {
skinName,
sdName,
mProperties,
- force,
snapshot,
+ force,
+ mEditAvdInfo != null, //edit existing
log);
success = avdInfo != null;