From: Xavier Ducrohet Date: Wed, 10 Jun 2009 18:22:46 +0000 (-0700) Subject: Centralized the local data, and create new listener mechanism to access it. X-Git-Tag: android-x86-1.6~9^2~82 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=201f83164f96036bcdc36a3c42082673a9fe429a;p=android-x86%2Fdevelopment.git Centralized the local data, and create new listener mechanism to access it. Created a permanent SdkManager in UpdaterData (alongside a new AvdManager). Pages can request a reload (for example on install/delete of a local package), and other pages are notified of SDK changes to update their display (local packages, local AVDs, available packages, etc...) Removed references to UpdaterWindow from the pages (moved some actions like installArchives and refreshSources into UpdaterData). Added a new page for the AVDs. Pretty basic for now (only the current AVD display). Clicking refresh on the Local pages causes a reload which triggers a refresh of the listeners pages which properly reloads the AVD page. --- diff --git a/tools/sdkmanager/libs/sdkuilib/.classpath b/tools/sdkmanager/libs/sdkuilib/.classpath index 5e78ee75..5a1790fc 100644 --- a/tools/sdkmanager/libs/sdkuilib/.classpath +++ b/tools/sdkmanager/libs/sdkuilib/.classpath @@ -1,8 +1,9 @@ - - - - - - - - + + + + + + + + + diff --git a/tools/sdkmanager/libs/sdkuilib/src/Android.mk b/tools/sdkmanager/libs/sdkuilib/src/Android.mk index 282de28e..970c1220 100644 --- a/tools/sdkmanager/libs/sdkuilib/src/Android.mk +++ b/tools/sdkmanager/libs/sdkuilib/src/Android.mk @@ -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 \ diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java new file mode 100755 index 00000000..52582f40 --- /dev/null +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AvdManagerPage.java @@ -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 mKnownAvdNames = new HashSet(); + 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<<$ +} diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java index 4f070091..f423358f 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java @@ -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$ @@ -187,6 +183,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 } @@ -196,16 +198,6 @@ public class LocalPackagesPage extends Composite { //$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)}. */ private void postCreate() { @@ -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 diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java index 330be18a..1deee926 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java @@ -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) { diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java index 712821d3..4f3314fd 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java @@ -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$ @@ -174,6 +172,12 @@ public class RemotePackagesPage extends Composite { } @Override + public void dispose() { + mUpdaterData.removeListener(this); + super.dispose(); + } + + @Override protected void checkSubclass() { // Disable the check that prevents subclassing of SWT components } @@ -183,16 +187,6 @@ public class RemotePackagesPage extends Composite { //$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)}. */ private void postCreate() { @@ -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<<$ } diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index 47ce3acc..055fbd2b 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -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 mListeners = new ArrayList(); + + 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). + *

This also reloads the AVDs in case their status changed. + *

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. + *

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. + *

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 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 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(); + } } diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java index c788eebb..2740958a 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java @@ -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 mPages = new ArrayList(); /** 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 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 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<<$ } diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java index 0d77ccb9..20560086 100644 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java @@ -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());