aboutsummaryrefslogtreecommitdiffstats
path: root/sdkmanager
diff options
context:
space:
mode:
authorRaphael <raphael@google.com>2009-06-10 18:33:45 -0700
committerRaphael <raphael@google.com>2009-06-10 18:33:45 -0700
commitadcb8628f2554897021655c579d55eaa6592cfd4 (patch)
tree8a93b50da4435b4a38ef1c77460f94d30710347b /sdkmanager
parent6842384c2fcfb5d868033a1cce4f54d1a65fd122 (diff)
downloadsdk-adcb8628f2554897021655c579d55eaa6592cfd4.zip
sdk-adcb8628f2554897021655c579d55eaa6592cfd4.tar.gz
sdk-adcb8628f2554897021655c579d55eaa6592cfd4.tar.bz2
SDK Updater: Revamp ITaskMonitor to be able to create sub monitors.
This allows us to nest tasks that share the same progress task dialog..
Diffstat (limited to 'sdkmanager')
-rwxr-xr-xsdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java7
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java15
-rwxr-xr-xsdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java64
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java6
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java135
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java4
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java12
-rwxr-xr-xsdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java59
8 files changed, 212 insertions, 90 deletions
diff --git a/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java b/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java
index 77e6a54..b07617f 100755
--- a/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java
+++ b/sdkmanager/app/src/com/android/sdkmanager/internal/repository/SettingsPage.java
@@ -21,6 +21,8 @@ import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdkuilib.internal.repository.ISettingsPage;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
@@ -28,16 +30,11 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
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 c8f7c06..85596ba 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
@@ -45,18 +45,27 @@ public interface ITaskMonitor {
/**
* Sets the max value of the progress bar.
* This method can be invoked from a non-UI thread.
+ *
+ * This method MUST be invoked once before using {@link #incProgress(int)} or
+ * {@link #getProgress()} or {@link #createSubMonitor(int)}. Callers are
+ * discouraged from using more than once -- implementations can either discard
+ * the next calls or behave incoherently.
*/
public void setProgressMax(int max);
/**
* Increments the current value of the progress bar.
* This method can be invoked from a non-UI thread.
+ *
+ * Callers MUST use setProgressMax before using this method.
*/
public void incProgress(int delta);
/**
* Returns the current value of the progress bar,
* between 0 and up to {@link #setProgressMax(int)} - 1.
+ *
+ * Callers MUST use setProgressMax before using this method.
*/
public int getProgress();
@@ -66,4 +75,10 @@ public interface ITaskMonitor {
* as possible.
*/
public boolean isCancelRequested();
+
+ /**
+ * Creates a sub-monitor that will use up to tickCount on the progress bar.
+ * tickCount must be 1 or more.
+ */
+ public ITaskMonitor createSubMonitor(int tickCount);
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
index d8ab806..c58a214 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
@@ -68,7 +68,7 @@ public class RepoSource implements IDescription {
}
/**
- * Returns the list of known packages found by the last call to {@link #load(ITaskFactory)}.
+ * Returns the list of known packages found by the last call to {@link #load(ITaskMonitor)}.
* This is null when the source hasn't been loaded yet.
*/
public Package[] getPackages() {
@@ -77,7 +77,7 @@ public class RepoSource implements IDescription {
/**
* Clear the internal packages list. After this call, {@link #getPackages()} will return
- * null till {@link #load(ITaskFactory)} is called.
+ * null till {@link #load(ITaskMonitor)} is called.
*/
public void clearPackages() {
mPackages = null;
@@ -94,47 +94,43 @@ public class RepoSource implements IDescription {
/**
* Tries to fetch the repository index for the given URL.
*/
- public void load(ITaskFactory taskFactory) {
+ public void load(ITaskMonitor monitor) {
- taskFactory.start("Init SDK Updater", new ITask() {
- public void run(ITaskMonitor monitor) {
- monitor.setProgressMax(4);
+ monitor.setProgressMax(4);
- setDefaultDescription();
+ setDefaultDescription();
- monitor.setDescription("Fetching %1$s", mUrl);
- monitor.incProgress(1);
+ monitor.setDescription("Fetching %1$s", mUrl);
+ monitor.incProgress(1);
- String xml = fetchUrl(mUrl, monitor);
+ String xml = fetchUrl(mUrl, monitor);
- if (xml == null) {
- mDescription += String.format("\nFailed to fetch URL %1$s", mUrl);
- return;
- }
+ if (xml == null) {
+ mDescription += String.format("\nFailed to fetch URL %1$s", mUrl);
+ return;
+ }
- monitor.setDescription("Validate XML");
- monitor.incProgress(1);
+ monitor.setDescription("Validate XML");
+ monitor.incProgress(1);
- if (!validateXml(xml, monitor)) {
- mDescription += String.format("\nFailed to validate XML at %1$s", mUrl);
- return;
- }
+ if (!validateXml(xml, monitor)) {
+ mDescription += String.format("\nFailed to validate XML at %1$s", mUrl);
+ return;
+ }
- monitor.setDescription("Parse XML");
- monitor.incProgress(1);
- parsePackages(xml, monitor);
- if (mPackages.length == 0) {
- mDescription += "\nNo packages found.";
- } else if (mPackages.length == 1) {
- mDescription += "\nOne package found.";
- } else {
- mDescription += String.format("\n%1$d packages found.", mPackages.length);
- }
+ monitor.setDescription("Parse XML");
+ monitor.incProgress(1);
+ parsePackages(xml, monitor);
+ if (mPackages.length == 0) {
+ mDescription += "\nNo packages found.";
+ } else if (mPackages.length == 1) {
+ mDescription += "\nOne package found.";
+ } else {
+ mDescription += String.format("\n%1$d packages found.", mPackages.length);
+ }
- // done
- monitor.incProgress(1);
- }
- });
+ // done
+ monitor.incProgress(1);
}
private void setDefaultDescription() {
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java
index a5cb86f..ca847c3 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java
@@ -320,15 +320,15 @@ final class ProgressDialog extends Dialog {
}
/**
- * Increments the current value of the progress bar.
+ * Sets the current value of the progress bar.
* This method can be invoked from a non-UI thread.
*/
- public void incProgress(final int delta) {
+ public void setProgress(final int value) {
if (!mDialogShell.isDisposed()) {
mDialogShell.getDisplay().syncExec(new Runnable() {
public void run() {
if (!mProgressBar.isDisposed()) {
- mProgressBar.setSelection(mProgressBar.getSelection() + delta);
+ mProgressBar.setSelection(value);
}
}
});
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java
index 709cce0..1ec7287 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java
@@ -28,8 +28,12 @@ import org.eclipse.swt.widgets.Shell;
*/
class ProgressTask implements ITaskMonitor {
- private ProgressDialog mDialog;
+ private static final double MAX_COUNT = 10000.0;
+
+ private final ProgressDialog mDialog;
private boolean mAutomaticallyCloseOnTaskCompletion = true;
+ private double mIncCoef = 0;
+ private double mValue = 0;
/**
@@ -46,29 +50,39 @@ class ProgressTask implements ITaskMonitor {
/**
* Sets the description in the current task dialog.
- * This method can be invoke from a non-UI thread.
+ * This method can be invoked from a non-UI thread.
*/
- public void setDescription(final String descriptionFormat, final Object...args) {
+ public void setDescription(String descriptionFormat, Object...args) {
mDialog.setDescription(descriptionFormat, args);
}
/**
* Sets the description in the current task dialog.
- * This method can be invoke from a non-UI thread.
+ * This method can be invoked from a non-UI thread.
*/
- public void setResult(final String resultFormat, final Object...args) {
+ public void setResult(String resultFormat, Object...args) {
mAutomaticallyCloseOnTaskCompletion = false;
mDialog.setResult(resultFormat, args);
}
/**
* Sets the max value of the progress bar.
- * This method can be invoke from a non-UI thread.
+ * This method can be invoked from a non-UI thread.
+ *
+ * Weird things will happen if setProgressMax is called multiple times
+ * *after* {@link #incProgress(int)}: we don't try to adjust it on the
+ * fly.
*
* @see ProgressBar#setMaximum(int)
*/
- public void setProgressMax(final int max) {
- mDialog.setProgressMax(max);
+ public void setProgressMax(int max) {
+ assert max > 0;
+ // Always set the dialog's progress max to 10k since it only handles
+ // integers and we want to have a better inner granularity. Instead
+ // we use the max to compute a coefficient for inc deltas.
+ mDialog.setProgressMax((int) MAX_COUNT);
+ mIncCoef = max > 0 ? MAX_COUNT / max : 0;
+ assert mIncCoef > 0;
}
/**
@@ -76,8 +90,15 @@ class ProgressTask implements ITaskMonitor {
*
* This method can be invoked from a non-UI thread.
*/
- public void incProgress(final int delta) {
- mDialog.incProgress(delta);
+ public void incProgress(int delta) {
+ assert mIncCoef > 0;
+ assert delta > 0;
+ internalIncProgress(delta * mIncCoef);
+ }
+
+ private void internalIncProgress(double realDelta) {
+ mValue += realDelta;
+ mDialog.setProgress((int)mValue);
}
/**
@@ -87,7 +108,8 @@ class ProgressTask implements ITaskMonitor {
* This method can be invoked from a non-UI thread.
*/
public int getProgress() {
- return mDialog.getProgress();
+ assert mIncCoef > 0;
+ return mIncCoef > 0 ? (int)(mDialog.getProgress() / mIncCoef) : 0;
}
/**
@@ -119,4 +141,95 @@ class ProgressTask implements ITaskMonitor {
}
return null;
}
+
+ /**
+ * Creates a sub-monitor that will use up to tickCount on the progress bar.
+ * tickCount must be 1 or more.
+ */
+ public ITaskMonitor createSubMonitor(int tickCount) {
+ assert mIncCoef > 0;
+ assert tickCount > 0;
+ return new SubTaskMonitor(this, null, mValue, tickCount * mIncCoef);
+ }
+
+ private interface ISubTaskMonitor extends ITaskMonitor {
+ public void subIncProgress(double realDelta);
+ }
+
+ private static class SubTaskMonitor implements ISubTaskMonitor {
+
+ private final ProgressTask mRoot;
+ private final ISubTaskMonitor mParent;
+ private final double mStart;
+ private final double mSpan;
+ private double mSubValue;
+ private double mSubCoef;
+
+ /**
+ * Creates a new sub task monitor which will work for the given range [start, start+span]
+ * in its parent.
+ *
+ * @param root The ProgressTask root
+ * @param parent The immediate parent. Can be the null or another sub task monitor.
+ * @param start The start value in the root's coordinates
+ * @param span The span value in the root's coordinates
+ */
+ public SubTaskMonitor(ProgressTask root,
+ ISubTaskMonitor parent,
+ double start,
+ double span) {
+ mRoot = root;
+ mParent = parent;
+ mStart = start;
+ mSpan = span;
+ mSubValue = start;
+ }
+
+ public boolean isCancelRequested() {
+ return mRoot.isCancelRequested();
+ }
+
+ public void setDescription(String descriptionFormat, Object... args) {
+ mRoot.setDescription(descriptionFormat, args);
+ }
+
+ public void setResult(String resultFormat, Object... args) {
+ mRoot.setResult(resultFormat, args);
+ }
+
+ public void setProgressMax(int max) {
+ assert max > 0;
+ mSubCoef = max > 0 ? mSpan / max : 0;
+ assert mSubCoef > 0;
+ }
+
+ public int getProgress() {
+ assert mSubCoef > 0;
+ return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0;
+ }
+
+ public void incProgress(int delta) {
+ assert mSubCoef > 0;
+ subIncProgress(delta * mSubCoef);
+ }
+
+ public void subIncProgress(double realDelta) {
+ mSubValue += realDelta;
+ if (mParent != null) {
+ mParent.subIncProgress(realDelta);
+ } else {
+ mRoot.internalIncProgress(realDelta);
+ }
+ }
+
+ public ITaskMonitor createSubMonitor(int tickCount) {
+ assert mSubCoef > 0;
+ assert tickCount > 0;
+ return new SubTaskMonitor(mRoot,
+ this,
+ mSubValue,
+ tickCount * mSubCoef);
+ }
+ }
+
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
index 6cc11a3..fb0c504 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
@@ -19,6 +19,8 @@ package com.android.sdkuilib.internal.repository;
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 org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
@@ -265,7 +267,7 @@ public class RemotePackagesPage extends Composite {
private void onRefreshSelected() {
if (mUpdaterWindow != null) {
- mUpdaterWindow.refreshSources(false /*forceFetching*/);
+ mUpdaterWindow.refreshSources(false /*forceFetching*/, null /*monitor*/);
}
}
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 3f020d1..a170775 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
@@ -18,6 +18,8 @@ package com.android.sdkuilib.internal.repository;
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.Package;
import com.android.sdklib.internal.repository.RepoSource;
import com.android.sdklib.internal.repository.RepoSources;
@@ -110,11 +112,17 @@ class RepoSourcesAdapter {
return ((RepoSourcesAdapter) parentElement).mRepoSources.getSources().toArray();
} else if (parentElement instanceof RepoSource) {
- RepoSource source = (RepoSource) parentElement;
+ final RepoSource source = (RepoSource) parentElement;
Package[] packages = source.getPackages();
if (packages == null) {
- source.load(mInput.mRepoSources.getTaskFactory());
+
+ mInput.mRepoSources.getTaskFactory().start("Loading Source", new ITask() {
+ public void run(ITaskMonitor monitor) {
+ source.load(monitor);
+ }
+ });
+
packages = source.getPackages();
}
if (packages != null) {
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
index cf679c7..3e98fae 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
@@ -407,17 +407,14 @@ public class UpdaterWindowImpl {
}
public void updateAll() {
- refreshSources(true);
-
- // TODO have refreshSources reuse the current progress task
-// mTaskFactory.start("Update Archives", new ITask() {
-// public void run(ITaskMonitor monitor) {
-// monitor.setProgressMax(3);
-//
-// monitor.setDescription("Refresh sources");
-// refreshSources(true);
-// }
-// });
+ mTaskFactory.start("Update Archives", new ITask() {
+ public void run(ITaskMonitor monitor) {
+ monitor.setProgressMax(3);
+
+ monitor.setDescription("Refresh sources");
+ refreshSources(true, monitor.createSubMonitor(1));
+ }
+ });
}
/**
@@ -426,32 +423,26 @@ public class UpdaterWindowImpl {
* @param forceFetching When true, load sources that haven't been loaded yet. When
* false, only refresh sources that have been loaded yet.
*/
- public void refreshSources(final boolean forceFetching) {
- ArrayList<RepoSource> sources = mUpdaterData.getSources().getSources();
- for (RepoSource source : sources) {
- if (forceFetching || source.getPackages() != null) {
- source.load(mTaskFactory);
+ public void refreshSources(final boolean forceFetching, ITaskMonitor monitor) {
+ ITask task = new ITask() {
+ public void run(ITaskMonitor monitor) {
+ ArrayList<RepoSource> sources = mUpdaterData.getSources().getSources();
+ monitor.setProgressMax(sources.size());
+ for (RepoSource source : sources) {
+ if (forceFetching || source.getPackages() != null) {
+ source.load(monitor.createSubMonitor(1));
+ }
+ monitor.incProgress(1);
+
+ }
}
+ };
+ if (monitor != null) {
+ task.run(monitor);
+ } else {
+ mTaskFactory.start("Refresh Sources", task);
}
-
- // TODO have source.load reuse the current progress task
-// mTaskFactory.start("Refresh sources", new ITask() {
-// public void run(ITaskMonitor monitor) {
-// ArrayList<RepoSource> sources = mUpdaterData.getSources().getSources();
-// monitor.setProgressMax(sources.size());
-//
-// for (RepoSource source : sources) {
-// if (forceFetching || source.getPackages() != null) {
-// monitor.setDescription(String.format("Refresh %1$s",
-// source.getShortDescription()));
-// source.load(mTaskFactory);
-// }
-// monitor.incProgress(1);
-// }
-// }
-// });
-
}
// End of hiding from SWT Designer