private int getApiVersion(Element usesSdk, String attribute, int defaultApiLevel) { String valueString = null; if (usesSdk.hasAttributeNS(NS_RESOURCES, attribute)) { valueString = usesSdk.getAttributeNS(NS_RESOURCES, attribute); } if (valueString != null) { int apiLevel = -1; try { apiLevel = Integer.valueOf(valueString); } catch (NumberFormatException e) { // Handle codename if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + valueString); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 apiLevel = target.getVersion().getApiLevel() + 1; } } if (usesSdk.getTagName().equals(ATTRIBUTE_MIN_SDK_VERSION)) { mMinSdkName = valueString; } } return apiLevel; } return defaultApiLevel; }
// The default attributes must be determined dynamically since whether // we use match_parent or fill_parent depends on the API level of the // project @Override String getDefaultAttrs(IProject project, String root) { Sdk currentSdk = Sdk.getCurrent(); String fill = VALUE_FILL_PARENT; if (currentSdk != null) { IAndroidTarget target = currentSdk.getTarget(project); // fill_parent was renamed match_parent in API level 8 if (target != null && target.getVersion().getApiLevel() >= 8) { fill = VALUE_MATCH_PARENT; } } // Only set "vertical" orientation of LinearLayouts by default; // for GridLayouts for example we want to rely on the real default // of the layout String size = String.format( "android:layout_width=\"%1$s\"\n" //$NON-NLS-1$ + "android:layout_height=\"%2$s\"", //$NON-NLS-1$ fill, fill); if (LINEAR_LAYOUT.equals(root)) { return "android:orientation=\"vertical\"\n" + size; // $NON-NLS-1$ } else { return size; } }
/** * Validates the fields, displays errors and warnings. Enables the finish button if there are no * errors. */ private void validatePage() { String error = null; String warning = null; // -- validate type TypeInfo type = mValues.type; if (error == null) { if (type == null) { error = "One of the types must be selected (e.g. layout, values, etc.)"; } } // -- validate project if (mValues.project == null) { error = "Please select an Android project."; } // -- validate type API level if (error == null) { IAndroidTarget target = Sdk.getCurrent().getTarget(mValues.project); int currentApiLevel = 1; if (target != null) { currentApiLevel = target.getVersion().getApiLevel(); } assert type != null; if (type.getTargetApiLevel() > currentApiLevel) { error = "The API level of the selected type (e.g. AppWidget, etc.) is not " + "compatible with the API level of the project."; } } // -- validate filename if (error == null) { String fileName = mValues.getFileName(); assert type != null; ResourceFolderType folderType = type.getResFolderType(); error = ResourceNameValidator.create(true, folderType).isValid(fileName); } // -- validate destination file doesn't exist if (error == null) { IFile file = mValues.getDestinationFile(); if (file != null && file.exists()) { warning = "The destination file already exists"; } } // -- update UI & enable finish if there's no error setPageComplete(error == null); if (error != null) { setMessage(error, IMessageProvider.ERROR); } else if (warning != null) { setMessage(warning, IMessageProvider.WARNING); } else { setErrorMessage(null); setMessage(null); } }
@NonNull public IAndroidTarget[] getMissingTargets() { synchronized (mLocalPackages) { if (mCachedMissingTargets == null) { Map<MissingTarget, MissingTarget> result = Maps.newHashMap(); Set<ISystemImage> seen = Sets.newHashSet(); for (IAndroidTarget target : getTargets()) { Collections.addAll(seen, target.getSystemImages()); } for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_ADDON_SYS_IMAGE)) { LocalAddonSysImgPkgInfo info = (LocalAddonSysImgPkgInfo) local; ISystemImage image = info.getSystemImage(); if (!seen.contains(image)) { addOrphanedSystemImage(image, info.getDesc(), result); } } for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_SYS_IMAGE)) { LocalSysImgPkgInfo info = (LocalSysImgPkgInfo) local; ISystemImage image = info.getSystemImage(); if (!seen.contains(image)) { addOrphanedSystemImage(image, info.getDesc(), result); } } mCachedMissingTargets = result.keySet(); } return mCachedMissingTargets.toArray(new IAndroidTarget[mCachedMissingTargets.size()]); } }
@Nullable public IAndroidTarget findTargetByName(@NotNull String name) { for (IAndroidTarget target : getTargets()) { if (target.getName().equals(name)) { return target; } } return null; }
public void createTestProject() { IAndroidTarget target = null; IAndroidTarget[] targets = getSdk().getTargets(); for (IAndroidTarget t : targets) { if (t.getVersion().getApiLevel() >= TARGET_API_LEVEL) { target = t; break; } } assertNotNull(target); }
@Nullable private String getOldPlatformToolsFolderPath() { String platformLocation; if (myWrapee.isPlatform()) { platformLocation = myWrapee.getLocation(); } else { IAndroidTarget parent = myWrapee.getParent(); platformLocation = parent != null ? parent.getLocation() : null; } if (platformLocation == null) { return null; } return platformLocation + SdkConstants.FD_TOOLS + File.separator; }
@Nullable public IAndroidTarget findTargetByApiLevel(@NotNull String apiLevel) { IAndroidTarget candidate = null; for (IAndroidTarget target : getTargets()) { if (AndroidSdkUtils.targetHasId(target, apiLevel)) { if (target.isPlatform()) { return target; } else if (candidate == null) { candidate = target; } } } return candidate; }
/** * Returns the project's target's hash string. * * <p>If {@link #getTarget()} returns a valid object, then this returns the value of {@link * IAndroidTarget#hashString()}. * * <p>Otherwise this will return the value of the property {@link * ProjectProperties#PROPERTY_TARGET} from {@link #getProperties()} (if valid). * * @return the target hash string or null if not found. */ public String getTargetHashString() { if (mTarget != null) { return mTarget.hashString(); } return mProperties.getProperty(ProjectProperties.PROPERTY_TARGET); }
@Override public boolean equals(Object obj) { if (!(obj instanceof MyTargetWrapper)) { return false; } MyTargetWrapper other = (MyTargetWrapper) obj; return myWrapee.equals(other.myWrapee); }
@Override public String getPath(int pathId) { String path = myAlternativePaths.get(pathId); if (path != null) { return path; } return myWrapee.getPath(pathId); }
/** * Add the available types in the type combobox, based on whether they are available for the * current SDK. * * <p>A type is available either if: - if mProject is null, API level 1 is considered valid - if * mProject is !null, the project->target->API must be >= to the type's API level. */ private void updateAvailableTypes() { IProject project = mValues.project; IAndroidTarget target = project != null ? Sdk.getCurrent().getTarget(project) : null; int currentApiLevel = 1; if (target != null) { currentApiLevel = target.getVersion().getApiLevel(); } List<String> items = new ArrayList<String>(sTypes.length); List<TypeInfo> types = new ArrayList<TypeInfo>(sTypes.length); for (int i = 0, n = sTypes.length; i < n; i++) { TypeInfo type = sTypes[i]; if (type.getTargetApiLevel() <= currentApiLevel) { items.add(type.getUiName()); types.add(type); } } mTypeCombo.setItems(items.toArray(new String[items.size()])); mTypeCombo.setData(types.toArray(new TypeInfo[types.size()])); }
protected IProject createProject(String name) { IAndroidTarget target = null; IAndroidTarget[] targets = getSdk().getTargets(); for (IAndroidTarget t : targets) { if (!t.isPlatform()) { continue; } if (t.getVersion().getApiLevel() >= TARGET_API_LEVEL) { target = t; break; } } assertNotNull(target); IRunnableContext context = new IRunnableContext() { @Override public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { runnable.run(new NullProgressMonitor()); } }; NewProjectWizardState state = new NewProjectWizardState(Mode.ANY); state.projectName = name; state.target = target; state.packageName = TEST_PROJECT_PACKAGE; state.activityName = name; state.applicationName = name; state.createActivity = false; state.useDefaultLocation = true; if (getMinSdk() != -1) { state.minSdk = Integer.toString(getMinSdk()); } NewProjectCreator creator = new NewProjectCreator(state, context); creator.createAndroidProjects(); return validateProjectExists(name); }
/** * Computes the minimum SDK and target SDK versions for the project * * @param project the project to look up the versions for * @return a pair of (minimum SDK, target SDK) versions, never null */ @NonNull public static Pair<Integer, Integer> computeSdkVersions(IProject project) { int mMinSdkVersion = 1; int mTargetSdkVersion = 1; IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project)); if (manifestFile != null) { try { Object value = AndroidManifest.getMinSdkVersion(manifestFile); mMinSdkVersion = 1; // Default case if missing if (value instanceof Integer) { mMinSdkVersion = ((Integer) value).intValue(); } else if (value instanceof String) { // handle codename, only if we can resolve it. if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + value); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 mMinSdkVersion = target.getVersion().getApiLevel() + 1; } } } Integer i = AndroidManifest.getTargetSdkVersion(manifestFile); if (i == null) { mTargetSdkVersion = mMinSdkVersion; } else { mTargetSdkVersion = i.intValue(); } } catch (XPathExpressionException e) { // do nothing we'll use 1 below. } catch (StreamException e) { // do nothing we'll use 1 below. } } return Pair.of(mMinSdkVersion, mTargetSdkVersion); }
/** Computes the changes this wizard will make */ @NonNull List<Change> computeChanges() { if (project == null) { return Collections.emptyList(); } ManifestInfo manifest = ManifestInfo.get(project); parameters.put(ATTR_PACKAGE_NAME, manifest.getPackage()); parameters.put(ATTR_MIN_API, manifest.getMinSdkVersion()); parameters.put(ATTR_MIN_API_LEVEL, manifest.getMinSdkName()); parameters.put(ATTR_TARGET_API, manifest.getTargetSdkVersion()); IAndroidTarget target = Sdk.getCurrent().getTarget(project); int buildApi; if (target != null) { buildApi = target.getVersion().getApiLevel(); } else { buildApi = manifest.getTargetSdkVersion(); } parameters.put(NewProjectWizard.ATTR_BUILD_API, buildApi); return getTemplateHandler().render(project, parameters); }
/** Displays the skins valid for the given target. */ private void displaySkinList(IAndroidTarget target, String message) { String[] skins = target.getSkins(); String defaultSkin = target.getDefaultSkin(); mSdkLog.printf(message); if (skins != null) { boolean first = true; for (String skin : skins) { if (first == false) { mSdkLog.printf(", "); } else { first = false; } mSdkLog.printf(skin); if (skin.equals(defaultSkin)) { mSdkLog.printf(" (default)"); } } mSdkLog.printf("\n"); } else { mSdkLog.printf("no skins.\n"); } }
/** Returns the string used to represent this qualifier in the folder name. */ @Override public String getFolderSegment(IAndroidTarget target) { if (mValue != null) { if (target == null) { // Default behavior (when target==null) is qualifier is supported return mValue.getValue(); } AndroidVersion version = target.getVersion(); if (version.getApiLevel() >= 4 || (version.getApiLevel() == 3 && "Donut".equals(version.getCodename()))) { return mValue.getValue(); } } return ""; //$NON-NLS-1$ }
/** * Returns the default theme for this project, by looking at the manifest default theme * registration, target SDK, rendering target, etc. * * @param renderingTarget the rendering target use to render the theme, or null * @param screenSize the screen size to obtain a default theme for, or null if unknown * @return the theme to use for this project, never null */ @NonNull public String getDefaultTheme(IAndroidTarget renderingTarget, ScreenSize screenSize) { sync(); if (mManifestTheme != null) { return mManifestTheme; } int renderingTargetSdk = mTargetSdk; if (renderingTarget != null) { renderingTargetSdk = renderingTarget.getVersion().getApiLevel(); } int apiLevel = Math.min(mTargetSdk, renderingTargetSdk); // For now this theme works only on XLARGE screens. When it works for all sizes, // add that new apiLevel to this check. if (apiLevel >= 11 && screenSize == ScreenSize.XLARGE || apiLevel >= 14) { return PREFIX_ANDROID_STYLE + "Theme.Holo"; // $NON-NLS-1$ } else { return PREFIX_ANDROID_STYLE + "Theme"; // $NON-NLS-1$ } }
@Override public boolean canRunOn(IAndroidTarget target) { return myWrapee.canRunOn(target); }
/** Displays the list of available Targets (Platforms and Add-ons) */ private void displayTargetList() { mSdkLog.printf("Available Android targets:\n"); int index = 1; for (IAndroidTarget target : mSdkManager.getTargets()) { 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"); mSdkLog.printf(" API level: %s\n", target.getVersion().getApiString()); mSdkLog.printf(" Revision: %d\n", target.getRevision()); } else { mSdkLog.printf(" Type: Add-On\n"); mSdkLog.printf(" Vendor: %s\n", target.getVendor()); mSdkLog.printf(" Revision: %d\n", target.getRevision()); if (target.getDescription() != null) { mSdkLog.printf(" Description: %s\n", target.getDescription()); } mSdkLog.printf( " Based on Android %s (API level %s)\n", target.getVersionName(), target.getVersion().getApiString()); // display the optional libraries. IOptionalLibrary[] libraries = target.getOptionalLibraries(); if (libraries != null) { mSdkLog.printf(" Libraries:\n"); for (IOptionalLibrary library : libraries) { mSdkLog.printf(" * %1$s (%2$s)\n", library.getName(), library.getJarName()); mSdkLog.printf(String.format(" %1$s\n", library.getDescription())); } } } // get the target skins displaySkinList(target, " Skins: "); if (target.getUsbVendorId() != IAndroidTarget.NO_USB_ID) { mSdkLog.printf( " Adds USB support for devices (Vendor: 0x%04X)\n", target.getUsbVendorId()); } index++; } }
/** Creates a new Android test project based on command-line parameters */ private void createTestProject() { String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath()); // first check the path of the parent project, and make sure it's valid. String pathToMainProject = mSdkCommandLine.getParamTestProjectMain(); File parentProject = new File(pathToMainProject); if (parentProject.isAbsolute() == false) { // if the path is not absolute, we need to resolve it based on the // destination path of the project try { parentProject = new File(projectDir, pathToMainProject).getCanonicalFile(); } catch (IOException e) { errorAndExit("Unable to resolve Main project's directory: %1$s", pathToMainProject); return; // help Eclipse static analyzer understand we'll never execute the rest. } } if (parentProject.isDirectory() == false) { errorAndExit("Main project's directory does not exist: %1$s", pathToMainProject); return; } // now look for a manifest in there File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML); if (manifest.isFile() == false) { errorAndExit( "No AndroidManifest.xml file found in the main project directory: %1$s", parentProject.getAbsolutePath()); return; } // now query the manifest for the package file. XPath xpath = AndroidXPathFactory.newXPath(); String packageName, activityName; try { packageName = xpath.evaluate("/manifest/@package", new InputSource(new FileInputStream(manifest))); mSdkLog.printf("Found main project package: %1$s\n", packageName); // now get the name of the first activity we find activityName = xpath.evaluate( "/manifest/application/activity[1]/@android:name", new InputSource(new FileInputStream(manifest))); // xpath will return empty string when there's no match if (activityName == null || activityName.length() == 0) { activityName = null; } else { mSdkLog.printf("Found main project activity: %1$s\n", activityName); } } catch (FileNotFoundException e) { // this shouldn't happen as we test it above. errorAndExit("No AndroidManifest.xml file found in main project."); return; // this is not strictly needed because errorAndExit will stop the execution, // but this makes the java compiler happy, wrt to uninitialized variables. } catch (XPathExpressionException e) { // looks like the main manifest is not valid. errorAndExit("Unable to parse main project manifest to get information."); return; // this is not strictly needed because errorAndExit will stop the execution, // but this makes the java compiler happy, wrt to uninitialized variables. } // now get the target hash ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(), PropertyType.DEFAULT); if (p == null) { errorAndExit("Unable to load the main project's %1$s", PropertyType.DEFAULT.getFilename()); return; } String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET); if (targetHash == null) { errorAndExit("Couldn't find the main project target"); return; } // and resolve it. IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash); if (target == null) { errorAndExit( "Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.", targetHash); return; } mSdkLog.printf("Found main project target: %1$s\n", target.getFullName()); ProjectCreator creator = getProjectCreator(); String projectName = mSdkCommandLine.getParamName(); if (projectName != null && !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) { errorAndExit( "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", projectName, ProjectCreator.CHARS_PROJECT_NAME); return; } creator.createProject( projectDir, projectName, packageName, activityName, target, false /* library*/, pathToMainProject); }
/** * Prompts the user to setup a hardware config for a Platform-based AVD. * * @throws IOException */ private Map<String, String> promptForHardware( IAndroidTarget createTarget, Map<String, String> skinHardwareConfig) throws IOException { byte[] readLineBuffer = new byte[256]; String result; String defaultAnswer = "no"; mSdkLog.printf("%s is a basic Android platform.\n", createTarget.getName()); mSdkLog.printf("Do you wish to create a custom hardware profile [%s]", defaultAnswer); result = readLine(readLineBuffer).trim(); // handle default: if (result.length() == 0) { result = defaultAnswer; } if (getBooleanReply(result) == false) { // no custom config, return the skin hardware config in case there is one. return skinHardwareConfig; } mSdkLog.printf("\n"); // empty line // get the list of possible hardware properties File hardwareDefs = new File( mOsSdkFolder + File.separator + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI); Map<String, HardwareProperty> hwMap = HardwareProperties.parseHardwareDefinitions(hardwareDefs, null /*sdkLog*/); HashMap<String, String> map = new HashMap<String, String>(); // we just want to loop on the HardwareProperties HardwareProperty[] hwProperties = hwMap.values().toArray(new HardwareProperty[hwMap.size()]); for (int i = 0; i < hwProperties.length; ) { HardwareProperty property = hwProperties[i]; String description = property.getDescription(); if (description != null) { mSdkLog.printf("%s: %s\n", property.getAbstract(), description); } else { mSdkLog.printf("%s\n", property.getAbstract()); } String defaultValue = property.getDefault(); String defaultFromSkin = skinHardwareConfig != null ? skinHardwareConfig.get(property.getName()) : null; if (defaultFromSkin != null) { mSdkLog.printf("%s [%s (from skin)]:", property.getName(), defaultFromSkin); } else if (defaultValue != null) { mSdkLog.printf("%s [%s]:", property.getName(), defaultValue); } else { mSdkLog.printf("%s (%s):", property.getName(), property.getType()); } result = readLine(readLineBuffer); if (result.length() == 0) { if (defaultFromSkin != null || defaultValue != null) { if (defaultFromSkin != null) { // we need to write this one in the AVD file map.put(property.getName(), defaultFromSkin); } mSdkLog.printf("\n"); // empty line i++; // go to the next property if we have a valid default value. // if there's no default, we'll redo this property } continue; } switch (property.getType()) { case BOOLEAN: try { if (getBooleanReply(result)) { map.put(property.getName(), "yes"); i++; // valid reply, move to next property } else { map.put(property.getName(), "no"); i++; // valid reply, move to next property } } catch (IOException e) { // display error, and do not increment i to redo this property mSdkLog.printf("\n%s\n", e.getMessage()); } break; case INTEGER: try { Integer.parseInt(result); map.put(property.getName(), result); i++; // valid reply, move to next property } catch (NumberFormatException e) { // display error, and do not increment i to redo this property mSdkLog.printf("\n%s\n", e.getMessage()); } break; case DISKSIZE: // TODO check validity map.put(property.getName(), result); i++; // valid reply, move to next property break; } mSdkLog.printf("\n"); // empty line } return map; }
@Override public int getUsbVendorId() { return myWrapee.getUsbVendorId(); }
@Override public ISystemImage[] getSystemImages() { return myWrapee.getSystemImages(); }
@Override public ISystemImage getSystemImage(String abiType) { return myWrapee.getSystemImage(abiType); }
@Override public int hashCode() { return myWrapee.hashCode(); }
/** * Displays the list of available AVDs for the given AvdManager. * * @param avdManager */ public void displayAvdList(AvdManager avdManager) { mSdkLog.printf("Available Android Virtual Devices:\n"); AvdInfo[] avds = avdManager.getValidAvds(); for (int index = 0; index < avds.length; index++) { AvdInfo info = avds[index]; if (index > 0) { mSdkLog.printf("---------\n"); } mSdkLog.printf(" Name: %s\n", info.getName()); mSdkLog.printf(" Path: %s\n", info.getPath()); // get the target of the AVD IAndroidTarget target = info.getTarget(); if (target.isPlatform()) { mSdkLog.printf( " Target: %s (API level %s)\n", target.getName(), target.getVersion().getApiString()); } else { mSdkLog.printf(" Target: %s (%s)\n", target.getName(), target.getVendor()); mSdkLog.printf( " Based on Android %s (API level %s)\n", target.getVersionName(), target.getVersion().getApiString()); } // display some extra values. Map<String, String> properties = info.getProperties(); 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); } String snapshot = properties.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); if (snapshot != null) { mSdkLog.printf("Snapshot: %s\n", snapshot); } } } // Are there some unused AVDs? AvdInfo[] badAvds = avdManager.getBrokenAvds(); if (badAvds.length == 0) { return; } mSdkLog.printf("\nThe following Android Virtual Devices could not be loaded:\n"); boolean needSeparator = false; for (AvdInfo info : badAvds) { if (needSeparator) { mSdkLog.printf("---------\n"); } mSdkLog.printf(" Name: %s\n", info.getName() == null ? "--" : info.getName()); mSdkLog.printf(" Path: %s\n", info.getPath() == null ? "--" : info.getPath()); String error = info.getErrorMessage(); mSdkLog.printf(" Error: %s\n", error == null ? "Uknown error" : error); needSeparator = true; } }
@Override public int compareTo(IAndroidTarget o) { return myWrapee.compareTo(o); }
/** Creates a new AVD. This is a text based creation with command line prompt. */ private void createAvd() { // find a matching target int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId()); IAndroidTarget[] targets = mSdkManager.getTargets(); if (targetId == INVALID_TARGET_ID || targetId > targets.length) { errorAndExit( "Target id is not valid. Use '%s list targets' to get the target ids.", SdkConstants.androidCmdName()); } IAndroidTarget target = targets[targetId - 1]; // target id is 1-based try { boolean removePrevious = mSdkCommandLine.getFlagForce(); AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); String avdName = mSdkCommandLine.getParamName(); if (!AvdManager.RE_AVD_NAME.matcher(avdName).matches()) { errorAndExit( "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", avdName, AvdManager.CHARS_AVD_NAME); return; } AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/); if (info != null) { if (removePrevious) { mSdkLog.warning( "Android Virtual Device '%s' already exists and will be replaced.", avdName); } else { errorAndExit( "Android Virtual Device '%s' already exists.\n" + "Use --force if you want to replace it.", avdName); return; } } String paramFolderPath = mSdkCommandLine.getParamLocationPath(); File avdFolder = null; if (paramFolderPath != null) { avdFolder = new File(paramFolderPath); } else { avdFolder = AvdManager.AvdInfo.getAvdFolder(avdName); } // Validate skin is either default (empty) or NNNxMMM or a valid skin name. Map<String, String> skinHardwareConfig = null; String skin = mSdkCommandLine.getParamSkin(); if (skin != null && skin.length() == 0) { skin = null; } if (skin != null && target != null) { boolean valid = false; // Is it a know skin name for this target? for (String s : target.getSkins()) { if (skin.equalsIgnoreCase(s)) { skin = s; // Make skin names case-insensitive. valid = true; // get the hardware properties for this skin File skinFolder = avdManager.getSkinPath(skin, target); FileWrapper skinHardwareFile = new FileWrapper(skinFolder, AvdManager.HARDWARE_INI); if (skinHardwareFile.isFile()) { skinHardwareConfig = ProjectProperties.parsePropertyFile(skinHardwareFile, mSdkLog); } break; } } // Is it NNNxMMM? if (!valid) { valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches(); } if (!valid) { displaySkinList(target, "Valid skins: "); errorAndExit("'%s' is not a valid skin name or size (NNNxMMM)", skin); return; } } Map<String, String> hardwareConfig = null; if (target != null && target.isPlatform()) { try { hardwareConfig = promptForHardware(target, skinHardwareConfig); } catch (IOException e) { errorAndExit(e.getMessage()); } } @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, skin, mSdkCommandLine.getParamSdCard(), hardwareConfig, removePrevious, mSdkCommandLine.getFlagSnapshot(), mSdkLog); } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); } }
@Override public String hashString() { return myWrapee.hashString(); }