am 201f8316: Centralized the local data, and create new listener mechanism to access it.

Merge commit '201f83164f96036bcdc36a3c42082673a9fe429a'

* commit '201f83164f96036bcdc36a3c42082673a9fe429a':
  Centralized the local data, and create new listener mechanism to access it.
This commit is contained in:
Xavier Ducrohet
2009-06-12 08:25:07 -07:00
committed by The Android Open Source Project
9 changed files with 485 additions and 184 deletions

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -8,6 +8,7 @@ LOCAL_JAVA_RESOURCE_DIRS := .
LOCAL_JAVA_LIBRARIES := \
sdklib \
androidprefs \
swt \
org.eclipse.jface_3.4.2.M20090107-0800 \
org.eclipse.equinox.common_3.4.0.v20080421-2006 \

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) 2009 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.sdkuilib.internal.repository;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
import com.android.sdkuilib.internal.repository.UpdaterData.ISdkListener;
import com.android.sdkuilib.internal.widgets.AvdSelector;
import com.android.sdkuilib.internal.widgets.AvdSelector.SelectionMode;
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;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import java.util.HashSet;
public class AvdManagerPage extends Composite implements ISdkListener {
private Button mRefreshButton;
private AvdSelector mAvdSelector;
private final HashSet<String> mKnownAvdNames = new HashSet<String>();
private final UpdaterData mUpdaterData;
/**
* Create the composite.
* @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer.
*/
public AvdManagerPage(Composite parent, UpdaterData updaterData) {
super(parent, SWT.BORDER);
mUpdaterData = updaterData != null ? updaterData : new UpdaterData();
mUpdaterData.addListeners(this);
createContents(this);
postCreate(); //$hide$
}
private void createContents(Composite parent) {
parent.setLayout(new GridLayout(3, false));
Label label = new Label(parent, SWT.NONE);
label.setText("List of existing Android Virtual Devices:");
label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 2, 1));
mRefreshButton = new Button(parent, SWT.PUSH);
mRefreshButton.setText("Refresh");
mRefreshButton.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
mRefreshButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onRefreshSelected(); //$hide$
}
});
Composite group = new Composite(parent, SWT.NONE);
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
GridLayout gl;
group.setLayout(gl = new GridLayout(1, false /*makeColumnsEqualWidth*/));
gl.marginHeight = gl.marginWidth = 0;
mAvdSelector = new AvdSelector(group,
SelectionMode.SELECT,
new AvdSelector.IExtraAction() {
public String label() {
return "Delete AVD...";
}
public boolean isEnabled() {
return mAvdSelector != null && mAvdSelector.getSelected() != null;
}
public void run() {
//onDelete();
}
});
}
@Override
public void dispose() {
mUpdaterData.removeListener(this);
super.dispose();
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
// -- Start of internal part ----------
// Hide everything down-below from SWT designer
//$hide>>$
/**
* Called by the constructor right after {@link #createContents(Composite)}.
*/
private void postCreate() {
reloadAvdList();
}
/**
* Reloads the AVD list in the AVD selector.
* Tries to preserve the selection.
*/
private void reloadAvdList() {
AvdInfo selected = mAvdSelector.getSelected();
AvdInfo[] avds = null;
AvdManager manager = mUpdaterData.getAvdManager();
if (manager != null) {
avds = manager.getValidAvds();
}
mAvdSelector.setAvds(avds, null /*filter*/);
// Keep the list of known AVD names to check if they exist quickly. however
// use the list of all AVDs, including broken ones (unless we don't know their
// name).
mKnownAvdNames.clear();
if (manager != null) {
for (AvdInfo avd : manager.getAllAvds()) {
String name = avd.getName();
if (name != null) {
mKnownAvdNames.add(name);
}
}
}
mAvdSelector.setSelection(selected);
}
public void onSdkChange() {
reloadAvdList();
}
private void onRefreshSelected() {
mUpdaterData.reloadAvds();
reloadAvdList();
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -18,9 +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.sdkuilib.internal.repository.UpdaterData.ISdkListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
@@ -53,9 +52,8 @@ import java.io.File;
* - refresh callback
*/
public class LocalPackagesPage extends Composite {
public class LocalPackagesPage extends Composite implements ISdkListener {
private final UpdaterWindowImpl mUpdaterWindow;
private final UpdaterData mUpdaterData;
private Label mSdkLocLabel;
@@ -79,15 +77,13 @@ public class LocalPackagesPage extends Composite {
* @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer.
* @param updaterWindow The parent window.
*/
public LocalPackagesPage(Composite parent,
UpdaterData updaterData,
UpdaterWindowImpl updaterWindow) {
UpdaterData updaterData) {
super(parent, SWT.BORDER);
mUpdaterWindow = updaterWindow;
mUpdaterData = updaterData != null ? updaterData : new UpdaterData();
mUpdaterData.addListeners(this);
createContents(this);
postCreate(); //$hide$
@@ -186,6 +182,12 @@ public class LocalPackagesPage extends Composite {
}
}
@Override
public void dispose() {
mUpdaterData.removeListener(this);
super.dispose();
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
@@ -195,16 +197,6 @@ public class LocalPackagesPage extends Composite {
// Hide everything down-below from SWT designer
//$hide>>$
/**
* Must be called once to set the adapter input for the package table viewer.
*/
public void setInput(LocalSdkAdapter localSdkAdapter) {
mTableViewerPackages.setLabelProvider( localSdkAdapter.getLabelProvider());
mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());
mTableViewerPackages.setInput(localSdkAdapter);
onTreeSelected();
}
/**
* Called by the constructor right after {@link #createContents(Composite)}.
*/
@@ -249,8 +241,8 @@ public class LocalPackagesPage extends Composite {
}
private void onUpdateInstalledPackage() {
if (mUpdaterWindow != null) {
mUpdaterWindow.updateAll();
if (mUpdaterData != null) {
mUpdaterData.reloadSdk();
}
}
@@ -297,9 +289,15 @@ public class LocalPackagesPage extends Composite {
}
private void onRefreshSelected() {
if (mUpdaterWindow != null) {
mUpdaterWindow.scanLocalSdkFolders();
}
mUpdaterData.reloadSdk();
}
public void onSdkChange() {
LocalSdkAdapter localSdkAdapter = mUpdaterData.getLocalSdkAdapter();
mTableViewerPackages.setLabelProvider( localSdkAdapter.getLabelProvider());
mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());
mTableViewerPackages.setInput(localSdkAdapter);
onTreeSelected();
}
// End of hiding from SWT Designer

View File

@@ -33,16 +33,10 @@ import org.eclipse.swt.graphics.Image;
*/
class LocalSdkAdapter {
private final LocalSdkParser mLocalSdkParser;
private String mOsSdkRoot;
private final UpdaterData mUpdaterData;
public LocalSdkAdapter(LocalSdkParser localSdkParser) {
mLocalSdkParser = localSdkParser;
}
public void setSdkRoot(String osSdkRoot) {
mOsSdkRoot = osSdkRoot;
mLocalSdkParser.clearPackages();
public LocalSdkAdapter(UpdaterData updaterData) {
mUpdaterData = updaterData;
}
public ILabelProvider getLabelProvider() {
@@ -95,13 +89,13 @@ class LocalSdkAdapter {
public Object[] getElements(Object inputElement) {
if (inputElement instanceof LocalSdkAdapter) {
LocalSdkAdapter adapter = (LocalSdkAdapter) inputElement;
LocalSdkParser parser = adapter.mLocalSdkParser;
LocalSdkParser parser = adapter.mUpdaterData.getLocalSdkParser();
Package[] packages = parser.getPackages();
if (packages == null) {
// load on demand the first time
packages = parser.parseSdk(adapter.mOsSdkRoot);
packages = parser.parseSdk(adapter.mUpdaterData.getOsSdkRoot());
}
if (packages != null) {

View File

@@ -21,6 +21,7 @@ import com.android.sdklib.internal.repository.Archive;
import com.android.sdklib.internal.repository.IDescription;
import com.android.sdklib.internal.repository.Package;
import com.android.sdklib.internal.repository.RepoSource;
import com.android.sdkuilib.internal.repository.UpdaterData.ISdkListener;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
@@ -60,9 +61,8 @@ import java.util.ArrayList;
* - install selected callback
*/
public class RemotePackagesPage extends Composite {
public class RemotePackagesPage extends Composite implements ISdkListener {
private final UpdaterWindowImpl mUpdaterWindow;
private final UpdaterData mUpdaterData;
private CheckboxTreeViewer mTreeViewerSources;
@@ -82,15 +82,13 @@ public class RemotePackagesPage extends Composite {
* @param parent The parent of the composite.
* @param updaterData An instance of {@link UpdaterData}. If null, a local
* one will be allocated just to help with the SWT Designer.
* @param updaterWindow The parent window.
*/
RemotePackagesPage(Composite parent,
UpdaterData updaterData,
UpdaterWindowImpl updaterWindow) {
UpdaterData updaterData) {
super(parent, SWT.BORDER);
mUpdaterWindow = updaterWindow;
mUpdaterData = updaterData != null ? updaterData : new UpdaterData();
mUpdaterData.addListeners(this);
createContents(this);
postCreate(); //$hide$
@@ -173,6 +171,12 @@ public class RemotePackagesPage extends Composite {
mInstallSelectedButton.setText("Install Selected");
}
@Override
public void dispose() {
mUpdaterData.removeListener(this);
super.dispose();
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
@@ -182,16 +186,6 @@ public class RemotePackagesPage extends Composite {
// Hide everything down-below from SWT designer
//$hide>>$
/**
* Must be called once to set the adapter input for the sources tree viewer.
*/
public void setInput(RepoSourcesAdapter sources) {
mTreeViewerSources.setContentProvider(sources.getContentProvider());
mTreeViewerSources.setLabelProvider( sources.getLabelProvider());
mTreeViewerSources.setInput(sources);
onTreeSelected();
}
/**
* Called by the constructor right after {@link #createContents(Composite)}.
*/
@@ -289,8 +283,8 @@ public class RemotePackagesPage extends Composite {
}
}
if (mUpdaterWindow != null) {
mUpdaterWindow.installArchives(archives);
if (mUpdaterData != null) {
mUpdaterData.installArchives(archives);
}
}
@@ -303,11 +297,19 @@ public class RemotePackagesPage extends Composite {
}
private void onRefreshSelected() {
if (mUpdaterWindow != null) {
mUpdaterWindow.refreshSources(false /*forceFetching*/, null /*monitor*/);
if (mUpdaterData != null) {
mUpdaterData.refreshSources(false /*forceFetching*/, null /*monitor*/);
}
}
public void onSdkChange() {
RepoSourcesAdapter sources = mUpdaterData.getSourcesAdapter();
mTreeViewerSources.setContentProvider(sources.getContentProvider());
mTreeViewerSources.setLabelProvider( sources.getLabelProvider());
mTreeViewerSources.setInput(sources);
onTreeSelected();
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -16,32 +16,78 @@
package com.android.sdkuilib.internal.repository;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.avd.AvdManager;
import com.android.sdklib.internal.repository.Archive;
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.RepoSource;
import com.android.sdklib.internal.repository.RepoSources;
import org.eclipse.swt.widgets.Display;
import java.util.ArrayList;
import java.util.Collection;
/**
* Data shared between {@link UpdaterWindowImpl} and its pages.
*/
class UpdaterData {
private ISdkLog mSdkLog;
private String mOsSdkRoot;
private final ISdkLog mSdkLog;
private ITaskFactory mTaskFactory;
private boolean mUserCanChangeSdkRoot;
private SdkManager mSdkManager;
private AvdManager mAvdManager;
private final LocalSdkParser mLocalSdkParser = new LocalSdkParser();
private final RepoSources mSources = new RepoSources();
private final LocalSdkAdapter mLocalSdkAdapter = new LocalSdkAdapter(mLocalSdkParser);
private final LocalSdkAdapter mLocalSdkAdapter = new LocalSdkAdapter(this);
private final RepoSourcesAdapter mSourcesAdapter = new RepoSourcesAdapter(mSources);
public void setOsSdkRoot(String osSdkRoot) {
private final ArrayList<ISdkListener> mListeners = new ArrayList<ISdkListener>();
public interface ISdkListener {
void onSdkChange();
}
public UpdaterData(String osSdkRoot, ISdkLog sdkLog) {
mOsSdkRoot = osSdkRoot;
mSdkLog = sdkLog;
initSdk();
}
/**
* default access constructor used by the pages when instantiated by the SWT designer.
*/
UpdaterData() {
mOsSdkRoot = null;
mSdkLog = null;
}
public void setOsSdkRoot(String osSdkRoot) {
if (mOsSdkRoot == null || mOsSdkRoot.equals(osSdkRoot) == false) {
mOsSdkRoot = osSdkRoot;
initSdk();
}
}
public String getOsSdkRoot() {
return mOsSdkRoot;
}
public void setTaskFactory(ITaskFactory taskFactory) {
mTaskFactory = taskFactory;
}
public void setUserCanChangeSdkRoot(boolean userCanChangeSdkRoot) {
mUserCanChangeSdkRoot = userCanChangeSdkRoot;
}
@@ -66,11 +112,207 @@ class UpdaterData {
return mLocalSdkAdapter;
}
public void setSdkLog(ISdkLog sdkLog) {
mSdkLog = sdkLog;
}
public ISdkLog getSdkLog() {
return mSdkLog;
}
public SdkManager getSdkManager() {
return mSdkManager;
}
public AvdManager getAvdManager() {
return mAvdManager;
}
public void addListeners(ISdkListener listener) {
if (mListeners.contains(listener) == false) {
mListeners.add(listener);
}
}
public void removeListener(ISdkListener listener) {
mListeners.remove(listener);
}
/**
* Reloads the SDK content (targets).
* <p/> This also reloads the AVDs in case their status changed.
* <p/>This does not notify the listeners ({@link ISdkListener}).
*/
public void reloadSdk() {
// reload SDK
mSdkManager.reloadSdk(mSdkLog);
// reload AVDs
if (mAvdManager != null) {
try {
mAvdManager.reloadAvds();
} catch (AndroidLocationException e) {
// FIXME
}
}
// notify adapters?
// TODO
// notify listeners
notifyListeners();
}
/**
* Reloads the AVDs.
* <p/>This does not notify the listeners.
*/
public void reloadAvds() {
// reload AVDs
if (mAvdManager != null) {
try {
mAvdManager.reloadAvds();
} catch (AndroidLocationException e) {
// FIXME
}
}
}
/**
* Notify the listeners ({@link ISdkListener}) that the SDK was reloaded.
* <p/>This can be called from any thread.
*/
public void notifyListeners() {
Display display = Display.getCurrent();
if (display != null && mListeners.size() > 0) {
display.syncExec(new Runnable() {
public void run() {
for (ISdkListener listener : mListeners) {
try {
listener.onSdkChange();
} catch (Throwable t) {
// TODO: log error
}
}
}
});
}
}
/**
* Install the list of given {@link Archive}s.
* @param archives The archives to install. Incompatible ones will be skipped.
*/
public void installArchives(final Collection<Archive> archives) {
if (mTaskFactory == null) {
throw new IllegalArgumentException("Task Factory is null");
}
// TODO filter the archive list to: a/ display a list of what is going to be installed,
// b/ display licenses and c/ check that the selected packages are actually upgrades
// or ask user to confirm downgrades. All this should be done in a separate class+window
// which will then call this method with the final list.
// TODO move most parts to SdkLib, maybe as part of Archive, making archives self-installing.
mTaskFactory.start("Installing Archives", new ITask() {
public void run(ITaskMonitor monitor) {
final int progressPerArchive = 2 * Archive.NUM_MONITOR_INC;
monitor.setProgressMax(archives.size() * progressPerArchive);
monitor.setDescription("Preparing to install archives");
int numInstalled = 0;
for (Archive archive : archives) {
int nextProgress = monitor.getProgress() + progressPerArchive;
try {
if (monitor.isCancelRequested()) {
break;
}
if (archive.install(mOsSdkRoot, monitor)) {
numInstalled++;
}
} catch (Throwable t) {
// Display anything unexpected in the monitor.
monitor.setResult("Unexpected Error: %1$s", t.getMessage());
} finally {
// Always move the progress bar to the desired position.
// This allows internal methods to not have to care in case
// they abort early
monitor.incProgress(nextProgress - monitor.getProgress());
}
}
if (numInstalled == 0) {
monitor.setDescription("Done. Nothing was installed.");
} else {
monitor.setDescription("Done. %1$d %2$s installed.",
numInstalled,
numInstalled == 1 ? "package" : "packages");
}
}
});
}
public void updateAll() {
if (mTaskFactory == null) {
throw new IllegalArgumentException("Task Factory is null");
}
mTaskFactory.start("Update Archives", new ITask() {
public void run(ITaskMonitor monitor) {
monitor.setProgressMax(3);
monitor.setDescription("Refresh sources");
refreshSources(true, monitor.createSubMonitor(1));
}
});
}
/**
* Refresh sources
*
* @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, ITaskMonitor monitor) {
ITask task = new ITask() {
public void run(ITaskMonitor monitor) {
ArrayList<RepoSource> sources = mSources.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);
}
}
/**
* Initializes the {@link SdkManager} and the {@link AvdManager}.
*/
private void initSdk() {
mSdkManager = SdkManager.createManager(mOsSdkRoot, mSdkLog);
try {
mAvdManager = null; // remove the old one if needed.
mAvdManager = new AvdManager(mSdkManager, mSdkLog);
} catch (AndroidLocationException e) {
mSdkLog.error(e, "Unable to read AVDs");
}
// notify adapters/parsers
// TODO
// notify listeners.
notifyListeners();
}
}

View File

@@ -19,9 +19,6 @@ package com.android.sdkuilib.internal.repository;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.repository.Archive;
import com.android.sdklib.internal.repository.ITask;
import com.android.sdklib.internal.repository.ITaskMonitor;
import com.android.sdklib.internal.repository.RepoSource;
import com.android.sdklib.repository.SdkRepository;
@@ -45,7 +42,6 @@ import org.eclipse.swt.widgets.Shell;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
/**
* This is the private implementation of the UpdateWindow.
@@ -53,7 +49,7 @@ import java.util.Collection;
public class UpdaterWindowImpl {
/** Internal data shared between the window and its pages. */
private final UpdaterData mUpdaterData = new UpdaterData();
private final UpdaterData mUpdaterData;
/** The array of pages instances. Only one is visible at a time. */
private ArrayList<Composite> mPages = new ArrayList<Composite>();
/** Indicates a page change is due to an internal request. Prevents callbacks from looping. */
@@ -73,12 +69,12 @@ public class UpdaterWindowImpl {
private Composite mPagesRootComposite;
private LocalPackagesPage mLocalPackagePage;
private RemotePackagesPage mRemotePackagesPage;
private AvdManagerPage mAvdManagerPage;
private StackLayout mStackLayout;
private Image mIconImage;
public UpdaterWindowImpl(ISdkLog sdkLog, String osSdkRoot, boolean userCanChangeSdkRoot) {
mUpdaterData.setSdkLog(sdkLog);
mUpdaterData.setOsSdkRoot(osSdkRoot);
mUpdaterData = new UpdaterData(osSdkRoot, sdkLog);
mUpdaterData.setUserCanChangeSdkRoot(userCanChangeSdkRoot);
}
@@ -136,8 +132,9 @@ public class UpdaterWindowImpl {
mStackLayout = new StackLayout();
mPagesRootComposite.setLayout(mStackLayout);
mLocalPackagePage = new LocalPackagesPage(mPagesRootComposite, mUpdaterData, this);
mRemotePackagesPage = new RemotePackagesPage(mPagesRootComposite, mUpdaterData, this);
mAvdManagerPage = new AvdManagerPage(mPagesRootComposite, mUpdaterData);
mLocalPackagePage = new LocalPackagesPage(mPagesRootComposite, mUpdaterData);
mRemotePackagesPage = new RemotePackagesPage(mPagesRootComposite, mUpdaterData);
mSashForm.setWeights(new int[] {150, 576});
}
@@ -214,7 +211,9 @@ public class UpdaterWindowImpl {
*/
private void firstInit() {
mTaskFactory = new ProgressTaskFactory(getShell());
mUpdaterData.setTaskFactory(mTaskFactory);
addPage(mAvdManagerPage, "Virtual Devices");
addPage(mLocalPackagePage, "Installed Packages");
addPage(mRemotePackagesPage, "Available Packages");
addExtraPages();
@@ -225,8 +224,8 @@ public class UpdaterWindowImpl {
// TODO read and apply settings
// TODO read add-on sources from some file
setupSources();
scanLocalSdkFolders();
initializeSettings();
mUpdaterData.notifyListeners();
}
// --- page switching ---
@@ -325,16 +324,8 @@ public class UpdaterWindowImpl {
}
}
mRemotePackagesPage.setInput(mUpdaterData.getSourcesAdapter());
}
/**
* Used to scan the local SDK folders the first time.
*/
public void scanLocalSdkFolders() {
mUpdaterData.getLocalSdkAdapter().setSdkRoot(mUpdaterData.getOsSdkRoot());
mLocalPackagePage.setInput(mUpdaterData.getLocalSdkAdapter());
mRemotePackagesPage.onSdkChange();
}
/**
@@ -353,101 +344,6 @@ public class UpdaterWindowImpl {
}
}
/**
* Install the list of given {@link Archive}s.
* @param archives The archives to install. Incompatible ones will be skipped.
*/
public void installArchives(final Collection<Archive> archives) {
// TODO filter the archive list to: a/ display a list of what is going to be installed,
// b/ display licenses and c/ check that the selected packages are actually upgrades
// or ask user to confirm downgrades. All this should be done in a separate class+window
// which will then call this method with the final list.
// TODO move most parts to SdkLib, maybe as part of Archive, making archives self-installing.
mTaskFactory.start("Installing Archives", new ITask() {
public void run(ITaskMonitor monitor) {
final int progressPerArchive = 2 * Archive.NUM_MONITOR_INC;
monitor.setProgressMax(archives.size() * progressPerArchive);
monitor.setDescription("Preparing to install archives");
int numInstalled = 0;
for (Archive archive : archives) {
int nextProgress = monitor.getProgress() + progressPerArchive;
try {
if (monitor.isCancelRequested()) {
break;
}
if (archive.install(mUpdaterData.getOsSdkRoot(), monitor)) {
numInstalled++;
}
} catch (Throwable t) {
// Display anything unexpected in the monitor.
monitor.setResult("Unexpected Error: %1$s", t.getMessage());
} finally {
// Always move the progress bar to the desired position.
// This allows internal methods to not have to care in case
// they abort early
monitor.incProgress(nextProgress - monitor.getProgress());
}
}
if (numInstalled == 0) {
monitor.setDescription("Done. Nothing was installed.");
} else {
monitor.setDescription("Done. %1$d %2$s installed.",
numInstalled,
numInstalled == 1 ? "package" : "packages");
}
}
});
}
public void updateAll() {
mTaskFactory.start("Update Archives", new ITask() {
public void run(ITaskMonitor monitor) {
monitor.setProgressMax(3);
monitor.setDescription("Refresh sources");
refreshSources(true, monitor.createSubMonitor(1));
}
});
}
/**
* Refresh sources
*
* @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, 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);
}
}
// End of hiding from SWT Designer
//$hide<<$
}

View File

@@ -124,7 +124,9 @@ public final class AvdSelector {
// Layout has 2 columns
Composite group = new Composite(parent, SWT.NONE);
group.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
GridLayout gl;
group.setLayout(gl = new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
gl.marginHeight = gl.marginWidth = 0;
group.setLayoutData(new GridData(GridData.FILL_BOTH));
group.setFont(parent.getFont());