diff options
author | Raphael Moll <ralf@android.com> | 2011-07-29 11:26:16 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-07-29 11:26:16 -0700 |
commit | 458bdd62753818cbfe54b640d0ba1493c01405b9 (patch) | |
tree | 2a07c23971daf781b0dd72e113a364b4800d895d | |
parent | 88088e5c3068ddb8c735f4f6822370f9c9bc15a6 (diff) | |
parent | e373ce4021c83e10151b75c146cba7521bd66cfe (diff) | |
download | sdk-458bdd62753818cbfe54b640d0ba1493c01405b9.zip sdk-458bdd62753818cbfe54b640d0ba1493c01405b9.tar.gz sdk-458bdd62753818cbfe54b640d0ba1493c01405b9.tar.bz2 |
Merge "SDK Manager2: Revamp progress bar handling."
17 files changed, 448 insertions, 142 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 ac8dd09..589b07c 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 @@ -463,7 +463,10 @@ public class ExtraPackage extends MinToolsPackage // First find if this extra is already installed. If so, reuse the same directory.
LocalSdkParser localParser = new LocalSdkParser();
- Package[] pkgs = localParser.parseSdk(osSdkRoot, sdkManager, new NullSdkLog());
+ Package[] pkgs = localParser.parseSdk(
+ osSdkRoot,
+ sdkManager,
+ new NullTaskMonitor(new NullSdkLog()));
for (Package pkg : pkgs) {
if (sameItemAs(pkg) && pkg instanceof ExtraPackage) {
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java index 540825c..fb59b42 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java @@ -21,5 +21,25 @@ package com.android.sdklib.internal.repository; */
public interface ITaskFactory {
+ /**
+ * Starts a new task with a new {@link ITaskMonitor}.
+ *
+ * @param title The title of the task, displayed in the monitor if any.
+ * @param task The task to run.
+ */
public abstract void start(String title, ITask task);
+
+ /**
+ * Starts a new task contributing to an already existing {@link ITaskMonitor}.
+ * <p/>
+ * To use this properly, you should use {@link ITaskMonitor#createSubMonitor(int)}
+ * and give the sub-monitor to the new task with the number of work units you want
+ * it to fill. The {@link #start} method will make sure to <em>fill</em> the progress
+ * when the task is completed, in case the actual task did not.
+ *
+ * @param title The title of the task, displayed in the monitor if any.
+ * @param parentMonitor The parent monitor. Can be null.
+ * @param task The task to run and have it display on the monitor.
+ */
+ public abstract void start(String title, ITaskMonitor parentMonitor, ITask task);
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java index 40f1ddb..313f36e 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java @@ -16,6 +16,8 @@ package com.android.sdklib.internal.repository;
+import com.android.sdklib.ISdkLog;
+
/**
* A monitor interface for a {@link ITask}.
@@ -42,8 +44,10 @@ package com.android.sdklib.internal.repository; * provided: error, normal and verbose. An UI may hide the log till an error is
* logged and/or might hide the verbose text unless a flag is checked by the user.
* This is set using {@link #log}, {@link #logError} and {@link #logVerbose}.
+ * <p/>
+ * A monitor is also an {@link ISdkLog} implementation.
*/
-public interface ITaskMonitor {
+public interface ITaskMonitor extends ISdkLog {
/**
* Sets the description in the current task dialog.
@@ -82,6 +86,12 @@ public interface ITaskMonitor { public void setProgressMax(int max);
/**
+ * Returns the max valie of the progress bar, as last set by {@link #setProgressMax(int)}.
+ * Returns 0 if the max has never been set yet.
+ */
+ public int getProgressMax();
+
+ /**
* Increments the current value of the progress bar.
* This method can be invoked from a non-UI thread.
*
@@ -121,5 +131,4 @@ public interface ITaskMonitor { * @return true if YES was clicked.
*/
public boolean displayPrompt(final String title, final String message);
-
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java index a8faeda..0347dd5 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java @@ -46,8 +46,7 @@ public class LocalSdkParser { }
/**
- * Returns the packages found by the last call to
- * {@link #parseSdk(String, SdkManager, ISdkLog)}.
+ * Returns the packages found by the last call to {@link #parseSdk}.
* <p/>
* This returns initially returns null.
* Once the parseSdk() method has been called, this returns a possibly empty but non-null array.
@@ -58,7 +57,7 @@ public class LocalSdkParser { /**
* Clear the internal packages list. After this call, {@link #getPackages()} will return
- * null till {@link #parseSdk(String, SdkManager, ISdkLog)} is called.
+ * null till {@link #parseSdk} is called.
*/
public void clearPackages() {
mPackages = null;
@@ -72,33 +71,41 @@ public class LocalSdkParser { *
* @param osSdkRoot The path to the SDK folder.
* @param sdkManager An existing SDK manager to list current platforms and addons.
- * @param log An SDK logger object. Cannot be null.
+ * @param monitor A monitor to track progress. Cannot be null.
* @return The packages found. Can be retrieved later using {@link #getPackages()}.
*/
- public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager, ISdkLog log) {
+ public Package[] parseSdk(
+ String osSdkRoot,
+ SdkManager sdkManager,
+ ITaskMonitor monitor) {
ArrayList<Package> packages = new ArrayList<Package>();
HashSet<File> visited = new HashSet<File>();
+ monitor.setProgressMax(8);
+
File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);
- Package pkg = scanDoc(dir, log);
+ Package pkg = scanDoc(dir, monitor);
if (pkg != null) {
packages.add(pkg);
visited.add(dir);
}
+ monitor.incProgress(1);
dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);
- pkg = scanTools(dir, log);
+ pkg = scanTools(dir, monitor);
if (pkg != null) {
packages.add(pkg);
visited.add(dir);
}
+ monitor.incProgress(1);
dir = new File(osSdkRoot, SdkConstants.FD_PLATFORM_TOOLS);
- pkg = scanPlatformTools(dir, log);
+ pkg = scanPlatformTools(dir, monitor);
if (pkg != null) {
packages.add(pkg);
visited.add(dir);
}
+ monitor.incProgress(1);
File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES);
@@ -130,7 +137,7 @@ public class LocalSdkParser { pkg = AddonPackage.create(target, props);
}
} catch (Exception e) {
- log.error(e, null);
+ monitor.error(e, null);
}
if (pkg != null) {
@@ -138,11 +145,16 @@ public class LocalSdkParser { visited.add(new File(target.getLocation()));
}
}
-
- scanMissingAddons(sdkManager, visited, packages, log);
- scanMissingSamples(osSdkRoot, visited, packages, log);
- scanExtras(osSdkRoot, visited, packages, log);
- scanExtrasDirectory(osSdkRoot, visited, packages, log);
+ monitor.incProgress(1);
+
+ scanMissingAddons(sdkManager, visited, packages, monitor);
+ monitor.incProgress(1);
+ scanMissingSamples(osSdkRoot, visited, packages, monitor);
+ monitor.incProgress(1);
+ scanExtras(osSdkRoot, visited, packages, monitor);
+ monitor.incProgress(1);
+ scanExtrasDirectory(osSdkRoot, visited, packages, monitor);
+ monitor.incProgress(1);
Collections.sort(packages);
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java new file mode 100755 index 0000000..afe291f --- /dev/null +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java @@ -0,0 +1,108 @@ +/*
+ * Copyright (C) 2011 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;
+
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.NullSdkLog;
+
+
+/**
+ * A no-op implementation of the {@link ITaskMonitor} interface.
+ * <p/>
+ * This can be passed to methods that require a monitor when the caller doesn't
+ * have any UI to update or means to report tracked progress.
+ * A custom {@link ISdkLog} is used. Clients could use {@link NullSdkLog} if
+ * they really don't care about the logging either.
+ */
+public class NullTaskMonitor implements ITaskMonitor {
+
+ private final ISdkLog mLog;
+
+ /**
+ * Creates a no-op {@link ITaskMonitor} that defers logging to the specified
+ * logger.
+ * <p/>
+ * This can be passed to methods that require a monitor when the caller doesn't
+ * have any UI to update or means to report tracked progress.
+ *
+ * @param log An {@link ISdkLog}. Must not be null. Consider using {@link NullSdkLog}.
+ */
+ public NullTaskMonitor(ISdkLog log) {
+ mLog = log;
+ }
+
+ public void setDescription(String format, Object...args) {
+ // pass
+ }
+
+ public void log(String format, Object...args) {
+ mLog.printf(format, args);
+ }
+
+ public void logError(String format, Object...args) {
+ mLog.error(null /*throwable*/, format, args);
+ }
+
+ public void logVerbose(String format, Object...args) {
+ mLog.printf(format, args);
+ }
+
+ public void setProgressMax(int max) {
+ // pass
+ }
+
+ public int getProgressMax() {
+ return 0;
+ }
+
+ public void incProgress(int delta) {
+ // pass
+ }
+
+ /** Always return 1. */
+ public int getProgress() {
+ return 1;
+ }
+
+ /** Always return false. */
+ public boolean isCancelRequested() {
+ return false;
+ }
+
+ public ITaskMonitor createSubMonitor(int tickCount) {
+ return this;
+ }
+
+ /** Always return false. */
+ public boolean displayPrompt(final String title, final String message) {
+ return false;
+ }
+
+ // --- ISdkLog ---
+
+ public void error(Throwable t, String errorFormat, Object... args) {
+ mLog.error(t, errorFormat, args);
+ }
+
+ public void warning(String warningFormat, Object... args) {
+ mLog.warning(warningFormat, args);
+ }
+
+ public void printf(String msgFormat, Object... args) {
+ mLog.printf(msgFormat, args);
+ }
+}
diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java index 3b7e608..c006707 100755 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java +++ b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java @@ -60,6 +60,10 @@ public class MockMonitor implements ITaskMonitor { public void setProgressMax(int max) {
}
+ public int getProgressMax() {
+ return 0;
+ }
+
public void setDescription(String format, Object... args) {
mCapturedDescriptions += String.format(format, args) + "\n"; //$NON-NLS-1$
}
@@ -82,4 +86,13 @@ public class MockMonitor implements ITaskMonitor { public ITaskMonitor createSubMonitor(int tickCount) {
return null;
}
+
+ public void error(Throwable t, String errorFormat, Object... args) {
+ }
+
+ public void printf(String msgFormat, Object... args) {
+ }
+
+ public void warning(String warningFormat, Object... args) {
+ }
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java index f09e144..d2ff1c4 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java @@ -17,6 +17,7 @@ package com.android.sdkuilib.internal.repository;
import com.android.sdklib.internal.repository.IDescription;
+import com.android.sdklib.internal.repository.NullTaskMonitor;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.SdkSource;
import com.android.sdkuilib.internal.repository.icons.ImageFactory;
@@ -93,7 +94,8 @@ class LocalSdkAdapter { */
public Object[] getElements(Object inputElement) {
if (inputElement == LocalSdkAdapter.this) {
- Package[] packages = mUpdaterData.getInstalledPackages();
+ Package[] packages = mUpdaterData.getInstalledPackages(
+ new NullTaskMonitor(mUpdaterData.getSdkLog()));
if (packages != null) {
return packages;
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackageLoader.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackageLoader.java index 925f088..3f329cf 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackageLoader.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/PackageLoader.java @@ -20,6 +20,7 @@ import com.android.sdklib.internal.repository.Archive; import com.android.sdklib.internal.repository.IPackageVersion; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskMonitor; +import com.android.sdklib.internal.repository.NullTaskMonitor; import com.android.sdklib.internal.repository.Package; import com.android.sdklib.internal.repository.SdkSource; import com.android.sdklib.internal.repository.Package.UpdateInfo; @@ -137,48 +138,50 @@ class PackageLoader { return; } - // get local packages and offer them to the callback - Package[] localPkgs = mUpdaterData.getInstalledPackages(); - if (localPkgs == null) { - localPkgs = new Package[0]; - } - if (!sourceLoadedCallback.onUpdateSource(null, localPkgs)) { - return; - } - - final int[] numPackages = { localPkgs == null ? 0 : localPkgs.length }; - - // get remote packages - final boolean forceHttp = mUpdaterData.getSettingsController().getForceHttp(); - mUpdaterData.loadRemoteAddonsList(); mUpdaterData.getTaskFactory().start("Loading Sources", new ITask() { public void run(ITaskMonitor monitor) { + monitor.setProgressMax(10); + + // get local packages and offer them to the callback + Package[] localPkgs = + mUpdaterData.getInstalledPackages(monitor.createSubMonitor(1)); + if (localPkgs == null) { + localPkgs = new Package[0]; + } + if (!sourceLoadedCallback.onUpdateSource(null, localPkgs)) { + return; + } + + // get remote packages + boolean forceHttp = mUpdaterData.getSettingsController().getForceHttp(); + mUpdaterData.loadRemoteAddonsList(monitor.createSubMonitor(1)); + SdkSource[] sources = mUpdaterData.getSources().getAllSources(); try { - for (SdkSource source : sources) { - Package[] pkgs = source.getPackages(); - if (pkgs == null) { - source.load(monitor, forceHttp); - pkgs = source.getPackages(); - } - if (pkgs == null) { - continue; - } - - numPackages[0] += pkgs.length; + if (sources != null && sources.length > 0) { + ITaskMonitor subMonitor = monitor.createSubMonitor(8); + subMonitor.setProgressMax(sources.length); + for (SdkSource source : sources) { + Package[] pkgs = source.getPackages(); + if (pkgs == null) { + source.load(subMonitor.createSubMonitor(1), forceHttp); + pkgs = source.getPackages(); + } + if (pkgs == null) { + continue; + } - // Notify the callback a new source has finished loading. - // If the callback requests so, stop right away. - if (!sourceLoadedCallback.onUpdateSource(source, pkgs)) { - return; + // Notify the callback a new source has finished loading. + // If the callback requests so, stop right away. + if (!sourceLoadedCallback.onUpdateSource(source, pkgs)) { + return; + } } } } catch(Exception e) { monitor.logError("Loading source failed: %1$s", e.toString()); } finally { - monitor.setDescription("Done loading %1$d packages from %2$d sources", - numPackages[0], - sources.length); + monitor.setDescription("Done loading packages."); } } }); @@ -299,7 +302,8 @@ class PackageLoader { // The local package list has changed, make sure to refresh it mUpdaterData.getLocalSdkParser().clearPackages(); - final Package[] localPkgs = mUpdaterData.getInstalledPackages(); + final Package[] localPkgs = mUpdaterData.getInstalledPackages( + new NullTaskMonitor(mUpdaterData.getSdkLog())); // Try to locate the installed package in the new package list for (Package localPkg : localPkgs) { 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 0d6dd7a..6e3d74e 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 @@ -650,15 +650,17 @@ public class PackagesPage extends UpdaterPage * is added or the list is reloaded. */ private void expandInitial(Object elem) { - mTreeViewer.setExpandedState(elem, true); - for (Object pkg : - ((ITreeContentProvider) mTreeViewer.getContentProvider()).getChildren(elem)) { - if (pkg instanceof PkgCategory) { - PkgCategory cat = (PkgCategory) pkg; - for (PkgItem item : cat.getItems()) { - if (item.getState() == PkgState.INSTALLED) { - expandInitial(pkg); - break; + if (mTreeViewer != null && !mTreeViewer.getTree().isDisposed()) { + mTreeViewer.setExpandedState(elem, true); + for (Object pkg : + ((ITreeContentProvider) mTreeViewer.getContentProvider()).getChildren(elem)) { + if (pkg instanceof PkgCategory) { + PkgCategory cat = (PkgCategory) pkg; + for (PkgItem item : cat.getItems()) { + if (item.getState() == PkgState.INSTALLED) { + expandInitial(pkg); + break; + } } } } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java index 54bc068..f5bc11d 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java @@ -20,6 +20,7 @@ import com.android.sdklib.internal.repository.Archive; import com.android.sdklib.internal.repository.IDescription;
import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskMonitor;
+import com.android.sdklib.internal.repository.NullTaskMonitor;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.SdkSource;
import com.android.sdklib.internal.repository.SdkSourceCategory;
@@ -172,7 +173,8 @@ public class RepoSourcesAdapter { } else if (parentElement instanceof SdkSourceCategory) {
SdkSourceCategory cat = (SdkSourceCategory) parentElement;
if (cat == SdkSourceCategory.ADDONS_3RD_PARTY) {
- mUpdaterData.loadRemoteAddonsList();
+ mUpdaterData.loadRemoteAddonsList(
+ new NullTaskMonitor(mUpdaterData.getSdkLog()));
}
SdkSource[] sources = mUpdaterData.getSources().getSources(cat);
@@ -314,7 +316,8 @@ public class RepoSourcesAdapter { */
private Package[] filterUpdateOnlyPackages(Package[] remotePackages) {
// get the installed packages
- Package[] installedPackages = mUpdaterData.getInstalledPackages();
+ Package[] installedPackages = mUpdaterData.getInstalledPackages(
+ new NullTaskMonitor(mUpdaterData.getSdkLog()));
// we'll populate this package list with either upgrades or new packages.
ArrayList<Package> filteredList = new ArrayList<Package>();
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java index 5a718c5..ef4864b 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java @@ -21,6 +21,7 @@ import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskFactory; import com.android.sdklib.internal.repository.ITaskMonitor; +import com.android.sdklib.internal.repository.NullTaskMonitor; import com.android.sdklib.repository.SdkRepoConstants; import java.util.ArrayList; @@ -87,7 +88,10 @@ public class SdkUpdaterNoWindow { // Setup the default sources including the getenv overrides. mUpdaterData.setupDefaultSources(); - mUpdaterData.getLocalSdkParser().parseSdk(osSdkRoot, sdkManager, sdkLog); + mUpdaterData.getLocalSdkParser().parseSdk( + osSdkRoot, + sdkManager, + new NullTaskMonitor(sdkLog)); } /** @@ -143,11 +147,35 @@ public class SdkUpdaterNoWindow { } /** - * A custom implementation of {@link ITaskFactory} that provides {@link ConsoleTask} objects. + * A custom implementation of {@link ITaskFactory} that + * provides {@link ConsoleTaskMonitor} objects. */ private class ConsoleTaskFactory implements ITaskFactory { public void start(String title, ITask task) { - new ConsoleTask(title, task); + start(title, null /*parentMonitor*/, task); + } + + public void start(String title, ITaskMonitor parentMonitor, ITask task) { + if (parentMonitor == null) { + task.run(new ConsoleTaskMonitor(title, task)); + } else { + // Use all the reminder of the parent monitor. + if (parentMonitor.getProgressMax() == 0) { + parentMonitor.setProgressMax(1); + } + + ITaskMonitor sub = parentMonitor.createSubMonitor( + parentMonitor.getProgressMax() - parentMonitor.getProgress()); + try { + task.run(sub); + } finally { + int delta = + sub.getProgressMax() - sub.getProgress(); + if (delta > 0) { + sub.incProgress(delta); + } + } + } } } @@ -155,7 +183,7 @@ public class SdkUpdaterNoWindow { * A custom implementation of {@link ITaskMonitor} that defers all output to the * super {@link SdkUpdaterNoWindow#mSdkLog}. */ - private class ConsoleTask implements ITaskMonitor { + private class ConsoleTaskMonitor implements ITaskMonitor { private static final double MAX_COUNT = 10000.0; private double mIncCoef = 0; @@ -164,11 +192,10 @@ public class SdkUpdaterNoWindow { private String mLastProgressBase = null; /** - * Creates a new {@link ConsoleTask} with the given title. + * Creates a new {@link ConsoleTaskMonitor} with the given title. */ - public ConsoleTask(String title, ITask task) { + public ConsoleTaskMonitor(String title, ITask task) { mSdkLog.printf("%s:\n", title); - task.run(this); } /** @@ -222,6 +249,20 @@ public class SdkUpdaterNoWindow { // The ConsoleTask does not display verbose log messages. } + // --- ISdkLog --- + + public void error(Throwable t, String errorFormat, Object... args) { + mSdkLog.error(t, errorFormat, args); + } + + public void warning(String warningFormat, Object... args) { + mSdkLog.warning(warningFormat, args); + } + + public void printf(String msgFormat, Object... args) { + mSdkLog.printf(msgFormat, args); + } + /** * Sets the max value of the progress bar. * @@ -238,6 +279,10 @@ public class SdkUpdaterNoWindow { assert mIncCoef > 0; } + public int getProgressMax() { + return mIncCoef > 0 ? (int) (MAX_COUNT / mIncCoef) : 0; + } + /** * Increments the current value of the progress bar. */ @@ -307,7 +352,7 @@ public class SdkUpdaterNoWindow { private static class ConsoleSubTaskMonitor implements IConsoleSubTaskMonitor { - private final ConsoleTask mRoot; + private final ConsoleTaskMonitor mRoot; private final IConsoleSubTaskMonitor mParent; private final double mStart; private final double mSpan; @@ -323,7 +368,7 @@ public class SdkUpdaterNoWindow { * @param start The start value in the root's coordinates * @param span The span value in the root's coordinates */ - public ConsoleSubTaskMonitor(ConsoleTask root, + public ConsoleSubTaskMonitor(ConsoleTaskMonitor root, IConsoleSubTaskMonitor parent, double start, double span) { @@ -360,6 +405,10 @@ public class SdkUpdaterNoWindow { assert mSubCoef > 0; } + public int getProgressMax() { + return mSubCoef > 0 ? (int) (mSpan / mSubCoef) : 0; + } + public int getProgress() { assert mSubCoef > 0; return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0; @@ -392,5 +441,19 @@ public class SdkUpdaterNoWindow { mSubValue, tickCount * mSubCoef); } + + // --- ISdkLog --- + + public void error(Throwable t, String errorFormat, Object... args) { + mRoot.error(t, errorFormat, args); + } + + public void warning(String warningFormat, Object... args) { + mRoot.warning(warningFormat, args); + } + + public void printf(String msgFormat, Object... args) { + mRoot.printf(msgFormat, args); + } } } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index 27099da..208c0cd 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -32,6 +32,7 @@ import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskFactory;
import com.android.sdklib.internal.repository.ITaskMonitor;
import com.android.sdklib.internal.repository.LocalSdkParser;
+import com.android.sdklib.internal.repository.NullTaskMonitor;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.PlatformToolPackage;
import com.android.sdklib.internal.repository.SdkAddonSource;
@@ -367,14 +368,14 @@ class UpdaterData implements IUpdaterData { * The package list is cached in the {@link LocalSdkParser} and will be reset when
* {@link #reloadSdk()} is invoked.
*/
- public Package[] getInstalledPackages() {
+ public Package[] getInstalledPackages(ITaskMonitor monitor) {
LocalSdkParser parser = getLocalSdkParser();
Package[] packages = parser.getPackages();
if (packages == null) {
// load on demand the first time
- packages = parser.parseSdk(getOsSdkRoot(), getSdkManager(), getSdkLog());
+ packages = parser.parseSdk(getOsSdkRoot(), getSdkManager(), monitor);
}
return packages;
@@ -404,7 +405,7 @@ class UpdaterData implements IUpdaterData { public void run(ITaskMonitor monitor) {
final int progressPerArchive = 2 * ArchiveInstaller.NUM_MONITOR_INC;
- monitor.setProgressMax(archives.size() * progressPerArchive);
+ monitor.setProgressMax(1 + archives.size() * progressPerArchive);
monitor.setDescription("Preparing to install archives");
boolean installedAddon = false;
@@ -414,7 +415,7 @@ class UpdaterData implements IUpdaterData { // Mark all current local archives as already installed.
HashSet<Archive> installedArchives = new HashSet<Archive>();
- for (Package p : getInstalledPackages()) {
+ for (Package p : getInstalledPackages(monitor.createSubMonitor(1))) {
for (Archive a : p.getArchives()) {
installedArchives.add(a);
}
@@ -695,7 +696,7 @@ class UpdaterData implements IUpdaterData { includeObsoletes);
if (selectedArchives == null) {
- loadRemoteAddonsList();
+ loadRemoteAddonsList(new NullTaskMonitor(getSdkLog()));
ul.addNewPlatforms(
archives,
getSources(),
@@ -708,7 +709,8 @@ class UpdaterData implements IUpdaterData { Collections.sort(archives);
- SdkUpdaterChooserDialog dialog = new SdkUpdaterChooserDialog(getWindowShell(), this, archives);
+ SdkUpdaterChooserDialog dialog =
+ new SdkUpdaterChooserDialog(getWindowShell(), this, archives);
dialog.open();
ArrayList<ArchiveInfo> result = dialog.getResult();
@@ -729,7 +731,7 @@ class UpdaterData implements IUpdaterData { */
private List<ArchiveInfo> getRemoteArchives_NoGUI(boolean includeObsoletes) {
refreshSources(true);
- loadRemoteAddonsList();
+ loadRemoteAddonsList(new NullTaskMonitor(getSdkLog()));
SdkUpdaterLogic ul = new SdkUpdaterLogic(this);
List<ArchiveInfo> archives = ul.computeUpdates(
@@ -970,15 +972,15 @@ class UpdaterData implements IUpdaterData { /**
* Loads the remote add-ons list.
*/
- public void loadRemoteAddonsList() {
+ public void loadRemoteAddonsList(ITaskMonitor monitor) {
if (mStateFetchRemoteAddonsList != 0) {
return;
}
- mTaskFactory.start("Load Add-ons List", new ITask() {
- public void run(ITaskMonitor monitor) {
- loadRemoteAddonsListInTask(monitor);
+ mTaskFactory.start("Load Add-ons List", monitor, new ITask() {
+ public void run(ITaskMonitor subMonitor) {
+ loadRemoteAddonsListInTask(subMonitor);
}
});
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java index c90df26..d80e8c2 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java @@ -18,6 +18,7 @@ package com.android.sdkuilib.internal.tasks; import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskFactory;
+import com.android.sdklib.internal.repository.ITaskMonitor;
import org.eclipse.swt.widgets.Shell;
@@ -34,6 +35,31 @@ public final class ProgressTaskFactory implements ITaskFactory { }
public void start(String title, ITask task) {
- new ProgressTask(mShell, title, task);
+ start(title, null /*parentMonitor*/, task);
+ }
+
+ public void start(String title, ITaskMonitor parentMonitor, ITask task) {
+
+ if (parentMonitor == null) {
+ new ProgressTask(mShell, title, task);
+
+ } else {
+ // Use all the reminder of the parent monitor.
+ if (parentMonitor.getProgressMax() == 0) {
+ parentMonitor.setProgressMax(1);
+ }
+
+ ITaskMonitor sub = parentMonitor.createSubMonitor(
+ parentMonitor.getProgressMax() - parentMonitor.getProgress());
+ try {
+ task.run(sub);
+ } finally {
+ int delta =
+ sub.getProgressMax() - sub.getProgress();
+ if (delta > 0) {
+ sub.incProgress(delta);
+ }
+ }
+ }
}
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java index a7d4863..efa1a93 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java @@ -104,39 +104,63 @@ public final class ProgressView implements IProgressUiProvider { }
/**
- * Starts the task and block till it's either finished or cancelled.
+ * Starts the task and block till it's either finished or canceled.
+ * This can be called from a non-UI thread safely.
*/
- public void startTask(final String title, final ITask task) {
+ public void startTask(
+ final String title,
+ final ITaskMonitor parentMonitor,
+ final ITask task) {
if (task != null) {
try {
- mLabel.setText(title);
- mProgressBar.setSelection(0);
- mProgressBar.setEnabled(true);
- changeState(ProgressView.State.ACTIVE);
+ if (parentMonitor == null && !mProgressBar.isDisposed()) {
+ mLabel.setText(title);
+ mProgressBar.setSelection(0);
+ mProgressBar.setEnabled(true);
+ changeState(ProgressView.State.ACTIVE);
+ }
Runnable r = new Runnable() {
public void run() {
- task.run(new TaskMonitorImpl(ProgressView.this));
+ if (parentMonitor == null) {
+ task.run(new TaskMonitorImpl(ProgressView.this));
+
+ } else {
+ // Use all the reminder of the parent monitor.
+ if (parentMonitor.getProgressMax() == 0) {
+ parentMonitor.setProgressMax(1);
+ }
+ ITaskMonitor sub = parentMonitor.createSubMonitor(
+ parentMonitor.getProgressMax() - parentMonitor.getProgress());
+ try {
+ task.run(sub);
+ } finally {
+ int delta =
+ sub.getProgressMax() - sub.getProgress();
+ if (delta > 0) {
+ sub.incProgress(delta);
+ }
+ }
+ }
}
};
- Thread t = new Thread(r, title);
+ final Thread t = new Thread(r, title);
t.start();
- // Process the app's event loop whilst we wait for the thread to finish
- Display display = mProgressBar.getDisplay();
- while (!mProgressBar.isDisposed() && t.isAlive()) {
- if (!display.readAndDispatch()) {
- display.sleep();
+ if (parentMonitor == null && !mProgressBar.isDisposed()) {
+ // Process the app's event loop whilst we wait for the thread to finish
+ while (!mProgressBar.isDisposed() && t.isAlive()) {
+ if (!mProgressBar.getDisplay().readAndDispatch()) {
+ mProgressBar.getDisplay().sleep();
+ }
}
}
-
-
} catch (Exception e) {
// TODO log
} finally {
- if (!mProgressBar.isDisposed()) {
+ if (parentMonitor == null && !mProgressBar.isDisposed()) {
changeState(ProgressView.State.IDLE);
mProgressBar.setSelection(0);
mProgressBar.setEnabled(false);
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java index 448b478..db9fd7c 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java @@ -18,6 +18,7 @@ package com.android.sdkuilib.internal.tasks; import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskFactory;
+import com.android.sdklib.internal.repository.ITaskMonitor;
/**
* An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog
@@ -35,7 +36,11 @@ public final class ProgressViewFactory implements ITaskFactory { }
public void start(String title, ITask task) {
+ start(title, null /*monitor*/, task);
+ }
+
+ public void start(String title, ITaskMonitor parentMonitor, ITask task) {
assert mProgressView != null;
- mProgressView.startTask(title, task);
+ mProgressView.startTask(title, parentMonitor, task);
}
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java index c95db47..547bc37 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java @@ -108,6 +108,10 @@ class TaskMonitorImpl implements ITaskMonitor { assert mIncCoef > 0;
}
+ public int getProgressMax() {
+ return mIncCoef > 0 ? (int) (MAX_COUNT / mIncCoef) : 0;
+ }
+
/**
* Increments the current value of the progress bar.
*
@@ -167,6 +171,28 @@ class TaskMonitorImpl implements ITaskMonitor { return new SubTaskMonitor(this, null, mValue, tickCount * mIncCoef);
}
+ // ----- ISdkLog interface ----
+
+ public void error(Throwable throwable, String errorFormat, Object... arg) {
+ if (errorFormat != null) {
+ logError("Error: " + errorFormat, arg);
+ }
+
+ if (throwable != null) {
+ logError("%s", throwable.getMessage()); //$NON-NLS-1$
+ }
+ }
+
+ public void warning(String warningFormat, Object... arg) {
+ log("Warning: " + warningFormat, arg);
+ }
+
+ public void printf(String msgFormat, Object... arg) {
+ log(msgFormat, arg);
+ }
+
+ // ----- Sub Monitor -----
+
private static class SubTaskMonitor implements ISubTaskMonitor {
private final TaskMonitorImpl mRoot;
@@ -222,6 +248,10 @@ class TaskMonitorImpl implements ITaskMonitor { assert mSubCoef > 0;
}
+ public int getProgressMax() {
+ return mSubCoef > 0 ? (int) (mSpan / mSubCoef) : 0;
+ }
+
public int getProgress() {
assert mSubCoef > 0;
return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0;
@@ -254,6 +284,19 @@ class TaskMonitorImpl implements ITaskMonitor { mSubValue,
tickCount * mSubCoef);
}
- }
+ // ----- ISdkLog interface ----
+
+ public void error(Throwable throwable, String errorFormat, Object... arg) {
+ mRoot.error(throwable, errorFormat, arg);
+ }
+
+ public void warning(String warningFormat, Object... arg) {
+ mRoot.warning(warningFormat, arg);
+ }
+
+ public void printf(String msgFormat, Object... arg) {
+ mRoot.printf(msgFormat, arg);
+ }
+ }
}
diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java index 20cd48a..b562e35 100755 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java +++ b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java @@ -16,6 +16,7 @@ package com.android.sdkuilib.internal.repository; +import com.android.sdklib.NullSdkLog; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.repository.Archive; import com.android.sdklib.internal.repository.ArchiveInstaller; @@ -23,6 +24,7 @@ import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskFactory; import com.android.sdklib.internal.repository.ITaskMonitor; import com.android.sdklib.internal.repository.MockEmptySdkManager; +import com.android.sdklib.internal.repository.NullTaskMonitor; import com.android.sdklib.mock.MockLog; import com.android.sdkuilib.internal.repository.icons.ImageFactory; @@ -85,56 +87,21 @@ class MockUpdaterData extends UpdaterData { private class MockTaskFactory implements ITaskFactory { public void start(String title, ITask task) { + start(title, null /*parentMonitor*/, task); + } + + public void start(String title, ITaskMonitor parentMonitor, ITask task) { new MockTask(task); } } //------------ - private static class MockTask implements ITaskMonitor { + private static class MockTask extends NullTaskMonitor { public MockTask(ITask task) { + super(new NullSdkLog()); task.run(this); } - - public ITaskMonitor createSubMonitor(int tickCount) { - return this; - } - - public boolean displayPrompt(String title, String message) { - return false; - } - - public int getProgress() { - return 0; - } - - public void incProgress(int delta) { - // ignore - } - - public boolean isCancelRequested() { - return false; - } - - public void setDescription(String format, Object... args) { - // ignore - } - - public void setProgressMax(int max) { - // ignore - } - - public void log(String format, Object... args) { - // ignore - } - - public void logError(String format, Object... args) { - // ignore - } - - public void logVerbose(String format, Object... args) { - // ignore - } } //------------ |