aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2011-06-24 12:22:00 -0700
committerAndroid Code Review <code-review@android.com>2011-06-24 12:22:00 -0700
commitc233709ec350fd0b2364c84a98194fa3351b2017 (patch)
tree2c7293abdd4058f3e35618934284e85c595df03c
parent148fe1908137e7f5ce24a5f2170a7254a71fc57d (diff)
parentcc556534e4b9e8e42e65f6ded684430858238471 (diff)
downloadsdk-c233709ec350fd0b2364c84a98194fa3351b2017.zip
sdk-c233709ec350fd0b2364c84a98194fa3351b2017.tar.gz
sdk-c233709ec350fd0b2364c84a98194fa3351b2017.tar.bz2
Merge "Sdkman2: Simplify packages names, fix extra package sort."
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java18
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java77
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackagesPage.java198
3 files changed, 226 insertions, 67 deletions
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java
index c142faf..793c98d 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ExtraPackage.java
@@ -526,6 +526,24 @@ public class ExtraPackage extends MinToolsPackage
return false;
}
+ /**
+ * For extra packages, we want to add vendor|path to the sorting key
+ * <em>before<em/> the revision number.
+ * <p/>
+ * {@inheritDoc}
+ */
+ @Override
+ protected String comparisonKey() {
+ String s = super.comparisonKey();
+ int pos = s.indexOf("|r:"); //$NON-NLS-1$
+ assert pos > 0;
+ s = s.substring(0, pos) +
+ "|ve:" + getVendor() + //$NON-NLS-1$
+ "|pa:" + getPath() + //$NON-NLS-1$
+ s.substring(pos);
+ return s;
+ }
+
// ---
/**
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
index baa6706..faf5a00 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
@@ -557,46 +557,83 @@ public abstract class Package implements IDescription, Comparable<Package> {
* <p/>
* This {@link #compareTo(Package)} method is purely an implementation detail to
* perform the right ordering of the packages in the list of available or installed packages.
+ * <p/>
+ * <em>Important</em>: Derived classes should consider overriding {@link #comparisonKey()}
+ * instead of this method.
*/
public int compareTo(Package other) {
- int s1 = this.sortingScore();
- int s2 = other.sortingScore();
- return s1 - s2;
+ String s1 = this.comparisonKey();
+ String s2 = other.comparisonKey();
+
+ return s1.compareTo(s2);
}
/**
- * Computes the score for each package used by {@link #compareTo(Package)}.
+ * Computes a comparison key for each package used by {@link #compareTo(Package)}.
+ * The key is a string.
+ * The base package class return a string that encodes the package type,
+ * the revision number and the platform version, if applicable, in the form:
+ * <pre>
+ * t:N|v:NNNN.P|r:NNNN|
+ * </pre>
+ * All fields must start by a "letter colon" prefix and end with a vertical pipe (|, ASCII 124).
+ * <p/>
+ * The string format <em>may</em> change between releases and clients should not
+ * store them outside of the session or expect them to be consistent between
+ * different releases. They are purely an internal implementation details of the
+ * {@link #compareTo(Package)} method.
+ * <p/>
+ * Derived classes should get the string from the super class and then append
+ * or <em>insert</em> their own |-separated content.
+ * For example an extra vendor name & path can be inserted before the revision
+ * number, since it has more sorting weight.
*/
- private int sortingScore() {
- // up to 31 bits (for signed stuff)
- int type = 0; // max type=7 => 3 bits
- int rev = getRevision(); // 12 bits... 4095
- int offset = 0; // 16 bits...
+ protected String comparisonKey() {
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("t:"); //$NON-NLS-1$
if (this instanceof ToolPackage) {
- type = 6;
+ sb.append(0);
} else if (this instanceof PlatformToolPackage) {
- type = 5;
+ sb.append(1);
} else if (this instanceof DocPackage) {
- type = 4;
+ sb.append(2);
} else if (this instanceof PlatformPackage) {
- type = 3;
+ sb.append(3);
} else if (this instanceof SamplePackage) {
- type = 2;
+ sb.append(4);
} else if (this instanceof AddonPackage) {
- type = 1;
+ sb.append(5);
} else {
// extras and everything else
- type = 0;
+ sb.append(9);
}
+ sb.append("|v:"); //$NON-NLS-1$
+
+
+ // We insert the package version here because it is more important
+ // than the revision number. We want package version to be sorted
+ // top-down, so we'll use 10k-api as the sorting key. The day we
+ // get reach 10k APIs, we'll need to revisit this.
if (this instanceof IPackageVersion) {
AndroidVersion v = ((IPackageVersion) this).getVersion();
- offset = v.getApiLevel();
- offset = offset * 2 + (v.isPreview() ? 1 : 0);
+
+ sb.append(String.format("%1$04d.%2$d", //$NON-NLS-1$
+ 10000 - v.getApiLevel(),
+ v.isPreview() ? 1 : 0
+ ));
}
+ sb.append("|r:"); //$NON-NLS-1$
+
- int n = (type << 28) + (offset << 12) + rev;
- return 0 - n;
+ // Append revision number
+
+ sb.append(String.format("%1$04d", getRevision())); //$NON-NLS-1$
+ sb.append('|');
+
+ return sb.toString();
}
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackagesPage.java
index 570f769..2b7a0db 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackagesPage.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackagesPage.java
@@ -147,6 +147,7 @@ public class PackagesPage extends UpdaterPage
private TreeViewerColumn mColumnStatus;
private Font mTreeFontItalic;
private TreeColumn mTreeColumnName;
+ private boolean mLastSortWasByApi;
public PackagesPage(Composite parent, int swtStyle, UpdaterData updaterData) {
super(parent, swtStyle);
@@ -532,7 +533,7 @@ public class PackagesPage extends UpdaterPage
}
private void sortPackages(boolean updateButtons) {
- if (mCheckSortApi != null && !mCheckSortApi.isDisposed() && mCheckSortApi.getSelection()) {
+ if (isSortByApi()) {
sortByApiLevel();
} else {
sortBySource();
@@ -543,6 +544,10 @@ public class PackagesPage extends UpdaterPage
}
}
+ private boolean isSortByApi() {
+ return mCheckSortApi != null && !mCheckSortApi.isDisposed() && mCheckSortApi.getSelection();
+ }
+
/**
* Recompute the tree by sorting all the packages by API.
* This does an update in-place of the mCategories list so that the table
@@ -556,34 +561,44 @@ public class PackagesPage extends UpdaterPage
mTreeColumnName.setImage(getImage(ICON_SORT_BY_API));
}
+ // If the sorting mode changed, clear the categories.
+ if (!mLastSortWasByApi) {
+ mLastSortWasByApi = true;
+ mCategories.clear();
+ }
+
// keep a map of the initial state so that we can detect which items or categories are
// no longer being used, so that we can removed them at the end of the in-place update.
- final Map<Integer, Pair<PkgCategory, HashSet<PkgItem>> > unusedItemsMap =
- new HashMap<Integer, Pair<PkgCategory, HashSet<PkgItem>> >();
- final Set<PkgCategory> unusedCatSet = new HashSet<PkgCategory>();
+ final Map<Integer, Pair<PkgApiCategory, HashSet<PkgItem>> > unusedItemsMap =
+ new HashMap<Integer, Pair<PkgApiCategory, HashSet<PkgItem>> >();
+ final Set<PkgApiCategory> unusedCatSet = new HashSet<PkgApiCategory>();
// get existing categories
for (PkgCategory cat : mCategories) {
- unusedCatSet.add(cat);
- unusedItemsMap.put(cat.getKey(), Pair.of(cat, new HashSet<PkgItem>(cat.getItems())));
+ if (cat instanceof PkgApiCategory) {
+ PkgApiCategory acat = (PkgApiCategory) cat;
+ unusedCatSet.add(acat);
+ unusedItemsMap.put(acat.getKey(),
+ Pair.of(acat, new HashSet<PkgItem>(acat.getItems())));
+ }
}
// always add the tools & extras categories, even if empty (unlikely anyway)
- if (!unusedItemsMap.containsKey(PkgCategory.KEY_TOOLS)) {
- PkgCategory cat = new PkgCategory(
- PkgCategory.KEY_TOOLS,
- "Tools",
+ if (!unusedItemsMap.containsKey(PkgApiCategory.KEY_TOOLS)) {
+ PkgApiCategory cat = new PkgApiCategory(
+ PkgApiCategory.KEY_TOOLS,
+ null,
imgFactory.getImageByName(ICON_CAT_OTHER));
- unusedItemsMap.put(PkgCategory.KEY_TOOLS, Pair.of(cat, new HashSet<PkgItem>()));
+ unusedItemsMap.put(PkgApiCategory.KEY_TOOLS, Pair.of(cat, new HashSet<PkgItem>()));
mCategories.add(cat);
}
- if (!unusedItemsMap.containsKey(PkgCategory.KEY_EXTRA)) {
- PkgCategory cat = new PkgCategory(
- PkgCategory.KEY_EXTRA,
- "Extras",
+ if (!unusedItemsMap.containsKey(PkgApiCategory.KEY_EXTRA)) {
+ PkgApiCategory cat = new PkgApiCategory(
+ PkgApiCategory.KEY_EXTRA,
+ null,
imgFactory.getImageByName(ICON_CAT_OTHER));
- unusedItemsMap.put(PkgCategory.KEY_EXTRA, Pair.of(cat, new HashSet<PkgItem>()));
+ unusedItemsMap.put(PkgApiCategory.KEY_EXTRA, Pair.of(cat, new HashSet<PkgItem>()));
mCategories.add(cat);
}
@@ -597,13 +612,13 @@ public class PackagesPage extends UpdaterPage
if (apiKey < 1) {
Package p = item.getPackage();
if (p instanceof ToolPackage || p instanceof PlatformToolPackage) {
- apiKey = PkgCategory.KEY_TOOLS;
+ apiKey = PkgApiCategory.KEY_TOOLS;
} else {
- apiKey = PkgCategory.KEY_EXTRA;
+ apiKey = PkgApiCategory.KEY_EXTRA;
}
}
- Pair<PkgCategory, HashSet<PkgItem>> mapEntry = unusedItemsMap.get(apiKey);
+ Pair<PkgApiCategory, HashSet<PkgItem>> mapEntry = unusedItemsMap.get(apiKey);
if (mapEntry == null) {
// This is a new category. Create it and add it to the map.
@@ -613,28 +628,25 @@ public class PackagesPage extends UpdaterPage
// If we don't (e.g. when installing a new platform that isn't yet available
// locally in the SDK Manager), it's OK we'll try to find the first platform
// package available.
- String label = null;
+ String platformName = null;
if (apiKey != -1) {
for (IAndroidTarget target : mUpdaterData.getSdkManager().getTargets()) {
if (target.isPlatform() && target.getVersion().getApiLevel() == apiKey) {
- label = target.getVersionName();
- if (label != null) {
- label = String.format("Android %1$s (API %2$d)", label, apiKey);
- break;
- }
+ platformName = target.getVersionName();
+ break;
}
}
}
- PkgCategory cat = new PkgCategory(
+ PkgApiCategory cat = new PkgApiCategory(
apiKey,
- label,
+ platformName,
imgFactory.getImageByName(ICON_CAT_PLATFORM));
mapEntry = Pair.of(cat, new HashSet<PkgItem>());
unusedItemsMap.put(apiKey, mapEntry);
mCategories.add(0, cat);
}
- PkgCategory cat = mapEntry.getFirst();
+ PkgApiCategory cat = mapEntry.getFirst();
assert cat != null;
unusedCatSet.remove(cat);
@@ -644,14 +656,13 @@ public class PackagesPage extends UpdaterPage
cat.getItems().add(item);
}
- if (apiKey != -1 && cat.getLabel() == null) {
+ if (apiKey != -1 && cat.getPlatformName() == null) {
// Check whether we can get the actual platform version name (e.g. "1.5")
// from the first Platform package we find in this category.
Package p = item.getPackage();
if (p instanceof PlatformPackage) {
- String vn = ((PlatformPackage) p).getVersionName();
- String name = String.format("Android %1$s (API %2$d)", vn, apiKey);
- cat.setLabel(name);
+ String platformName = ((PlatformPackage) p).getVersionName();
+ cat.setPlatformName(platformName);
}
}
}
@@ -667,7 +678,10 @@ public class PackagesPage extends UpdaterPage
// Remove any unused items in the category.
int apikey = cat.getKey();
- Pair<PkgCategory, HashSet<PkgItem>> mapEntry = unusedItemsMap.get(apikey);
+ Pair<PkgApiCategory, HashSet<PkgItem>> mapEntry = unusedItemsMap.get(apikey);
+ if (mapEntry == null) { //DEBUG
+ apikey = (apikey + 1) - 1;
+ }
assert mapEntry != null;
HashSet<PkgItem> unusedItems = mapEntry.getSecond();
for (Iterator<PkgItem> iterItem = cat.getItems().iterator(); iterItem.hasNext(); ) {
@@ -679,13 +693,6 @@ public class PackagesPage extends UpdaterPage
// Sort the items
Collections.sort(cat.getItems());
-
- // Fix the category name for any API where we might not have found a platform package.
- if (cat.getLabel() == null) {
- int api = cat.getKey();
- String name = String.format("API %1$d", api);
- cat.setLabel(name);
- }
}
// Sort the categories list.
@@ -716,6 +723,7 @@ public class PackagesPage extends UpdaterPage
mTreeColumnName.setImage(getImage(ICON_SORT_BY_SOURCE));
}
+ mLastSortWasByApi = false;
mCategories.clear();
Set<SdkSource> sourceSet = new HashSet<SdkSource>();
@@ -1075,7 +1083,7 @@ public class PackagesPage extends UpdaterPage
if (element instanceof PkgCategory) {
return ((PkgCategory) element).getLabel();
} else if (element instanceof PkgItem) {
- return ((PkgItem) element).getName();
+ return getPkgItemname((PkgItem) element);
} else if (element instanceof IDescription) {
return ((IDescription) element).getShortDescription();
}
@@ -1133,6 +1141,41 @@ public class PackagesPage extends UpdaterPage
return ""; //$NON-NLS-1$
}
+ private String getPkgItemname(PkgItem item) {
+ String name = item.getName().trim();
+
+ if (isSortByApi()) {
+ // When sorting by API, the package name might contains the API number
+ // or the platform name at the end. If we find it, cut it out since it's
+ // redundant.
+
+ PkgApiCategory cat = (PkgApiCategory) findCategoryForItem(item);
+ String apiLabel = cat.getApiLabel();
+ String platLabel = cat.getPlatformName();
+
+ if (platLabel != null && name.endsWith(platLabel)) {
+ return name.substring(0, name.length() - platLabel.length());
+
+ } else if (apiLabel != null && name.endsWith(apiLabel)) {
+ return name.substring(0, name.length() - apiLabel.length());
+ }
+ }
+
+ return name;
+ }
+
+ private PkgCategory findCategoryForItem(PkgItem item) {
+ for (PkgCategory cat : mCategories) {
+ for (PkgItem i : cat.getItems()) {
+ if (i == item) {
+ return cat;
+ }
+ }
+ }
+
+ return null;
+ }
+
@Override
public Image getImage(Object element) {
ImageFactory imgFactory = mUpdaterData.getImageFactory();
@@ -1263,14 +1306,9 @@ public class PackagesPage extends UpdaterPage
private final List<PkgItem> mItems = new ArrayList<PkgItem>();
private String mLabel;
-
// When sorting by Source, key is the hash of the source's name.
// When storing by API, key is the API level (>=1). Tools and extra have the
- // special values so they get naturally sorted the way we want them.
- // (Note: don't use max to avoid integers wrapping in comparisons. We can
- // revisit the day we get 2^30 platforms.)
- public final static int KEY_TOOLS = Integer.MAX_VALUE / 2;
- public final static int KEY_EXTRA = -1;
+ // special values.
public PkgCategory(int key, String label, Object iconRef) {
mKey = key;
@@ -1299,6 +1337,72 @@ public class PackagesPage extends UpdaterPage
}
}
+ private static class PkgApiCategory extends PkgCategory {
+
+ /** Platform name, in the form "Android 1.2". Can be null if we don't have the name. */
+ private String mPlatformName;
+
+ // When sorting by Source, key is the hash of the source's name.
+ // When storing by API, key is the API level (>=1). Tools and extra have the
+ // special values so they get naturally sorted the way we want them.
+ // (Note: don't use max to avoid integers wrapping in comparisons. We can
+ // revisit the day we get 2^30 platforms.)
+ public final static int KEY_TOOLS = Integer.MAX_VALUE / 2;
+ public final static int KEY_EXTRA = -1;
+
+ public PkgApiCategory(int apiKey, String platformName, Object iconRef) {
+ super(apiKey, null /*label*/, iconRef);
+ setPlatformName(platformName);
+ }
+
+ public String getPlatformName() {
+ return mPlatformName;
+ }
+
+ public void setPlatformName(String platformName) {
+ if (platformName != null) {
+ // Normal case for actual platform categories
+ mPlatformName = String.format("Android %1$s", platformName);
+ super.setLabel(null);
+ }
+ }
+
+ public String getApiLabel() {
+ int api = getKey();
+ if (api > 0) {
+ return String.format("API %1$d", getKey());
+ }
+ return null;
+ }
+
+ @Override
+ public String getLabel() {
+ String label = super.getLabel();
+ if (label == null) {
+ int key = getKey();
+
+ if (key == KEY_TOOLS) {
+ label = "Tools";
+ } else if (key == KEY_EXTRA) {
+ label = "Extras";
+ } else {
+ if (mPlatformName != null) {
+ label = String.format("%1$s (%2$s)", mPlatformName, getApiLabel());
+ } else {
+ label = getApiLabel();
+ }
+ }
+ super.setLabel(label);
+ }
+ return label;
+ }
+
+ @Override
+ public void setLabel(String label) {
+ throw new UnsupportedOperationException("Use setPlatformName() instead."); //$NON-NLS-1$
+ }
+ }
+
private class PackageManagerImpl extends PackageManager {
public PackageManagerImpl(UpdaterData updaterData) {