* To use, call {@link #parseArgs(String[])} and then
* call {@link #getValue(String, String, String)}.
*/
-public class CommandLineProcessor {
+class CommandLineProcessor {
/** Internal verb name for internally hidden flags. */
public final static String GLOBAL_FLAG_VERB = "@@internal@@";
* is actually the tools dir, in which case this is used to get the original CWD. */
private final static String WORKDIR = "com.android.sdkmanager.workdir";
+ /** Value returned by {@link #resolveTargetName(String)} when the target id does not match. */
+ private final static int INVALID_TARGET_ID = 0;
+
private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
*/
private void createProject() {
// get the target and try to resolve it.
- int targetId = mSdkCommandLine.getParamTargetId();
+ int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
IAndroidTarget[] targets = mSdkManager.getTargets();
if (targetId < 1 || targetId > targets.length) {
errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
private void updateProject() {
// get the target and try to resolve it.
IAndroidTarget target = null;
- int targetId = mSdkCommandLine.getParamTargetId();
+ int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
if (targetId >= 0) {
IAndroidTarget[] targets = mSdkManager.getTargets();
if (targetId < 1 || targetId > targets.length) {
int index = 1;
for (IAndroidTarget target : mSdkManager.getTargets()) {
- mSdkLog.printf("id: %d\n", index);
+ mSdkLog.printf("id: %1$d or \"%2$s\"\n", index, target.hashString());
mSdkLog.printf(" Name: %s\n", target.getName());
if (target.isPlatform()) {
mSdkLog.printf(" Type: Platform\n");
*/
private void createAvd() {
// find a matching target
- int targetId = mSdkCommandLine.getParamTargetId();
+ int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
IAndroidTarget target = null;
if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
"Android Virtual Device '%s' already exists and will be replaced.",
avdName);
} else {
- errorAndExit("Android Virtual Device '%s' already exists.", avdName);
+ errorAndExit("Android Virtual Device '%s' already exists.\n" +
+ "Use --force if you want to replace it.",
+ avdName);
return;
}
}
skin = null;
}
- if (skin != null) {
+ if (skin != null && target != null) {
boolean valid = false;
// Is it a know skin name for this target?
for (String s : target.getSkins()) {
}
Map<String, String> hardwareConfig = null;
- if (target.isPlatform()) {
+ if (target != null && target.isPlatform()) {
try {
hardwareConfig = promptForHardware(target, skinHardwareConfig);
} catch (IOException e) {
}
}
+ @SuppressWarnings("unused") // oldAvdInfo is never read, yet useful for debugging
AvdInfo oldAvdInfo = null;
if (removePrevious) {
oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/);
}
+ @SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging
AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
avdName,
target,
mSdkLog.error(null, format, args);
System.exit(1);
}
+
+ /**
+ * Converts a symbolic target name (such as those accepted by --target on the command-line)
+ * to an internal target index id. A valid target name is either a numeric target id (> 0)
+ * or a target hash string.
+ * <p/>
+ * If the given target can't be mapped, {@link #INVALID_TARGET_ID} (0) is returned.
+ * It's up to the caller to output an error.
+ * <p/>
+ * On success, returns a value > 0.
+ */
+ private int resolveTargetName(String targetName) {
+
+ if (targetName == null) {
+ return INVALID_TARGET_ID;
+ }
+
+ targetName = targetName.trim();
+
+ // Case of an integer number
+ if (targetName.matches("[0-9]*")) {
+ try {
+ int n = Integer.parseInt(targetName);
+ return n < 1 ? INVALID_TARGET_ID : n;
+ } catch (NumberFormatException e) {
+ // Ignore. Should not happen.
+ }
+ }
+
+ // Let's try to find a platform or addon name.
+ IAndroidTarget[] targets = mSdkManager.getTargets();
+ for (int i = 0; i < targets.length; i++) {
+ if (targetName.equals(targets[i].hashString())) {
+ return i + 1;
+ }
+ }
+
+ return INVALID_TARGET_ID;
+ }
}
/**
* Specific command-line flags for the {@link SdkManager}.
*/
-public class SdkCommandLine extends CommandLineProcessor {
+class SdkCommandLine extends CommandLineProcessor {
public final static String VERB_LIST = "list";
public final static String VERB_CREATE = "create";
define(Mode.STRING, true,
VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
"Name of the new AVD", null);
- define(Mode.INTEGER, true,
+ define(Mode.STRING, true,
VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
"Target id of the new AVD", null);
define(Mode.STRING, false,
VERB_CREATE, OBJECT_PROJECT,
"p", KEY_PATH,
"Location path of new project", null);
- define(Mode.INTEGER, true,
+ define(Mode.STRING, true,
VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
"Target id of the new project", null);
define(Mode.STRING, true,
VERB_UPDATE, OBJECT_PROJECT,
"p", KEY_PATH,
"Location path of the project", null);
- define(Mode.INTEGER, true,
+ define(Mode.STRING, true,
VERB_UPDATE, OBJECT_PROJECT,
"t", KEY_TARGET_ID,
"Target id to set for the project", -1);
/** Helper to retrieve the --path value. */
public String getParamLocationPath() {
- return ((String) getValue(null, null, KEY_PATH));
+ return (String) getValue(null, null, KEY_PATH);
}
- /** Helper to retrieve the --target id value. */
- public int getParamTargetId() {
- return ((Integer) getValue(null, null, KEY_TARGET_ID)).intValue();
+ /**
+ * Helper to retrieve the --target id value.
+ * The id is a string. It can be one of:
+ * - an integer, in which case it's the index of the target (cf "android list targets")
+ * - a symbolic name such as android-N for platforn API N
+ * - a symbolic add-on name such as written in the avd/*.ini files,
+ * e.g. "Google Inc.:Google APIs:3"
+ */
+ public String getParamTargetId() {
+ return (String) getValue(null, null, KEY_TARGET_ID);
}
/** Helper to retrieve the --name value. */
public String getParamName() {
- return ((String) getValue(null, null, KEY_NAME));
+ return (String) getValue(null, null, KEY_NAME);
}
/** Helper to retrieve the --skin value. */
public String getParamSkin() {
- return ((String) getValue(null, null, KEY_SKIN));
+ return (String) getValue(null, null, KEY_SKIN);
}
/** Helper to retrieve the --sdcard value. */
public String getParamSdCard() {
- return ((String) getValue(null, null, KEY_SDCARD));
+ return (String) getValue(null, null, KEY_SDCARD);
}
/** Helper to retrieve the --force flag. */
/** Helper to retrieve the --rename value for a move verb. */
public String getParamMoveNewName() {
- return ((String) getValue(VERB_MOVE, null, KEY_RENAME));
+ return (String) getValue(VERB_MOVE, null, KEY_RENAME);
}
private IAndroidTarget[] mTargets;
/**
+ * Create a new {@link SdkManager} instance.
+ * External users should use {@link #createManager(String, ISdkLog)}.
+ *
+ * @param sdkLocation the location of the SDK.
+ */
+ private SdkManager(String sdkLocation) {
+ mSdkLocation = sdkLocation;
+ }
+
+ /**
* Creates an {@link SdkManager} for a given sdk location.
* @param sdkLocation the location of the SDK.
* @param log the ISdkLog object receiving warning/error from the parsing.
/**
* Returns the targets that are available in the SDK.
+ * <p/>
+ * The array can be empty but not null.
*/
public IAndroidTarget[] getTargets() {
return mTargets;
}
/**
+ * Sets the targets that are available in the SDK.
+ * <p/>
+ * The array can be empty but not null.
+ */
+ private void setTargets(IAndroidTarget[] targets) {
+ assert targets != null;
+ mTargets = targets;
+ }
+
+ /**
* Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.
*
* @param hash the {@link IAndroidTarget} hash string.
setTargets(list.toArray(new IAndroidTarget[list.size()]));
}
- private SdkManager(String sdkLocation) {
- mSdkLocation = sdkLocation;
- }
-
- private void setTargets(IAndroidTarget[] targets) {
- mTargets = targets;
- }
-
/**
* Loads the Platforms from the SDK.
* @param location Location of the SDK