--- /dev/null
+#Wed Feb 02 16:41:18 PST 2011\r
+eclipse.preferences.version=1\r
+encoding//tests/com/android/sdklib/testdata/addon_sample_1.xml=UTF-8\r
public final static String FD_SKINS = "skins";
/** Name of the SDK samples folder. */
public final static String FD_SAMPLES = "samples";
+ /** Name of the SDK extras folder. */
+ public final static String FD_EXTRAS = "extras";
/** Name of the SDK templates folder, i.e. "templates" */
public final static String FD_TEMPLATES = "templates";
/** Name of the SDK Ant folder, i.e. "ant" */
package com.android.sdklib;
+import com.android.annotations.VisibleForTesting;
+import com.android.annotations.VisibleForTesting.Visibility;
import com.android.prefs.AndroidLocation;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.AndroidVersion.AndroidVersionException;
* @see PlatformTarget
* @see AddOnTarget
*/
-public final class SdkManager {
+public class SdkManager {
public final static String PROP_VERSION_SDK = "ro.build.version.sdk"; //$NON-NLS-1$
public final static String PROP_VERSION_CODENAME = "ro.build.version.codename"; //$NON-NLS-1$
*
* @param osSdkPath the location of the SDK.
*/
- private SdkManager(String osSdkPath) {
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected SdkManager(String osSdkPath) {
mOsSdkPath = osSdkPath;
}
* <p/>
* The array can be empty but not null.
*/
- private void setTargets(IAndroidTarget[] targets) {
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ protected void setTargets(IAndroidTarget[] targets) {
assert targets != null;
mTargets = targets;
}
return null;\r
}\r
\r
- /**\r
- * Makes sure the base /add-ons folder exists before installing.\r
- */\r
- @Override\r
- public boolean preInstallHook(Archive archive,\r
- ITaskMonitor monitor,\r
- String osSdkRoot,\r
- File installFolder) {\r
- File addonsRoot = new File(osSdkRoot, SdkConstants.FD_ADDONS);\r
- if (!addonsRoot.isDirectory()) {\r
- addonsRoot.mkdir();\r
- }\r
-\r
- return super.preInstallHook(archive, monitor, osSdkRoot, installFolder);\r
- }\r
-\r
@Override\r
public boolean sameItemAs(Package pkg) {\r
if (pkg instanceof AddonPackage) {\r
\r
package com.android.sdklib.internal.repository;\r
\r
+import com.android.sdklib.NullSdkLog;\r
import com.android.sdklib.SdkConstants;\r
import com.android.sdklib.SdkManager;\r
import com.android.sdklib.internal.repository.Archive.Arch;\r
private final String mVendor;\r
\r
/**\r
- * The sub-folder name. It must be a non-empty single-segment path.\r
+ * The sub-folder name. It must be a non-empty single-segment path and has the same\r
+ * rules as {@link #mVendor}.\r
*/\r
private final String mPath;\r
\r
\r
props.setProperty(PROP_PATH, mPath);\r
if (mVendor != null) {\r
- props.setProperty(PROP_PATH, mVendor);\r
+ props.setProperty(PROP_VENDOR, mVendor);\r
}\r
\r
if (getMinApiLevel() != MIN_API_LEVEL_NOT_SPECIFIED) {\r
}\r
\r
/**\r
- * Static helper to check if a given path is acceptable for an "extra" package.\r
+ * Static helper to check if a given vendor and path is acceptable for an "extra" package.\r
*/\r
public boolean isPathValid() {\r
- if (SdkConstants.FD_ADDONS.equals(mPath) ||\r
- SdkConstants.FD_PLATFORMS.equals(mPath) ||\r
- SdkConstants.FD_PLATFORM_TOOLS.equals(mPath) ||\r
- SdkConstants.FD_TOOLS.equals(mPath) ||\r
- SdkConstants.FD_DOCS.equals(mPath) ||\r
- RepoConstants.FD_TEMP.equals(mPath)) {\r
+ return isSegmentValid(mVendor) && isSegmentValid(mPath);\r
+ }\r
+\r
+ private boolean isSegmentValid(String segment) {\r
+ if (SdkConstants.FD_ADDONS.equals(segment) ||\r
+ SdkConstants.FD_PLATFORMS.equals(segment) ||\r
+ SdkConstants.FD_PLATFORM_TOOLS.equals(segment) ||\r
+ SdkConstants.FD_TOOLS.equals(segment) ||\r
+ SdkConstants.FD_DOCS.equals(segment) ||\r
+ RepoConstants.FD_TEMP.equals(segment)) {\r
return false;\r
}\r
- return mPath != null && mPath.indexOf('/') == -1 && mPath.indexOf('\\') == -1;\r
+ return segment != null && segment.indexOf('/') == -1 && segment.indexOf('\\') == -1;\r
}\r
\r
/**\r
- * The install folder name. It is a single-segment path.\r
+ * Returns the sanitized path folder name. It is a single-segment path.\r
+ * <p/>\r
+ * The package is installed in SDK/extras/vendor_name/path_name.\r
* <p/>\r
* The paths "add-ons", "platforms", "tools" and "docs" are reserved and cannot be used.\r
* This limitation cannot be written in the XML Schema and must be enforced here by using\r
* the method {@link #isPathValid()} *before* installing the package.\r
*/\r
public String getPath() {\r
- String path = mPath;\r
+ // The XSD specifies the XML vendor and path should only contain [a-zA-Z0-9]+\r
+ // and cannot be empty. Let's be defensive and enforce that anyway since things\r
+ // like "____" are still valid values that we don't want to allow.\r
\r
- if (mVendor != null && mVendor.length() > 0) {\r
- path = mVendor + "-" + mPath; //$NON-NLS-1$\r
+ // Sanitize the path\r
+ String path = mPath.replaceAll("[^a-zA-Z0-9-]+", "_"); //$NON-NLS-1$\r
+ if (path.length() == 0 || path.equals("_")) { //$NON-NLS-1$\r
+ int h = path.hashCode();\r
+ path = String.format("extra%08x", h); //$NON-NLS-1$\r
}\r
\r
- int h = path.hashCode();\r
+ return path;\r
+ }\r
\r
- // Sanitize the path\r
- path = path.replaceAll("[^a-zA-Z0-9-]+", "_"); //$NON-NLS-1$\r
- if (path.length() == 0) {\r
- path = String.format("unknown_extra%08x", h); //$NON-NLS-1$\r
+ /**\r
+ * Returns the sanitized vendor folder name. It is a single-segment path.\r
+ * <p/>\r
+ * The package is installed in SDK/extras/vendor_name/path_name.\r
+ * <p/>\r
+ * An empty string is returned in case of error.\r
+ */\r
+ public String getVendor() {\r
+\r
+ // The XSD specifies the XML vendor and path should only contain [a-zA-Z0-9]+\r
+ // and cannot be empty. Let's be defensive and enforce that anyway since things\r
+ // like "____" are still valid values that we don't want to allow.\r
+\r
+ if (mVendor != null && mVendor.length() > 0) {\r
+ String vendor = mVendor;\r
+ // Sanitize the vendor\r
+ vendor = vendor.replaceAll("[^a-zA-Z0-9-]+", "_"); //$NON-NLS-1$\r
+ if (vendor.equals("_")) { //$NON-NLS-1$\r
+ int h = vendor.hashCode();\r
+ vendor = String.format("vendor%08x", h); //$NON-NLS-1$\r
+ }\r
+\r
+ return vendor;\r
}\r
\r
- return path;\r
+ return ""; //$NON-NLS-1$\r
}\r
\r
/** Returns a short description for an {@link IDescription}. */\r
@Override\r
public String getShortDescription() {\r
- String name = getPath();\r
- if (name != null) {\r
- // Uniformize all spaces in the name and upper case words.\r
-\r
- name = name.replaceAll("[ _\t\f-]+", " "); //$NON-NLS-1$ //$NON-NLS-2$\r
-\r
- // Look at all lower case characters in range [1..n-1] and replace them by an upper\r
- // case if they are preceded by a space. Also upper cases the first character of the\r
- // string.\r
- boolean changed = false;\r
- char[] chars = name.toCharArray();\r
- for (int n = chars.length - 1, i = 0; i < n; i++) {\r
- if (Character.isLowerCase(chars[i]) && (i == 0 || chars[i - 1] == ' ')) {\r
- chars[i] = Character.toUpperCase(chars[i]);\r
- changed = true;\r
- }\r
+ String name = mPath;\r
+\r
+ // In the past, we used to save the extras in a folder vendor-path,\r
+ // and that "vendor" would end up in the path when we reload the extra from\r
+ // disk. Detect this and compensate.\r
+ if (mVendor != null && mVendor.length() > 0) {\r
+ if (name.startsWith(mVendor + "-")) { //$NON-NLS-1$\r
+ name = name.substring(mVendor.length() + 1);\r
}\r
- if (changed) {\r
- name = new String(chars);\r
+ }\r
+\r
+ // Uniformize all spaces in the name\r
+ if (name != null) {\r
+ name = name.replaceAll("[ _\t\f-]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$\r
+ }\r
+ if (name == null || name.length() == 0) { //$NON-NLS-1$\r
+ name = "Unkown Extra";\r
+ }\r
+\r
+ if (mVendor != null && mVendor.length() > 0) {\r
+ name = mVendor + " " + name; //$NON-NLS-1$\r
+ name = name.replaceAll("[ _\t\f-]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$\r
+ }\r
+\r
+ // Look at all lower case characters in range [1..n-1] and replace them by an upper\r
+ // case if they are preceded by a space. Also upper cases the first character of the\r
+ // string.\r
+ boolean changed = false;\r
+ char[] chars = name.toCharArray();\r
+ for (int n = chars.length - 1, i = 0; i < n; i++) {\r
+ if (Character.isLowerCase(chars[i]) && (i == 0 || chars[i - 1] == ' ')) {\r
+ chars[i] = Character.toUpperCase(chars[i]);\r
+ changed = true;\r
}\r
}\r
+ if (changed) {\r
+ name = new String(chars);\r
+ }\r
+\r
+ // Special case: reformat a few typical acronyms.\r
+ name = name.replaceAll(" Usb ", " USB "); //$NON-NLS-1$\r
+ name = name.replaceAll(" Api ", " API "); //$NON-NLS-1$\r
\r
String s = String.format("%1$s package, revision %2$d%3$s",\r
name,\r
getRevision(),\r
- isObsolete() ? " (Obsolete)" : "");\r
+ isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$\r
\r
return s;\r
}\r
public String getLongDescription() {\r
String s = getDescription();\r
if (s == null || s.length() == 0) {\r
- s = String.format("Extra %1$s package", getPath());\r
+ s = String.format("Extra %1$s package by %2$s", getPath(), getVendor());\r
}\r
\r
if (s.indexOf("revision") == -1) {\r
s += String.format("\nRevision %1$d%2$s",\r
getRevision(),\r
- isObsolete() ? " (Obsolete)" : "");\r
+ isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$\r
}\r
\r
if (getMinToolsRevision() != MIN_TOOLS_REV_NOT_SPECIFIED) {\r
s += String.format("\nRequires SDK Platform Android API %1$s", getMinApiLevel());\r
}\r
\r
+ // For a local archive, also put the install path in the long description.\r
+ // This should help users locate the extra on their drive.\r
+ File localPath = getLocalArchivePath();\r
+ if (localPath != null) {\r
+ s += String.format("\nLocation: %1$s", localPath.getAbsolutePath());\r
+ }\r
+\r
return s;\r
}\r
\r
*\r
* @param osSdkRoot The OS path of the SDK root folder.\r
* @param sdkManager An existing SDK manager to list current platforms and addons.\r
+ * Not used in this implementation.\r
* @return A new {@link File} corresponding to the directory to use to install this package.\r
*/\r
@Override\r
public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) {\r
- return new File(osSdkRoot, getPath());\r
+\r
+ // First find if this extra is already installed. If so, reuse the same directory.\r
+ LocalSdkParser localParser = new LocalSdkParser();\r
+ Package[] pkgs = localParser.parseSdk(osSdkRoot, sdkManager, new NullSdkLog());\r
+\r
+ for (Package pkg : pkgs) {\r
+ if (sameItemAs(pkg) && pkg instanceof ExtraPackage) {\r
+ File localPath = ((ExtraPackage) pkg).getLocalArchivePath();\r
+ if (localPath != null) {\r
+ return localPath;\r
+ }\r
+ }\r
+ }\r
+\r
+ // The /extras dir at the root of the SDK\r
+ File path = new File(osSdkRoot, SdkConstants.FD_EXTRAS);\r
+\r
+ String vendor = getVendor();\r
+ if (vendor != null && vendor.length() > 0) {\r
+ path = new File(path, vendor);\r
+ }\r
+\r
+ String name = getPath();\r
+ if (name != null && name.length() > 0) {\r
+ path = new File(path, name);\r
+ }\r
+\r
+ return path;\r
}\r
\r
@Override\r
public boolean sameItemAs(Package pkg) {\r
- // Extra packages are similar if they have the same path.\r
- return pkg instanceof ExtraPackage && ((ExtraPackage)pkg).mPath.equals(mPath);\r
+ // Extra packages are similar if they have the same path and vendor\r
+ if (pkg instanceof ExtraPackage) {\r
+ ExtraPackage ep = (ExtraPackage) pkg;\r
+\r
+ // To be backward compatible, we need to support the old vendor-path form\r
+ if (ep.mPath != null && (ep.mVendor == null || ep.mVendor.length() == 0) &&\r
+ mPath != null && mVendor != null) {\r
+ if (ep.mPath.equals(mVendor + "-" + mPath)) { //$NON-NLS-1$\r
+ return true;\r
+ }\r
+ }\r
+\r
+ if (!mPath.equals(ep.mPath)) {\r
+ return false;\r
+ }\r
+ if ((mVendor == null && ep.mVendor == null) ||\r
+ (mVendor != null && !mVendor.equals(ep.mVendor))) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ // ---\r
+\r
+ /**\r
+ * If this package is installed, returns the install path of the archive if valid.\r
+ * Returns null if not installed or if the path does not exist.\r
+ */\r
+ private File getLocalArchivePath() {\r
+ Archive[] archives = getArchives();\r
+ if (archives.length == 1 && archives[0].isLocal()) {\r
+ File path = new File(archives[0].getLocalOsPath());\r
+ if (path.isDirectory()) {\r
+ return path;\r
+ }\r
+ }\r
+\r
+ return null;\r
}\r
}\r
scanMissingAddons(sdkManager, visited, packages, log);\r
scanMissingSamples(osSdkRoot, visited, packages, log);\r
scanExtras(osSdkRoot, visited, packages, log);\r
+ scanExtrasDirectory(osSdkRoot, visited, packages, log);\r
\r
Collections.sort(packages);\r
\r
}\r
\r
/**\r
- * Find any other directory <em>at the top level</em> that hasn't been visited yet\r
- * and assume they contain extra packages. This is <em>not</em> a recursive search.\r
+ * Find any directory in the /extras/vendors/path folders for extra packages.\r
+ * This isn't a recursive search.\r
*/\r
private void scanExtras(String osSdkRoot,\r
HashSet<File> visited,\r
ArrayList<Package> packages,\r
ISdkLog log) {\r
- File root = new File(osSdkRoot);\r
+ File root = new File(osSdkRoot, SdkConstants.FD_EXTRAS);\r
+\r
+ if (!root.isDirectory()) {\r
+ // This should not happen. It makes listFiles() return null so let's avoid it.\r
+ return;\r
+ }\r
+\r
+ for (File vendor : root.listFiles()) {\r
+ if (vendor.isDirectory()) {\r
+ scanExtrasDirectory(vendor.getAbsolutePath(), visited, packages, log);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Find any other directory in the given "root" directory that hasn't been visited yet\r
+ * and assume they contain extra packages. This is <em>not</em> a recursive search.\r
+ */\r
+ private void scanExtrasDirectory(String extrasRoot,\r
+ HashSet<File> visited,\r
+ ArrayList<Package> packages,\r
+ ISdkLog log) {\r
+ File root = new File(extrasRoot);\r
\r
if (!root.isDirectory()) {\r
// This should not happen. It makes listFiles() return null so let's avoid it.\r
* <p/>\r
* Some types of packages install in a fix location, for example docs and tools.\r
* In this case the returned folder may already exist with a different archive installed\r
- * at the desired location.\r
+ * at the desired location. <br/>\r
* For other packages types, such as add-on or platform, the folder name is only partially\r
* relevant to determine the content and thus a real check will be done to provide an\r
* existing or new folder depending on the current content of the SDK.\r
+ * <p/>\r
+ * Note that the installer *will* create all directories returned here just before\r
+ * installation so this method must not attempt to create them.\r
*\r
* @param osSdkRoot The OS path of the SDK root folder.\r
* @param sdkManager An existing SDK manager to list current platforms and addons.\r
* be continue. The installer will still install the remaining packages if possible.\r
* <p/>\r
* The base implementation always return true.\r
+ * <p/>\r
+ * Note that the installer *will* create all directories specified by\r
+ * {@link #getInstallFolder} just before installation, so they must not be\r
+ * created here. This is also called before the previous install dir is removed\r
+ * so the previous content is still there during upgrade.\r
*\r
* @param archive The archive that will be installed\r
* @param monitor The {@link ITaskMonitor} to display errors.\r
* - Add-on based on n <br/>\r
* - Add-on based on n-1 <br/>\r
* - Extra packages <br/>\r
+ * <p/>\r
+ * Important: this must NOT be used to compare if two packages are the same thing.\r
+ * This is achieved by {@link #sameItemAs(Package)} or {@link #canBeUpdatedBy(Package)}.\r
+ * <p/>\r
+ * This {@link #compareTo(Package)} method is purely an implementation detail to\r
+ * perform the right ordering of the packages in the list of available or installed packages.\r
*/\r
public int compareTo(Package other) {\r
int s1 = this.sortingScore();\r
return folder;\r
}\r
\r
- /**\r
- * Makes sure the base /platforms folder exists before installing.\r
- */\r
- @Override\r
- public boolean preInstallHook(Archive archive,\r
- ITaskMonitor monitor,\r
- String osSdkRoot,\r
- File installFolder) {\r
- File platformsRoot = new File(osSdkRoot, SdkConstants.FD_PLATFORMS);\r
- if (!platformsRoot.isDirectory()) {\r
- platformsRoot.mkdir();\r
- }\r
-\r
- return super.preInstallHook(archive, monitor, osSdkRoot, installFolder);\r
- }\r
-\r
@Override\r
public boolean sameItemAs(Package pkg) {\r
if (pkg instanceof PlatformPackage) {\r
// The /samples dir at the root of the SDK\r
File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES);\r
\r
- // First find if this platform is already installed. If so, reuse the same directory.\r
+ // First find if this sample is already installed. If so, reuse the same directory.\r
for (IAndroidTarget target : sdkManager.getTargets()) {\r
if (target.isPlatform() &&\r
target.getVersion().equals(mVersion)) {\r
ITaskMonitor monitor,\r
String osSdkRoot,\r
File installFolder) {\r
- File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES);\r
- if (!samplesRoot.isDirectory()) {\r
- samplesRoot.mkdir();\r
- }\r
\r
if (installFolder != null && installFolder.isDirectory()) {\r
// Get the hash computed during the last installation\r
--- /dev/null
+/*\r
+ * Copyright (C) 2011 The Android Open Source Project\r
+ *\r
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.eclipse.org/org/documents/epl-v10.php\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.android.sdklib.internal.repository;\r
+\r
+import com.android.sdklib.IAndroidTarget;\r
+import com.android.sdklib.SdkManager;\r
+\r
+/**\r
+ * An invalid SDK Manager, just good enough to avoid passing a null reference.\r
+ */\r
+class MockEmptySdkManager extends SdkManager {\r
+ public MockEmptySdkManager(String osSdkPath) {\r
+ super(osSdkPath);\r
+ setTargets(new IAndroidTarget[0]);\r
+ }\r
+}\r
\r
package com.android.sdklib.internal.repository;\r
\r
+import com.android.sdklib.SdkManager;\r
import com.android.sdklib.repository.SdkAddonConstants;\r
\r
import org.w3c.dom.Document;\r
\r
import java.io.ByteArrayInputStream;\r
+import java.io.File;\r
import java.io.FileInputStream;\r
import java.io.IOException;\r
import java.io.InputStream;\r
assertEquals("Found My First add-on by John Doe, Android API 1, revision 1\n" +\r
"Found My Second add-on by John Deer, Android API 2, revision 42\n" +\r
"Found This add-on has no libraries by Joe Bar, Android API 4, revision 3\n" +\r
- "Found A Usb Driver package, revision 43 (Obsolete)\n" +\r
- "Found Android Vendor Extra Api Dep package, revision 2 (Obsolete)\n",\r
+ "Found G USB Driver package, revision 43 (Obsolete)\n" +\r
+ "Found Android Vendor Extra API Dep package, revision 2 (Obsolete)\n" +\r
+ "Found Unkown Extra package, revision 2 (Obsolete)\n",\r
monitor.getCapturedDescriptions());\r
assertEquals("", monitor.getCapturedResults());\r
\r
// check the packages we found... we expected to find 11 packages with each at least\r
// one archive.\r
Package[] pkgs = mSource.getPackages();\r
- assertEquals(5, pkgs.length);\r
+ assertEquals(6, pkgs.length);\r
for (Package p : pkgs) {\r
assertTrue(p.getArchives().length >= 1);\r
}\r
\r
- // Check the extra packages path\r
- ArrayList<String> extraPaths = new ArrayList<String>();\r
+ // Check the extra packages path, vendor, install folder\r
+\r
+ final String osSdkPath = "SDK";\r
+ final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath);\r
+\r
+ ArrayList<String> extraPaths = new ArrayList<String>();\r
+ ArrayList<String> extraVendors = new ArrayList<String>();\r
+ ArrayList<File> extraInstall = new ArrayList<File>();\r
for (Package p : pkgs) {\r
if (p instanceof ExtraPackage) {\r
extraPaths.add(((ExtraPackage) p).getPath());\r
+ extraVendors.add(((ExtraPackage) p).getVendor());\r
+ extraInstall.add(((ExtraPackage) p).getInstallFolder(osSdkPath, sdkManager));\r
}\r
}\r
assertEquals(\r
- "[a-usb_driver, android_vendor-extra_api_dep]",\r
+ "[usb_driver, extra_api_dep, extra0000005f]",\r
Arrays.toString(extraPaths.toArray()));\r
+ assertEquals(\r
+ "[g, android_vendor, vendor0000005f]",\r
+ Arrays.toString(extraVendors.toArray()));\r
+ assertEquals(\r
+ ("[SDK/extras/g/usb_driver, " +\r
+ "SDK/extras/android_vendor/extra_api_dep, " +\r
+ "SDK/extras/vendor0000005f/extra0000005f]").replace('/', File.separatorChar),\r
+ Arrays.toString(extraInstall.toArray()));\r
}\r
\r
/**\r
\r
package com.android.sdklib.internal.repository;\r
\r
+import com.android.sdklib.SdkManager;\r
import com.android.sdklib.repository.SdkRepoConstants;\r
\r
import org.w3c.dom.Document;\r
\r
import java.io.ByteArrayInputStream;\r
+import java.io.File;\r
import java.io.FileInputStream;\r
import java.io.IOException;\r
import java.io.InputStream;\r
assertTrue(p.getArchives().length >= 1);\r
}\r
\r
- // Check the extra packages path\r
- ArrayList<String> extraPaths = new ArrayList<String>();\r
+ // Check the extra packages path, vendor, install folder\r
+\r
+ final String osSdkPath = "SDK";\r
+ final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath);\r
+\r
+ ArrayList<String> extraPaths = new ArrayList<String>();\r
+ ArrayList<String> extraVendors = new ArrayList<String>();\r
+ ArrayList<File> extraInstall = new ArrayList<File>();\r
for (Package p : pkgs) {\r
if (p instanceof ExtraPackage) {\r
extraPaths.add(((ExtraPackage) p).getPath());\r
+ extraVendors.add(((ExtraPackage) p).getVendor());\r
+ extraInstall.add(((ExtraPackage) p).getInstallFolder(osSdkPath, sdkManager));\r
}\r
}\r
assertEquals(\r
"[usb_driver]",\r
Arrays.toString(extraPaths.toArray()));\r
+ assertEquals(\r
+ "[]",\r
+ Arrays.toString(extraVendors.toArray()));\r
+ assertEquals(\r
+ "[SDK/extras/usb_driver]".replace('/', File.separatorChar),\r
+ Arrays.toString(extraInstall.toArray()));\r
}\r
\r
/**\r
"Found Android SDK Tools, revision 42\n" +\r
"Found This add-on has no libraries by Joe Bar, Android API 4, revision 3\n" +\r
"Found Usb Driver package, revision 43 (Obsolete)\n" +\r
- "Found Extra Api Dep package, revision 2 (Obsolete)\n" +\r
+ "Found Extra API Dep package, revision 2 (Obsolete)\n" +\r
"Found Samples for SDK API 14, revision 24 (Obsolete)\n",\r
monitor.getCapturedDescriptions());\r
assertEquals("", monitor.getCapturedResults());\r
assertTrue(p.getArchives().length >= 1);\r
}\r
\r
- // Check the extra packages path\r
- ArrayList<String> extraPaths = new ArrayList<String>();\r
+ // Check the extra packages path, vendor, install folder\r
+\r
+ final String osSdkPath = "SDK";\r
+ final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath);\r
+\r
+ ArrayList<String> extraPaths = new ArrayList<String>();\r
+ ArrayList<String> extraVendors = new ArrayList<String>();\r
+ ArrayList<File> extraInstall = new ArrayList<File>();\r
for (Package p : pkgs) {\r
if (p instanceof ExtraPackage) {\r
extraPaths.add(((ExtraPackage) p).getPath());\r
+ extraVendors.add(((ExtraPackage) p).getVendor());\r
+ extraInstall.add(((ExtraPackage) p).getInstallFolder(osSdkPath, sdkManager));\r
}\r
}\r
assertEquals(\r
"[usb_driver, extra_api_dep]",\r
Arrays.toString(extraPaths.toArray()));\r
+ assertEquals(\r
+ "[, ]",\r
+ Arrays.toString(extraVendors.toArray()));\r
+ assertEquals(\r
+ "[SDK/extras/usb_driver, SDK/extras/extra_api_dep]".replace('/', File.separatorChar),\r
+ Arrays.toString(extraInstall.toArray()));\r
}\r
\r
/**\r
"Found Documentation for Android SDK, API 2, revision 42\n" +\r
"Found Android SDK Tools, revision 42\n" +\r
"Found Android SDK Platform-tools, revision 3\n" +\r
- "Found A Usb Driver package, revision 43 (Obsolete)\n" +\r
- "Found Android Vendor Extra Api Dep package, revision 2 (Obsolete)\n" +\r
+ "Found A USB Driver package, revision 43 (Obsolete)\n" +\r
+ "Found Android Vendor Extra API Dep package, revision 2 (Obsolete)\n" +\r
"Found Samples for SDK API 14, revision 24 (Obsolete)\n",\r
monitor.getCapturedDescriptions());\r
assertEquals("", monitor.getCapturedResults());\r
assertTrue(p.getArchives().length >= 1);\r
}\r
\r
- // Check the extra packages path\r
- ArrayList<String> extraPaths = new ArrayList<String>();\r
+ // Check the extra packages path, vendor, install folder\r
+\r
+ final String osSdkPath = "SDK";\r
+ final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath);\r
+\r
+ ArrayList<String> extraPaths = new ArrayList<String>();\r
+ ArrayList<String> extraVendors = new ArrayList<String>();\r
+ ArrayList<File> extraInstall = new ArrayList<File>();\r
for (Package p : pkgs) {\r
if (p instanceof ExtraPackage) {\r
extraPaths.add(((ExtraPackage) p).getPath());\r
+ extraVendors.add(((ExtraPackage) p).getVendor());\r
+ extraInstall.add(((ExtraPackage) p).getInstallFolder(osSdkPath, sdkManager));\r
}\r
}\r
assertEquals(\r
- "[a-usb_driver, android_vendor-extra_api_dep]",\r
+ "[usb_driver, extra_api_dep]",\r
Arrays.toString(extraPaths.toArray()));\r
+ assertEquals(\r
+ "[a, android_vendor]",\r
+ Arrays.toString(extraVendors.toArray()));\r
+ assertEquals(\r
+ "[SDK/extras/a/usb_driver, SDK/extras/android_vendor/extra_api_dep]"\r
+ .replace('/', File.separatorChar),\r
+ Arrays.toString(extraInstall.toArray()));\r
}\r
\r
/**\r
</sdk:add-on>
<sdk:extra>
- <sdk:vendor>a</sdk:vendor>
+ <sdk:vendor>g</sdk:vendor>
<sdk:path>usb_driver</sdk:path>
<sdk:uses-license ref="license2" />
<sdk:revision>43</sdk:revision>
<sdk:obsolete></sdk:obsolete>
</sdk:extra>
+ <sdk:extra>
+ <sdk:vendor>____</sdk:vendor>
+ <sdk:path>____</sdk:path>
+ <sdk:uses-license ref="license2" />
+ <sdk:revision>2</sdk:revision>
+ <sdk:archives>
+ <sdk:archive os="any" arch="any">
+ <sdk:size>65536</sdk:size>
+ <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum>
+ <sdk:url>distrib/extra_mega_duff.zip</sdk:url>
+ </sdk:archive>
+ </sdk:archives>
+ <sdk:description>Some extra package that has a min-api-level of 42</sdk:description>
+ <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url>
+ <sdk:min-tools-rev>3</sdk:min-tools-rev>
+ <sdk:min-api-level>42</sdk:min-api-level>
+ <sdk:obsolete></sdk:obsolete>
+ </sdk:extra>
+
</sdk:sdk-addon>