diff options
Diffstat (limited to 'sdkmanager')
2 files changed, 125 insertions, 41 deletions
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java index 8a525e3..26211c3 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/AdtUpdateDialog.java @@ -22,6 +22,7 @@ import com.android.sdklib.ISdkLog; import com.android.sdklib.internal.repository.ExtraPackage;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.PlatformPackage;
+import com.android.sdklib.internal.repository.SdkSource;
import com.android.sdkuilib.internal.repository.SettingsController;
import com.android.sdkuilib.internal.repository.UpdaterData;
import com.android.sdkuilib.internal.repository.sdkman2.PackageLoader.IAutoInstallTask;
@@ -61,6 +62,8 @@ import java.io.File; */
public class AdtUpdateDialog extends SwtBaseDialog {
+ public static final int USE_MAX_REMOTE_API_LEVEL = 0;
+
private static final String APP_NAME = "Android SDK Manager";
private final UpdaterData mUpdaterData;
@@ -105,25 +108,48 @@ public class AdtUpdateDialog extends SwtBaseDialog { * @wbp.parser.entryPoint
*/
public Pair<Boolean, File> installExtraPackage(String vendor, String path) {
- mPackageFilter = PackageFilter.createExtraFilter(vendor, path);
+ mPackageFilter = createExtraFilter(vendor, path);
open();
return Pair.of(mResultCode, mResultPath);
}
/**
- * Displays the update dialog and triggers installation of the requested {@code platform}
- * package with the specified api level attributes.
+ * Displays the update dialog and triggers installation of the requested platform
+ * package with the specified API level.
* <p/>
* Callers must not try to reuse this dialog after this call.
*
- * @param apiLevel The platform api level to match.
+ * @param apiLevel The platform API level to match.
+ * The special value {@link #USE_MAX_REMOTE_API_LEVEL} means to use
+ * the highest API level available on the remote repository.
* @return A boolean indicating whether the installation was successful (meaning the package
* was either already present, or got installed or updated properly) and a {@link File}
* with the path to the root folder of the package. The file is null when the boolean
* is false, otherwise it should point to an existing valid folder.
*/
public Pair<Boolean, File> installPlatformPackage(int apiLevel) {
- mPackageFilter = PackageFilter.createPlatformFilter(apiLevel);
+ mPackageFilter = createPlatformFilter(apiLevel, false /*forceRemote*/);
+ open();
+ return Pair.of(mResultCode, mResultPath);
+ }
+
+ /**
+ * Displays the update dialog and triggers installation of a new SDK. This works by
+ * requesting a remote platform package with the specified API level.
+ * By dependency, any missing tools or platform-tools packages will also be installed.
+ * <p/>
+ * Callers must not try to reuse this dialog after this call.
+ *
+ * @param apiLevel The platform API level to match.
+ * The special value {@link #USE_MAX_REMOTE_API_LEVEL} means to use
+ * the highest API level available on the repository.
+ * @return A boolean indicating whether the installation was successful (meaning the package
+ * was either already present, or got installed or updated properly) and a {@link File}
+ * with the path to the root folder of the package. The file is null when the boolean
+ * is false, otherwise it should point to an existing valid folder.
+ */
+ public Pair<Boolean, File> installNewSdk(int apiLevel) {
+ mPackageFilter = createPlatformFilter(apiLevel, true /*forceRemote*/);
open();
return Pair.of(mResultCode, mResultPath);
}
@@ -176,21 +202,28 @@ public class AdtUpdateDialog extends SwtBaseDialog { @Override
protected void eventLoop() {
mPackageMananger.loadPackagesWithInstallTask(new IAutoInstallTask() {
+ public Package[] filterLoadedSource(SdkSource source, Package[] packages) {
+ for (Package pkg : packages) {
+ mPackageFilter.visit(pkg);
+ }
+ return packages;
+ }
+
public boolean acceptPackage(Package pkg) {
// Is this the package we want to install?
return mPackageFilter.accept(pkg);
}
- public void setResult(Package pkg, boolean success, File installPath) {
- // Capture the result from the installation.
- mResultCode = Boolean.valueOf(success);
- mResultPath = installPath;
- }
+ public void setResult(Package pkg, boolean success, File installPath) {
+ // Capture the result from the installation.
+ mResultCode = Boolean.valueOf(success);
+ mResultPath = installPath;
+ }
- public void taskCompleted() {
- // We can close that window now.
- close();
- }
+ public void taskCompleted() {
+ // We can close that window now.
+ close();
+ }
});
super.eventLoop();
@@ -224,41 +257,75 @@ public class AdtUpdateDialog extends SwtBaseDialog { // ----
private static abstract class PackageFilter {
+ /** Visit a new package definition, in case we need to adjust the filter dynamically. */
+ abstract void visit(Package pkg);
+ /** Checks whether this is the package we've been looking for. */
abstract boolean accept(Package pkg);
+ }
+
+ public static PackageFilter createExtraFilter(
+ final String vendor,
+ final String path) {
+ return new PackageFilter() {
+ String mVendor = vendor;
+ String mPath = path;
+
+ @Override
+ boolean accept(Package pkg) {
+ if (pkg instanceof ExtraPackage) {
+ ExtraPackage ep = (ExtraPackage) pkg;
+ return ep.getVendor().equals(mVendor) &&
+ ep.getPath().equals(mPath);
+ }
+ return false;
+ }
- public static PackageFilter createExtraFilter(
- final String vendor,
- final String path) {
- return new PackageFilter() {
- String mVendor = vendor;
- String mPath = path;
- @Override
- boolean accept(Package pkg) {
- if (pkg instanceof ExtraPackage) {
- ExtraPackage ep = (ExtraPackage) pkg;
- return ep.getVendor().equals(mVendor) &&
- ep.getPath().equals(mPath);
+ @Override
+ void visit(Package pkg) {
+ // nop
+ }
+ };
+ }
+
+ public static PackageFilter createPlatformFilter(
+ final int apiLevel,
+ final boolean forceRemote) {
+ return new PackageFilter() {
+ int mApiLevel = apiLevel;
+ boolean mFindMaxApi = apiLevel == USE_MAX_REMOTE_API_LEVEL;
+
+ @Override
+ boolean accept(Package pkg) {
+ if (pkg instanceof PlatformPackage) {
+ if (forceRemote && pkg.isLocal()) {
+ // We only want remote packages, to force a fresh install.
+ return false;
}
- return false;
+ PlatformPackage pp = (PlatformPackage) pkg;
+ AndroidVersion v = pp.getVersion();
+ return !v.isPreview() && v.getApiLevel() == mApiLevel;
}
- };
- }
+ return false;
+ }
- public static PackageFilter createPlatformFilter(final int apiLevel) {
- return new PackageFilter() {
- int mApiLevel = apiLevel;
- @Override
- boolean accept(Package pkg) {
- if (pkg instanceof PlatformPackage) {
- PlatformPackage pp = (PlatformPackage) pkg;
- AndroidVersion v = pp.getVersion();
- return !v.isPreview() && v.getApiLevel() == mApiLevel;
+ @Override
+ void visit(Package pkg) {
+ // Try to find the max API in all remote packages
+ if (mFindMaxApi &&
+ pkg instanceof PlatformPackage &&
+ !pkg.isLocal()) {
+ PlatformPackage pp = (PlatformPackage) pkg;
+ AndroidVersion v = pp.getVersion();
+ if (!v.isPreview()) {
+ int api = v.getApiLevel();
+ if (api > mApiLevel) {
+ mApiLevel = api;
+ }
}
- return false;
}
- };
- }
+ }
+ };
}
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 9996600..3c7d437 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 @@ -86,6 +86,17 @@ class PackageLoader { */ public interface IAutoInstallTask { /** + * Invoked by the loader once a source has been loaded and its packages + * definitions are known. The method should return the {@code packages} + * array and can modify it if necessary. + * The loader will call {@link #acceptPackage(Package)} on all the packages returned. + * + * @param source The source of the packages. Null for the locally installed packages. + * @param packages The packages found in the source. + */ + public Package[] filterLoadedSource(SdkSource source, Package[] packages); + + /** * Called by the install task for every package available (new ones, updates as well * as existing ones that don't have a potential update.) * The method should return true if this is the package that should be installed, @@ -221,6 +232,12 @@ class PackageLoader { loadPackages(new ISourceLoadedCallback() { public boolean onUpdateSource(SdkSource source, Package[] packages) { + packages = installTask.filterLoadedSource(source, packages); + if (packages == null || packages.length == 0) { + // Tell loadPackages() to process the next source. + return true; + } + for (Package pkg : packages) { if (pkg.isLocal()) { // This is a local (aka installed) package |