aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2012-05-22 12:40:57 -0700
committerRaphael Moll <ralf@android.com>2012-05-31 12:48:20 -0700
commitdb0a40e662c8d14f0a6451845198f055a76a02af (patch)
tree13fd6742eda2e67f020d18314fba5c98385b8fa9
parent929e008c80c5f0d2cf875f44231634ced002f1f1 (diff)
downloadsdk-db0a40e662c8d14f0a6451845198f055a76a02af.zip
sdk-db0a40e662c8d14f0a6451845198f055a76a02af.tar.gz
sdk-db0a40e662c8d14f0a6451845198f055a76a02af.tar.bz2
SDK Manager: support standalone sys-img xml.
This extends the addons_list XSD to support both addons sites and OEM's system-image sites. Then this defines a new schema "sys-img" XSD for a site that offers only system images. Change-Id: I77ff56c4c70f57ab8ea44cf4ea3094125653737b
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java90
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java15
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java9
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java9
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java109
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd7
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd1
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java8
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java28
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java7
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java83
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd2
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd106
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd229
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java64
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java2
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java211
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java4
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java108
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java4
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java101
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml48
-rwxr-xr-xsdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml83
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java4
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java13
25 files changed, 1297 insertions, 48 deletions
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java
index 216e309..0880645 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java
@@ -57,14 +57,21 @@ import javax.xml.validation.Validator;
*/
public class AddonsListFetcher {
+ public enum SiteType {
+ ADDON_SITE,
+ SYS_IMG_SITE
+ }
+
/**
* An immutable structure representing an add-on site.
*/
public static class Site {
private final String mUrl;
private final String mUiName;
+ private final SiteType mType;
- private Site(String url, String uiName) {
+ private Site(String url, String uiName, SiteType type) {
+ mType = type;
mUrl = url.trim();
mUiName = uiName;
}
@@ -76,6 +83,17 @@ public class AddonsListFetcher {
public String getUiName() {
return mUiName;
}
+
+ public SiteType getType() {
+ return mType;
+ }
+
+ /** Returns a debug string representation of this object. Not for user display. */
+ @Override
+ public String toString() {
+ return String.format("<%1$s URL='%2$s' Name='%3$s'>", //$NON-NLS-1$
+ mType, mUrl, mUiName);
+ }
}
/**
@@ -92,7 +110,7 @@ public class AddonsListFetcher {
url = url == null ? "" : url.trim();
- monitor.setProgressMax(5);
+ monitor.setProgressMax(6);
monitor.setDescription("Fetching %1$s", url);
monitor.incProgress(1);
@@ -102,7 +120,55 @@ public class AddonsListFetcher {
Document validatedDoc = null;
String validatedUri = null;
+ String[] defaultNames = new String[SdkAddonsListConstants.NS_LATEST_VERSION];
+ for (int version = SdkAddonsListConstants.NS_LATEST_VERSION, i = 0;
+ version >= 1;
+ version--, i++) {
+ defaultNames[i] = SdkAddonsListConstants.getDefaultName(version);
+ }
+
InputStream xml = fetchUrl(url, cache, monitor.createSubMonitor(1), exception);
+ if (xml != null) {
+ int version = getXmlSchemaVersion(xml);
+ if (version == 0) {
+ xml = null;
+ }
+ }
+
+ // If we can't find the latest version, try earlier schema versions.
+ if (xml == null && defaultNames.length > 0) {
+ ITaskMonitor subMonitor = monitor.createSubMonitor(1);
+ subMonitor.setProgressMax(defaultNames.length);
+
+ String baseUrl = url;
+ if (!baseUrl.endsWith("/")) { //$NON-NLS-1$
+ int pos = baseUrl.lastIndexOf('/');
+ if (pos > 0) {
+ baseUrl = baseUrl.substring(0, pos + 1);
+ }
+ }
+
+ for (String name : defaultNames) {
+ String newUrl = baseUrl + name;
+ if (newUrl.equals(url)) {
+ continue;
+ }
+ xml = fetchUrl(newUrl, cache, subMonitor.createSubMonitor(1), exception);
+ if (xml != null) {
+ int version = getXmlSchemaVersion(xml);
+ if (version == 0) {
+ xml = null;
+ } else {
+ url = newUrl;
+ subMonitor.incProgress(
+ subMonitor.getProgressMax() - subMonitor.getProgress());
+ break;
+ }
+ }
+ }
+ } else {
+ monitor.incProgress(1);
+ }
if (xml != null) {
monitor.setDescription("Validate XML");
@@ -434,8 +500,22 @@ public class AddonsListFetcher {
child != null;
child = child.getNextSibling()) {
if (child.getNodeType() == Node.ELEMENT_NODE &&
- nsUri.equals(child.getNamespaceURI()) &&
- child.getLocalName().equals(SdkAddonsListConstants.NODE_ADDON_SITE)) {
+ nsUri.equals(child.getNamespaceURI())) {
+
+ String elementName = child.getLocalName();
+ SiteType type = null;
+
+ if (SdkAddonsListConstants.NODE_SYS_IMG_SITE.equals(elementName)) {
+ type = SiteType.SYS_IMG_SITE;
+
+ } else if (SdkAddonsListConstants.NODE_ADDON_SITE.equals(elementName)) {
+ type = SiteType.ADDON_SITE;
+ }
+
+ // Not an addon-site nor a sys-img-site, don't process this.
+ if (type == null) {
+ continue;
+ }
Node url = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_URL);
Node name = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_NAME);
@@ -451,7 +531,7 @@ public class AddonsListFetcher {
}
if (strUrl.length() > 0 && strName.length() > 0) {
- sites.add(new Site(strUrl, strName));
+ sites.add(new Site(strUrl, strName, type));
}
}
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java
index 39a134b..cff7e1a 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java
@@ -34,7 +34,7 @@ public class SdkAddonSource extends SdkSource {
/**
* Constructs a new source for the given repository URL.
* @param url The source URL. Cannot be null. If the URL ends with a /, the default
- * repository.xml filename will be appended automatically.
+ * addon.xml filename will be appended automatically.
* @param uiName The UI-visible name of the source. Can be null.
*/
public SdkAddonSource(String url, String uiName) {
@@ -50,6 +50,16 @@ public class SdkAddonSource extends SdkSource {
return true;
}
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return false;
+ }
+
+
@Override
protected String[] getDefaultXmlFileUrls() {
return new String[] { SdkAddonConstants.URL_DEFAULT_FILENAME };
@@ -86,8 +96,7 @@ public class SdkAddonSource extends SdkSource {
}
/**
- * There is no support forward evolution of the sdk-addon schema yet since we
- * currently have only one version.
+ * This kind of schema does not support forward-evolution of the &lt;tool&gt; element.
*
* @param xml The input XML stream. Can be null.
* @return Always null.
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java
index 482655f..9fe5574 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java
@@ -65,6 +65,15 @@ public class SdkRepoSource extends SdkSource {
return false;
}
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return false;
+ }
+
private static String[] sDefaults = null; // lazily allocated in getDefaultXmlFileUrls
@Override
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java
index c07715b..8187480 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java
@@ -126,6 +126,13 @@ public abstract class SdkSource implements IDescription, Comparable<SdkSource> {
public abstract boolean isAddonSource();
/**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ public abstract boolean isSysImgSource();
+
+
+ /**
* Returns the basename of the default URLs to try to download the
* XML manifest.
* E.g. this is typically SdkRepoConstants.URL_DEFAULT_XML_FILE
@@ -373,7 +380,7 @@ public abstract class SdkSource implements IDescription, Comparable<SdkSource> {
}
}
- for(String name : defaultNames) {
+ for (String name : defaultNames) {
String newUrl = baseUrl + name;
if (newUrl.equals(url)) {
continue;
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java
new file mode 100755
index 0000000..7cee61d
--- /dev/null
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib.internal.repository.sources;
+
+import com.android.annotations.Nullable;
+import com.android.sdklib.internal.repository.packages.Package;
+import com.android.sdklib.repository.SdkSysImgConstants;
+
+import org.w3c.dom.Document;
+
+import java.io.InputStream;
+
+
+/**
+ * An sdk-sys-img source, i.e. a download site for system-image packages.
+ * A repository describes one or more {@link Package}s available for download.
+ */
+public class SdkSysImgSource extends SdkSource {
+
+ /**
+ * Constructs a new source for the given repository URL.
+ * @param url The source URL. Cannot be null. If the URL ends with a /, the default
+ * sys-img.xml filename will be appended automatically.
+ * @param uiName The UI-visible name of the source. Can be null.
+ */
+ public SdkSysImgSource(String url, String uiName) {
+ super(url, uiName);
+ }
+
+ /**
+ * Returns true if this is an addon source.
+ * We only load addons and extras from these sources.
+ */
+ @Override
+ public boolean isAddonSource() {
+ return false;
+ }
+
+ /**
+ * Returns true if this is a system-image source.
+ * We only load system-images from these sources.
+ */
+ @Override
+ public boolean isSysImgSource() {
+ return true;
+ }
+
+
+ @Override
+ protected String[] getDefaultXmlFileUrls() {
+ return new String[] { SdkSysImgConstants.URL_DEFAULT_FILENAME };
+ }
+
+ @Override
+ protected int getNsLatestVersion() {
+ return SdkSysImgConstants.NS_LATEST_VERSION;
+ }
+
+ @Override
+ protected String getNsUri() {
+ return SdkSysImgConstants.NS_URI;
+ }
+
+ @Override
+ protected String getNsPattern() {
+ return SdkSysImgConstants.NS_PATTERN;
+ }
+
+ @Override
+ protected String getSchemaUri(int version) {
+ return SdkSysImgConstants.getSchemaUri(version);
+ }
+
+ @Override
+ protected String getRootElementName() {
+ return SdkSysImgConstants.NODE_SDK_SYS_IMG;
+ }
+
+ @Override
+ protected InputStream getXsdStream(int version) {
+ return SdkSysImgConstants.getXsdStream(version);
+ }
+
+ /**
+ * This kind of schema does not support forward-evolution of the &lt;tool&gt; element.
+ *
+ * @param xml The input XML stream. Can be null.
+ * @return Always null.
+ * @null This implementation always return null.
+ */
+ @Override
+ protected Document findAlternateToolsXml(@Nullable InputStream xml) {
+ return null;
+ }
+}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd
index 6250789..546b00d 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-5.xsd
@@ -70,12 +70,13 @@
</xsd:documentation>
</xsd:annotation>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="add-on" type="sdk:addonType" />
- <xsd:element name="extra" type="sdk:extraType" />
- <xsd:element name="license" type="sdk:licenseType" />
+ <xsd:element name="add-on" type="sdk:addonType" />
+ <xsd:element name="extra" type="sdk:extraType" />
+ <xsd:element name="license" type="sdk:licenseType" />
</xsd:choice>
</xsd:complexType>
+
<!-- The definition of an SDK Add-on package. -->
<xsd:complexType name="addonType">
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd
index ca41b36..ea18070 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-7.xsd
@@ -212,6 +212,7 @@
</xsd:all>
</xsd:complexType>
+
<!-- The definition of the ABI supported by a platform's system image. -->
<xsd:simpleType name="abiType">
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java
index 53db79f..703cc9d 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java
@@ -44,6 +44,14 @@ public class RepoConstants {
/** The optional project-files provided by extra packages. */
public static final String NODE_PROJECT_FILES = "project-files"; //$NON-NLS-1$
+ /** A system-image package. */
+ public static final String NODE_SYSTEM_IMAGE = "system-image"; //$NON-NLS-1$
+
+ /* An included-ABI element for a system-image package. */
+ public static final String NODE_ABI_INCLUDED = "included-abi"; //$NON-NLS-1$
+ /* An ABI element for a system-image package. */
+ public static final String NODE_ABI = "abi"; //$NON-NLS-1$
+
/** The optional minimal tools revision required by platform & extra packages. */
public static final String NODE_MIN_TOOLS_REV = "min-tools-rev"; //$NON-NLS-1$
/** The optional minimal platform-tools revision required by tool packages. */
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java
index b5b0249..6b4498f 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java
@@ -24,13 +24,6 @@ import java.io.InputStream;
*/
public class SdkAddonsListConstants {
- /** The canonical URL filename for addons-list XML files. */
- public static final String URL_DEFAULT_FILENAME = "addons_list-1.xml"; //$NON-NLS-1$
-
- /** The URL where to find the official addons list fle. */
- public static final String URL_ADDON_LIST =
- SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME;
-
/** The base of our sdk-addons-list XML namespace. */
private static final String NS_BASE =
"http://schemas.android.com/sdk/android/addons-list/"; //$NON-NLS-1$
@@ -43,17 +36,30 @@ public class SdkAddonsListConstants {
/** The latest version of the sdk-addons-list XML Schema.
* Valid version numbers are between 1 and this number, included. */
- public static final int NS_LATEST_VERSION = 1;
+ public static final int NS_LATEST_VERSION = 2;
/** The XML namespace of the latest sdk-addons-list XML. */
public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION);
+
+ /** The canonical URL filename for addons-list XML files. */
+ public static final String URL_DEFAULT_FILENAME = getDefaultName(NS_LATEST_VERSION);
+
+ /** The URL where to find the official addons list fle. */
+ public static final String URL_ADDON_LIST =
+ SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME;
+
+
+
/** The root sdk-addons-list element */
public static final String NODE_SDK_ADDONS_LIST = "sdk-addons-list"; //$NON-NLS-1$
/** An add-on site. */
public static final String NODE_ADDON_SITE = "addon-site"; //$NON-NLS-1$
+ /** A system image site. */
+ public static final String NODE_SYS_IMG_SITE = "sys-img-site"; //$NON-NLS-1$
+
/** The UI-visible name of the add-on site. */
public static final String NODE_NAME = "name"; //$NON-NLS-1$
@@ -84,7 +90,7 @@ public class SdkAddonsListConstants {
* null if there is no schema for the requested version.
*/
public static InputStream getXsdStream(int version) {
- String filename = String.format("sdk-addons-list-%d.xsd", version); //$NON-NLS-1$
+ String filename = String.format("sdk-addons-list-%d.xsd", version); //$NON-NLS-1$
return SdkAddonsListConstants.class.getResourceAsStream(filename);
}
@@ -95,4 +101,8 @@ public class SdkAddonsListConstants {
public static String getSchemaUri(int version) {
return String.format(NS_BASE + "%d", version); //$NON-NLS-1$
}
+
+ public static String getDefaultName(int version) {
+ return String.format("addons_list-%1$d.xml", version); //$NON-NLS-1$
+ }
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java
index 5ad6285..e45da76 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java
@@ -107,16 +107,9 @@ public class SdkRepoConstants extends RepoConstants {
public static final String NODE_DOC = "doc"; //$NON-NLS-1$
/** A sample package. */
public static final String NODE_SAMPLE = "sample"; //$NON-NLS-1$
- /** A system-image package. */
- public static final String NODE_SYSTEM_IMAGE = "system-image"; //$NON-NLS-1$
/** A source package. */
public static final String NODE_SOURCE = "source"; //$NON-NLS-1$
- /* An included-ABI element for a system-image package. */
- public static final String NODE_ABI_INCLUDED = "included-abi"; //$NON-NLS-1$
- /* An ABI element for a system-image package. */
- public static final String NODE_ABI = "abi"; //$NON-NLS-1$
-
/**
* List of possible nodes in a repository XML. Used to populate options automatically
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java
new file mode 100755
index 0000000..cf84d60
--- /dev/null
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib.repository;
+
+
+import com.android.sdklib.internal.repository.sources.SdkSource;
+
+import java.io.InputStream;
+
+/**
+ * Public constants for the sdk-sys-img XML Schema.
+ */
+public class SdkSysImgConstants extends RepoConstants {
+
+ /**
+ * The default name looked for by {@link SdkSource} when trying to load an
+ * sdk-sys-img XML if the URL doesn't match an existing resource.
+ */
+ public static final String URL_DEFAULT_FILENAME = "sys-img.xml"; //$NON-NLS-1$
+
+ /** The base of our sdk-sys-img XML namespace. */
+ private static final String NS_BASE =
+ "http://schemas.android.com/sdk/android/sys-img/"; //$NON-NLS-1$
+
+ /**
+ * The pattern of our sdk-sys-img XML namespace.
+ * Matcher's group(1) is the schema version (integer).
+ */
+ public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$
+
+ /**
+ * The latest version of the sdk-sys-img XML Schema.
+ * Valid version numbers are between 1 and this number, included.
+ */
+ public static final int NS_LATEST_VERSION = 1;
+
+ /** The XML namespace of the latest sdk-sys-img XML. */
+ public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION);
+
+ /** The root sdk-sys-img element */
+ public static final String NODE_SDK_SYS_IMG = "sdk-sys-img"; //$NON-NLS-1$
+
+ /**
+ * List of possible nodes in a repository XML. Used to populate options automatically
+ * in the no-GUI mode.
+ */
+ public static final String[] NODES = {
+ NODE_SYSTEM_IMAGE,
+ };
+
+ /**
+ * Returns a stream to the requested {@code sdk-sys-img} XML Schema.
+ *
+ * @param version Between 1 and {@link #NS_LATEST_VERSION}, included.
+ * @return An {@link InputStream} object for the local XSD file or
+ * null if there is no schema for the requested version.
+ */
+ public static InputStream getXsdStream(int version) {
+ return getXsdStream(NODE_SDK_SYS_IMG, version);
+ }
+
+ /**
+ * Returns the URI of the sdk-sys-img schema for the given version number.
+ * @param version Between 1 and {@link #NS_LATEST_VERSION} included.
+ */
+ public static String getSchemaUri(int version) {
+ return String.format(NS_BASE + "%d", version); //$NON-NLS-1$
+ }
+}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd
index ac2113c..176fb60 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd
@@ -23,7 +23,7 @@
version="1">
<!--
- A simple list of add-ons site that is loaded by default by the SDK Manager.
+ A simple list of add-ons sites that is loaded by default by the SDK Manager.
-->
<xsd:element name="sdk-addons-list" type="sa1:addonsListType" />
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd
new file mode 100755
index 0000000..dde7214
--- /dev/null
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<xsd:schema
+ targetNamespace="http://schemas.android.com/sdk/android/addons-list/2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:sa1="http://schemas.android.com/sdk/android/addons-list/2"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1">
+
+ <!--
+ A simple list of add-ons sites that is loaded by default by the SDK Manager.
+
+ - v1: Defines <addon-site>
+ - v2: Adds support for <sys-img-site>
+ -->
+
+ <xsd:element name="sdk-addons-list" type="sa1:addonsListType" />
+
+ <xsd:complexType name="addonsListType">
+ <xsd:annotation>
+ <xsd:documentation>
+ A simple list of add-ons site.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="addon-site" type="sa1:addonSiteType" />
+ <xsd:element name="sys-img-site" type="sa1:sysImgSiteType" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <!-- The definition of an Add-on Site. -->
+
+ <xsd:complexType name="addonSiteType">
+ <xsd:annotation>
+ <xsd:documentation>An SDK add-on site.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:all>
+ <!-- The URL of the site.
+
+ This can be either the exact URL of the an XML resource conforming
+ to the latest sdk-addon-N.xsd schema, or it can be the URL of a
+ 'directory', in which case the manager will look for a resource
+ named 'addon.xml' at this location.
+
+ Examples:
+ http://www.example.com/android/my_addons.xml
+ or
+ http://www.example.com/android/
+
+ In the second example, the manager will actually look for:
+ http://www.example.com/android/addon.xml
+ -->
+ <xsd:element name="url" type="xsd:token" />
+
+ <!-- The UI-visible name of the add-on site. -->
+ <xsd:element name="name" type="xsd:normalizedString" />
+
+ </xsd:all>
+ </xsd:complexType>
+
+ <!-- The definition of an Sys-Img Site. -->
+
+ <xsd:complexType name="sysImgSiteType">
+ <xsd:annotation>
+ <xsd:documentation>An SDK sys-img site.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:all>
+ <!-- The URL of the site.
+
+ This can be either the exact URL of the an XML resource conforming
+ to the latest sdk-sys-img-N.xsd schema, or it can be the URL of a
+ 'directory', in which case the manager will look for a resource
+ named 'sysimg.xml' at this location.
+
+ Examples:
+ http://www.example.com/android/my_sys_img.xml
+ or
+ http://www.example.com/android/
+
+ In the second example, the manager will actually look for:
+ http://www.example.com/android/sysimg.xml
+ -->
+ <xsd:element name="url" type="xsd:token" />
+
+ <!-- The UI-visible name of the sys-img site. -->
+ <xsd:element name="name" type="xsd:normalizedString" />
+
+ </xsd:all>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd
new file mode 100755
index 0000000..a19aa49
--- /dev/null
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<xsd:schema
+ targetNamespace="http://schemas.android.com/sdk/android/sys-img/1"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1">
+
+ <!-- The repository contains a collection of downloadable items known as
+ "packages". Each package has a type and various attributes and contains
+ a list of file "archives" that can be downloaded for specific OSes.
+
+ An Android Addon repository is a web site that contains an "addon.xml"
+ file that conforms to this XML Schema.
+
+ History:
+ - v1 is used by the SDK Updater in Tools r20. It is split out of the
+ main SDK Repository XML Schema and can only contain <system-image> packages.
+ -->
+
+ <xsd:element name="sdk-sys-img" type="sdk:repositoryType" />
+
+ <xsd:complexType name="repositoryType">
+ <xsd:annotation>
+ <xsd:documentation>
+ The repository contains a collection of downloadable system images.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="system-image" type="sdk:systemImageType" />
+ <xsd:element name="license" type="sdk:licenseType" />
+ </xsd:choice>
+ </xsd:complexType>
+
+
+ <!-- The definition of a system image used by a platform. -->
+
+ <xsd:complexType name="systemImageType" >
+ <xsd:annotation>
+ <xsd:documentation>
+ System Image for a platform.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:all>
+ <!-- api-level+codename identifies the platform to which this system image belongs. -->
+
+ <!-- The Android API Level for the platform. An int > 0. -->
+ <xsd:element name="api-level" type="xsd:positiveInteger" />
+ <!-- The optional codename for this platform, if it's a preview. -->
+ <xsd:element name="codename" type="xsd:string" minOccurs="0" />
+
+ <!-- The revision, an int > 0, incremented each time a new
+ package is generated. -->
+ <xsd:element name="revision" type="xsd:positiveInteger" />
+
+ <!-- The ABI of the system emulated by this image. -->
+ <xsd:element name="abi" type="sdk:abiType" />
+
+ <!-- The optional license of this package. If present, users will have
+ to agree to it before downloading. -->
+ <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" />
+ <!-- The optional description of this package. -->
+ <xsd:element name="description" type="xsd:string" minOccurs="0" />
+ <!-- The optional description URL of this package -->
+ <xsd:element name="desc-url" type="xsd:token" minOccurs="0" />
+ <!-- The optional release note for this package. -->
+ <xsd:element name="release-note" type="xsd:string" minOccurs="0" />
+ <!-- The optional release note URL of this package -->
+ <xsd:element name="release-url" type="xsd:token" minOccurs="0" />
+
+ <!-- A list of file archives for this package. -->
+ <xsd:element name="archives" type="sdk:archivesType" />
+
+ <!-- An optional element indicating the package is obsolete.
+ The string content is however currently not defined and ignored. -->
+ <xsd:element name="obsolete" type="xsd:string" minOccurs="0" />
+ </xsd:all>
+ </xsd:complexType>
+
+
+ <!-- The definition of the ABI supported by a platform's system image. -->
+
+ <xsd:simpleType name="abiType">
+ <xsd:annotation>
+ <xsd:documentation>The ABI of a platform's system image.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="armeabi" />
+ <xsd:enumeration value="armeabi-v7a" />
+ <xsd:enumeration value="x86" />
+ <xsd:enumeration value="mips" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <!-- The definition of a license to be referenced by the uses-license element. -->
+
+ <xsd:complexType name="licenseType">
+ <xsd:annotation>
+ <xsd:documentation>
+ A license definition. Such a license must be used later as a reference
+ using a uses-license element in one of the package elements.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="id" type="xsd:ID" />
+ <xsd:attribute name="type" type="xsd:token" fixed="text" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+
+ <!-- Type describing the license used by a package.
+ The license MUST be defined using a license node and referenced
+ using the ref attribute of the license element inside a package.
+ -->
+
+ <xsd:complexType name="usesLicenseType">
+ <xsd:annotation>
+ <xsd:documentation>
+ Describes the license used by a package. The license MUST be defined
+ using a license node and referenced using the ref attribute of the
+ license element inside a package.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="ref" type="xsd:IDREF" />
+ </xsd:complexType>
+
+
+ <!-- A collection of files that can be downloaded for a given architecture.
+ The <archives> node is mandatory in the repository elements and the
+ collection must have at least one <archive> declared.
+ Each archive is a zip file that will be unzipped in a location that depends
+ on its package type.
+ -->
+
+ <xsd:complexType name="archivesType">
+ <xsd:annotation>
+ <xsd:documentation>
+ A collection of files that can be downloaded for a given architecture.
+ The &lt;archives&gt; node is mandatory in the repository packages and the
+ collection must have at least one &lt;archive&gt; declared.
+ Each archive is a zip file that will be unzipped in a location that depends
+ on its package type.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <!-- One archive file -->
+ <xsd:element name="archive">
+ <xsd:complexType>
+ <!-- Properties of the archive file -->
+ <xsd:all>
+ <!-- The size in bytes of the archive to download. -->
+ <xsd:element name="size" type="xsd:positiveInteger" />
+ <!-- The checksum of the archive file. -->
+ <xsd:element name="checksum" type="sdk:checksumType" />
+ <!-- The URL is an absolute URL if it starts with http://, https://
+ or ftp://. Otherwise it is relative to the parent directory that
+ contains this repository.xml -->
+ <xsd:element name="url" type="xsd:token" />
+ </xsd:all>
+
+ <!-- Attributes that identify the OS and architecture -->
+ <xsd:attribute name="os" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="any" />
+ <xsd:enumeration value="linux" />
+ <xsd:enumeration value="macosx" />
+ <xsd:enumeration value="windows" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="arch" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="any" />
+ <xsd:enumeration value="ppc" />
+ <xsd:enumeration value="x86" />
+ <xsd:enumeration value="x86_64" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <!-- The definition of a file checksum -->
+
+ <xsd:simpleType name="sha1Number">
+ <xsd:annotation>
+ <xsd:documentation>A SHA1 checksum.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="([0-9a-fA-F]){40}"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="checksumType">
+ <xsd:annotation>
+ <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleContent>
+ <xsd:extension base="sdk:sha1Number">
+ <xsd:attribute name="type" type="xsd:token" fixed="sha1" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java
index 9cf84a2..9c9c149 100755
--- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java
@@ -25,6 +25,7 @@ import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Arrays;
import junit.framework.TestCase;
@@ -75,7 +76,7 @@ public class AddonsListFetcherTest extends TestCase {
}
/**
- * Validate we can still load a valid addon schema version 1
+ * Validate we can load a valid addon schema version 1
*/
public void testLoadSample_1() throws Exception {
InputStream xmlStream =
@@ -109,21 +110,66 @@ public class AddonsListFetcherTest extends TestCase {
assertEquals("", monitor.getCapturedVerboseLog());
// check the sites we found...
+ // The XML file is UTF-8 so we support character sets (but the Java source file is
+ // not, so we use the \\u notation to create the Unicode String)
+ assertEquals(
+ "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " +
+ "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " +
+ "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>]",
+ Arrays.toString(result));
assertEquals(3, result.length);
+ }
+
+ /**
+ * Validate we can load a valid addon schema version 2
+ */
+ public void testLoadSample_2() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/addons_list_sample_2.xml");
+
+ // guess the version from the XML document
+ int version = mFetcher._getXmlSchemaVersion(xmlStream);
+ assertEquals(2, version);
+
+ Boolean[] validatorFound = new Boolean[] { Boolean.FALSE };
+ String[] validationError = new String[] { null };
+ String url = "not-a-valid-url://addons_list.xml";
+
+ String uri = mFetcher._validateXml(
+ xmlStream, url, version, validationError, validatorFound);
+ assertEquals(Boolean.TRUE, validatorFound[0]);
+ assertEquals(null, validationError[0]);
+ assertEquals(SdkAddonsListConstants.getSchemaUri(2), uri);
- assertEquals("My Example Add-ons.", result[0].getUiName());
- assertEquals("http://www.example.com/my_addons.xml", result[0].getUrl());
+ // Validation was successful, load the document
+ MockMonitor monitor = new MockMonitor();
+ Document doc = mFetcher._getDocument(xmlStream, monitor);
+ assertNotNull(doc);
+
+ // Get the sites
+ Site[] result = mFetcher._parseAddonsList(doc, uri, monitor);
+ assertEquals("", monitor.getCapturedDescriptions());
+ assertEquals("", monitor.getCapturedLog());
+ assertEquals("", monitor.getCapturedErrorLog());
+ assertEquals("", monitor.getCapturedVerboseLog());
+
+ // check the sites we found...
// The XML file is UTF-8 so we support character sets (but the Java source file is
// not, so we use the \\u notation to create the Unicode String)
- assertEquals("\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002",
- result[1].getUiName());
- assertEquals("http://www.example.co.jp/addons.xml", result[1].getUrl());
-
- assertEquals("Example of directory URL.", result[2].getUiName());
- assertEquals("http://www.example.com/", result[2].getUrl());
+ assertEquals(
+ "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " +
+ "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " +
+ "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>, " +
+ "<SYS_IMG_SITE URL='http://www.example.com/' Name='Example of sys-img URL using the default xml filename.'>, " +
+ "<SYS_IMG_SITE URL='http://www.example.com/specific_file.xml' Name='Example of sys-img URL using a specific xml filename.'>]",
+ Arrays.toString(result));
+ assertEquals(5, result.length);
}
+ // IMPORTANT: Each time you add a test here for a new version, you should
+ // also add a test in ValidateAddonsListXmlTest.
+
/**
* Returns an SdkLib file resource as a {@link ByteArrayInputStream},
* which has the advantage that we can use {@link InputStream#reset()} on it
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java
index d866018..e7950dd 100755
--- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java
@@ -41,7 +41,7 @@ import java.util.Arrays;
import junit.framework.TestCase;
/**
- * Tests for {@link SdkAddonSource}
+ * Tests for {@link SdkAddonSource}.
*/
public class SdkAddonSourceTest extends TestCase {
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java
new file mode 100755
index 0000000..96c3d40
--- /dev/null
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib.internal.repository.sources;
+
+import com.android.sdklib.internal.repository.ITaskMonitor;
+import com.android.sdklib.internal.repository.MockMonitor;
+import com.android.sdklib.internal.repository.packages.Package;
+import com.android.sdklib.internal.repository.packages.SystemImagePackage;
+import com.android.sdklib.repository.SdkSysImgConstants;
+
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SdkSysImgSource}.
+ */
+public class SdkSysImgSourceTest extends TestCase {
+
+ /**
+ * An internal helper class to give us visibility to the protected members we want
+ * to test.
+ */
+ private static class MockSdkSysImgSource extends SdkSysImgSource {
+ public MockSdkSysImgSource() {
+ super("fake-url", null /*uiName*/);
+ }
+
+ public Document _findAlternateToolsXml(InputStream xml) {
+ return super.findAlternateToolsXml(xml);
+ }
+
+ public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) {
+ return super.parsePackages(doc, nsUri, monitor);
+ }
+
+ public int _getXmlSchemaVersion(InputStream xml) {
+ return super.getXmlSchemaVersion(xml);
+ }
+
+ public String _validateXml(InputStream xml, String url, int version,
+ String[] outError, Boolean[] validatorFound) {
+ return super.validateXml(xml, url, version, outError, validatorFound);
+ }
+
+ public Document _getDocument(InputStream xml, ITaskMonitor monitor) {
+ return super.getDocument(xml, monitor);
+ }
+
+ }
+
+ private MockSdkSysImgSource mSource;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mSource = new MockSdkSysImgSource();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ mSource = null;
+ }
+
+ /**
+ * Validate that findAlternateToolsXml doesn't work for this source even
+ * when trying to load a valid xml. That's because finding alternate tools
+ * is not supported by this kind of source.
+ */
+ public void testFindAlternateToolsXml_1() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/sys_img_sample_1.xml");
+
+ Document result = mSource._findAlternateToolsXml(xmlStream);
+ assertNull(result);
+ }
+
+ /**
+ * Validate we can load a valid schema version 1
+ */
+ public void testLoadSysImgXml_1() throws Exception {
+ InputStream xmlStream =
+ getTestResource("/com/android/sdklib/testdata/sys_img_sample_1.xml");
+
+ // guess the version from the XML document
+ int version = mSource._getXmlSchemaVersion(xmlStream);
+ assertEquals(1, version);
+
+ Boolean[] validatorFound = new Boolean[] { Boolean.FALSE };
+ String[] validationError = new String[] { null };
+ String url = "not-a-valid-url://" + SdkSysImgConstants.URL_DEFAULT_FILENAME;
+
+ String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound);
+ assertEquals(Boolean.TRUE, validatorFound[0]);
+ assertEquals(null, validationError[0]);
+ assertEquals(SdkSysImgConstants.getSchemaUri(1), uri);
+
+ // Validation was successful, load the document
+ MockMonitor monitor = new MockMonitor();
+ Document doc = mSource._getDocument(xmlStream, monitor);
+ assertNotNull(doc);
+
+ // Get the packages
+ assertTrue(mSource._parsePackages(doc, uri, monitor));
+
+ assertEquals(
+ "Found Intel x86 Atom System Image, Android API 2, revision 1\n" +
+ "Found ARM EABI v7a System Image, Android API 2, revision 2\n" +
+ "Found ARM EABI System Image, Android API 42, revision 12\n" +
+ "Found Mips System Image, Android API 42, revision 12\n",
+ monitor.getCapturedVerboseLog());
+ assertEquals("", monitor.getCapturedLog());
+ assertEquals("", monitor.getCapturedErrorLog());
+
+ // check the packages we found...
+ // Note the order doesn't necessary match the one from the
+ // assertEquald(getCapturedVerboseLog) because packages are sorted using the
+ // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc.
+
+ Package[] pkgs = mSource.getPackages();
+
+ assertEquals(4, pkgs.length);
+ for (Package p : pkgs) {
+ // We expected to find packages with each at least one archive.
+ assertTrue(p.getArchives().length >= 1);
+ // And only system images are supported by this source
+ assertTrue(p instanceof SystemImagePackage);
+ }
+
+ // Check the system-image packages
+ ArrayList<String> sysImgVersionAbi = new ArrayList<String>();
+ for (Package p : pkgs) {
+ if (p instanceof SystemImagePackage) {
+ SystemImagePackage sip = (SystemImagePackage) p;
+ String v = sip.getAndroidVersion().getApiString();
+ String a = sip.getAbi();
+ sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$
+ }
+ }
+ assertEquals(
+ "[42 armeabi, " +
+ "42 mips, " +
+ "2 armeabi-v7a, " +
+ "2 x86]",
+ Arrays.toString(sysImgVersionAbi.toArray()));
+
+ }
+
+
+ //-----
+
+ /**
+ * Returns an SdkLib file resource as a {@link ByteArrayInputStream},
+ * which has the advantage that we can use {@link InputStream#reset()} on it
+ * at any time to read it multiple times.
+ * <p/>
+ * The default for getResourceAsStream() is to return a {@link FileInputStream} that
+ * does not support reset(), yet we need it in the tested code.
+ *
+ * @throws IOException if some I/O read fails
+ */
+ private ByteArrayInputStream getTestResource(String filename) throws IOException {
+ InputStream xmlStream = this.getClass().getResourceAsStream(filename);
+
+ try {
+ byte[] data = new byte[8192];
+ int offset = 0;
+ int n;
+
+ while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) {
+ offset += n;
+
+ if (offset == data.length) {
+ byte[] newData = new byte[offset + 8192];
+ System.arraycopy(data, 0, newData, 0, offset);
+ data = newData;
+ }
+ }
+
+ return new ByteArrayInputStream(data, 0, offset);
+ } finally {
+ if (xmlStream != null) {
+ xmlStream.close();
+ }
+ }
+ }
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java
index d88d566..40ff727 100755
--- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java
@@ -49,7 +49,7 @@ public class ValidateAddonXmlTest extends TestCase {
/**
* Helper method that returns a validator for our Addon XSD
*
- * @param version The versoion number, in range {@code 1..NS_LATEST_VERSION}
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
* @param handler A {@link CaptureErrorHandler}. If null the default will be used,
* which will most likely print errors to stderr.
*/
@@ -80,7 +80,7 @@ public class ValidateAddonXmlTest extends TestCase {
// --- Tests ------------
- /** Validates that NS_LATEST_VERSION points to the max avaialble XSD schema. */
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
public void testAddonLatestVersionNumber() throws Exception {
CaptureErrorHandler handler = new CaptureErrorHandler();
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java
new file mode 100755
index 0000000..2f68e41
--- /dev/null
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib.repository;
+
+import com.android.annotations.Nullable;
+
+import org.xml.sax.SAXException;
+
+import java.io.InputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests local validation of an SDK Addon-List sample XMLs using an XML Schema validator.
+ */
+public class ValidateAddonsListXmlTest extends TestCase {
+
+ // --- Helpers ------------
+
+ /**
+ * Helper method that returns a validator for our Addons-List XSD
+ *
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
+ * @param handler A {@link CaptureErrorHandler}. If null the default will be used,
+ * which will most likely print errors to stderr.
+ */
+ private Validator getValidator(int version, @Nullable CaptureErrorHandler handler)
+ throws SAXException {
+ Validator validator = null;
+ InputStream xsdStream = SdkAddonsListConstants.getXsdStream(version);
+ if (xsdStream != null) {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));
+ validator = schema.newValidator();
+ if (handler != null) {
+ validator.setErrorHandler(handler);
+ }
+ }
+
+ return validator;
+ }
+
+ // --- Tests ------------
+
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
+ public void testAddonLatestVersionNumber() throws Exception {
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+
+ // There should be a schema matching NS_LATEST_VERSION
+ assertNotNull(getValidator(SdkAddonsListConstants.NS_LATEST_VERSION, handler));
+
+ // There should NOT be a schema with NS_LATEST_VERSION+1
+ assertNull(
+ String.format(
+ "There's an ADDON XSD at version %d but SdkAddonsListConstants.NS_LATEST_VERSION is still set to %d.",
+ SdkAddonsListConstants.NS_LATEST_VERSION + 1,
+ SdkAddonsListConstants.NS_LATEST_VERSION),
+ getValidator(SdkAddonsListConstants.NS_LATEST_VERSION + 1, handler));
+ }
+
+ /** Validate a valid sample using namespace version 1 using an InputStream */
+ public void testValidateLocalAddonFile1() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/addons_list_sample_1.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(1, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ /** Validate a valid sample using namespace version 2 using an InputStream */
+ public void testValidateLocalAddonFile2() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/addons_list_sample_2.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(2, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ // IMPORTANT: each time you add a test here, you should add a corresponding
+ // test in AddonsListFetcherTest to validate the XML content is parsed correctly.
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java
index 648ff05..c5ceb3e 100755
--- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java
@@ -52,7 +52,7 @@ public class ValidateRepositoryXmlTest extends TestCase {
/**
* Helper method that returns a validator for our Repository XSD
*
- * @param version The versoion number, in range {@code 1..NS_LATEST_VERSION}
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
* @param handler A {@link CaptureErrorHandler}. If null the default will be used,
* which will most likely print errors to stderr.
*/
@@ -84,7 +84,7 @@ public class ValidateRepositoryXmlTest extends TestCase {
// --- Tests ------------
- /** Validates that NS_LATEST_VERSION points to the max avaialble XSD schema. */
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
public void testRepoLatestVersionNumber() throws Exception {
CaptureErrorHandler handler = new CaptureErrorHandler();
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java
new file mode 100755
index 0000000..6933634
--- /dev/null
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib.repository;
+
+import com.android.annotations.Nullable;
+
+import org.xml.sax.SAXException;
+
+import java.io.InputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests local validation of an SDK Repository sample XMLs using an XML Schema validator.
+ *
+ * References:
+ * http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html
+ */
+public class ValidateSysImgXmlTest extends TestCase {
+
+ // --- Helpers ------------
+
+ /**
+ * Helper method that returns a validator for our Repository XSD
+ *
+ * @param version The version number, in range {@code 1..NS_LATEST_VERSION}
+ * @param handler A {@link CaptureErrorHandler}. If null the default will be used,
+ * which will most likely print errors to stderr.
+ */
+ private Validator getValidator(int version, @Nullable CaptureErrorHandler handler)
+ throws SAXException {
+ Validator validator = null;
+ InputStream xsdStream = SdkSysImgConstants.getXsdStream(version);
+ if (xsdStream != null) {
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));
+ validator = schema.newValidator();
+
+ if (handler != null) {
+ validator.setErrorHandler(handler);
+ }
+ }
+
+ return validator;
+ }
+
+ // --- Tests ------------
+
+ /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */
+ public void testSysImgLatestVersionNumber() throws Exception {
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+
+ // There should be a schema matching NS_LATEST_VERSION
+ assertNotNull(getValidator(SdkSysImgConstants.NS_LATEST_VERSION, handler));
+
+ // There should NOT be a schema with NS_LATEST_VERSION+1
+ assertNull(
+ String.format(
+ "There's a REPO XSD at version %d but SdkSysImgConstants.NS_LATEST_VERSION is still set to %d.",
+ SdkSysImgConstants.NS_LATEST_VERSION + 1,
+ SdkSysImgConstants.NS_LATEST_VERSION),
+ getValidator(SdkSysImgConstants.NS_LATEST_VERSION + 1, handler));
+ }
+
+ /** Validate a valid sample using namespace version 1 using an InputStream */
+ public void testValidateLocalRepositoryFile1() throws Exception {
+ InputStream xmlStream = this.getClass().getResourceAsStream(
+ "/com/android/sdklib/testdata/sys_img_sample_1.xml");
+ Source source = new StreamSource(xmlStream);
+
+ CaptureErrorHandler handler = new CaptureErrorHandler();
+ Validator validator = getValidator(1, handler);
+ validator.validate(source);
+ handler.verify();
+ }
+
+ // IMPORTANT: each time you add a test here, you should add a corresponding
+ // test in SdkSysImgSourceTest to validate the XML content is parsed correctly.
+
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml
new file mode 100755
index 0000000..4e4907c
--- /dev/null
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<sdk:sdk-addons-list
+ xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/2">
+
+ <sdk:addon-site>
+ <sdk:url>http://www.example.com/my_addons.xml</sdk:url>
+ <sdk:name> <!-- we'll ignore leading/trailing spacing -->
+ My Example Add-ons.
+ </sdk:name>
+ </sdk:addon-site>
+
+ <sdk:addon-site>
+ <sdk:url>http://www.example.co.jp/addons.xml</sdk:url>
+ <!-- this file is UTF-8 so we support character sets -->
+ <sdk:name>ありがとうございます。</sdk:name>
+ </sdk:addon-site>
+
+ <sdk:addon-site>
+ <sdk:url>http://www.example.com/</sdk:url>
+ <sdk:name>Example of directory URL.</sdk:name>
+ </sdk:addon-site>
+
+ <sdk:sys-img-site>
+ <sdk:url>http://www.example.com/</sdk:url>
+ <sdk:name>Example of sys-img URL using the default xml filename.</sdk:name>
+ </sdk:sys-img-site>
+
+ <sdk:sys-img-site>
+ <sdk:url>http://www.example.com/specific_file.xml</sdk:url>
+ <sdk:name>Example of sys-img URL using a specific xml filename.</sdk:name>
+ </sdk:sys-img-site>
+
+</sdk:sdk-addons-list>
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml
new file mode 100755
index 0000000..6196db4
--- /dev/null
+++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<sdk:sdk-sys-img
+ xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1">
+
+ <!-- Define a couple of licenses. These will be referenced by uses-license later. -->
+
+ <sdk:license type="text" id="license1">
+ This is the license
+ for this platform.
+ </sdk:license>
+
+ <sdk:license id="license2">
+ Licenses are only of type 'text' right now, so this is implied.
+ </sdk:license>
+
+ <sdk:system-image>
+ <sdk:api-level>2</sdk:api-level>
+ <sdk:revision>1</sdk:revision>
+ <sdk:abi>x86</sdk:abi>
+ <sdk:archives>
+ <sdk:archive os="any">
+ <sdk:size>65535</sdk:size>
+ <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum>
+ <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url>
+ </sdk:archive>
+ </sdk:archives>
+ </sdk:system-image>
+
+ <sdk:system-image>
+ <sdk:api-level>2</sdk:api-level>
+ <sdk:revision>2</sdk:revision>
+ <sdk:abi>armeabi-v7a</sdk:abi>
+ <sdk:archives>
+ <sdk:archive os="any">
+ <sdk:size>65534</sdk:size>
+ <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum>
+ <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url>
+ </sdk:archive>
+ </sdk:archives>
+ </sdk:system-image>
+
+ <sdk:system-image>
+ <sdk:api-level>42</sdk:api-level>
+ <sdk:revision>12</sdk:revision>
+ <sdk:abi>armeabi</sdk:abi>
+ <sdk:archives>
+ <sdk:archive os="any">
+ <sdk:size>1234</sdk:size>
+ <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum>
+ <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url>
+ </sdk:archive>
+ </sdk:archives>
+ </sdk:system-image>
+
+ <sdk:system-image>
+ <sdk:api-level>42</sdk:api-level>
+ <sdk:revision>12</sdk:revision>
+ <sdk:abi>mips</sdk:abi>
+ <sdk:archives>
+ <sdk:archive os="any">
+ <sdk:size>12345</sdk:size>
+ <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum>
+ <sdk:url>http://www.example.com/plat42/mips/image12.zip</sdk:url>
+ </sdk:archive>
+ </sdk:archives>
+ </sdk:system-image>
+
+</sdk:sdk-sys-img>
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
index 10b02c6..d1078d0 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AddonSitesDialog.java
@@ -382,9 +382,7 @@ public class AddonSitesDialog extends UpdaterBaseDialog {
// create the source, store it and update the list
SdkAddonSource newSource = new SdkAddonSource(url, null/*uiName*/);
- mSources.add(
- SdkSourceCategory.USER_ADDONS,
- newSource);
+ mSources.add(SdkSourceCategory.USER_ADDONS, newSource);
setReturnValue(true);
// notify sources change listeners. This will invoke our own loadUserUrlsList().
mSources.notifyChangeListeners();
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java
index 4ad78b8..983c94d 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackageLoader.java
@@ -29,6 +29,7 @@ import com.android.sdklib.internal.repository.sources.SdkAddonSource;
import com.android.sdklib.internal.repository.sources.SdkSource;
import com.android.sdklib.internal.repository.sources.SdkSourceCategory;
import com.android.sdklib.internal.repository.sources.SdkSources;
+import com.android.sdklib.internal.repository.sources.SdkSysImgSource;
import com.android.sdklib.repository.SdkAddonsListConstants;
import com.android.sdklib.repository.SdkRepoConstants;
import com.android.sdkuilib.internal.repository.UpdaterData;
@@ -448,8 +449,16 @@ public class PackageLoader {
if (fetch3rdParties) {
for (Site s : sites) {
- sources.add(SdkSourceCategory.ADDONS_3RD_PARTY,
- new SdkAddonSource(s.getUrl(), s.getUiName()));
+ switch (s.getType()) {
+ case ADDON_SITE:
+ sources.add(SdkSourceCategory.ADDONS_3RD_PARTY,
+ new SdkAddonSource(s.getUrl(), s.getUiName()));
+ break;
+ case SYS_IMG_SITE:
+ sources.add(SdkSourceCategory.ADDONS_3RD_PARTY,
+ new SdkSysImgSource(s.getUrl(), s.getUiName()));
+ break;
+ }
}
}