diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java index 6de260129..aad181289 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java @@ -1521,7 +1521,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener /** * Get the stderr/stdout outputs of a process and return when the process is done. * Both must be read or the process will block on windows. - * @param process The process to get the ouput from + * @param process The process to get the output from */ private void grabEmulatorOutput(final Process process) { // read the lines as they come. if null is returned, it's diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java index 6813d0b9e..d2fe5ae23 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java @@ -411,6 +411,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener offsetComp.setLayout(layout); mPreferredAvdSelector = new AvdSelector(offsetComp, + mSdk.getSdkLocation(), mSdk.getAvdManager(), new NonRunningAvdFilter(), DisplayMode.SIMPLE_SELECTION); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java index 2378248ed..74d4c4bf6 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java @@ -195,7 +195,9 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { // create the selector with no manager, we'll reset the manager every time this is // displayed to ensure we have the latest one (dialog is reused but SDK could have // been changed in between. - mPreferredAvdSelector = new AvdSelector(offsetComp, null /* avd manager */, + mPreferredAvdSelector = new AvdSelector(offsetComp, + Sdk.getCurrent().getSdkLocation(), + null /* avd manager */, DisplayMode.SIMPLE_CHECK); mPreferredAvdSelector.setTableHeightHint(100); mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() { 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 index d69ce5f42..ccfd27607 100755 --- 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 @@ -52,7 +52,10 @@ public class AvdManagerPage extends Composite implements ISdkListener { Label label = new Label(parent, SWT.NONE); label.setText("List of existing Android Virtual Devices:"); - mAvdSelector = new AvdSelector(parent, mUpdaterData.getAvdManager(), DisplayMode.MANAGER); + mAvdSelector = new AvdSelector(parent, + mUpdaterData.getOsSdkRoot(), + mUpdaterData.getAvdManager(), + DisplayMode.MANAGER); } @Override 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 5c47b7cab..e36bd6c8e 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 @@ -23,6 +23,7 @@ import com.android.sdklib.internal.repository.RepoSource; import com.android.sdklib.internal.repository.RepoSources; import com.android.sdklib.repository.SdkRepository; import com.android.sdkuilib.internal.repository.icons.ImageFactory; +import com.android.sdkuilib.internal.tasks.ProgressTaskFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java similarity index 96% rename from tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java rename to tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java index fe73ac564..12ef2cc34 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressDialog.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressDialog.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.sdkuilib.internal.repository; +package com.android.sdkuilib.internal.tasks; import com.android.sdklib.internal.repository.ITaskMonitor; diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java similarity index 95% rename from tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java rename to tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java index 1ec728701..9ed8a01d6 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.sdkuilib.internal.repository; +package com.android.sdkuilib.internal.tasks; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskMonitor; @@ -26,7 +26,7 @@ import org.eclipse.swt.widgets.Shell; /** * An {@link ITaskMonitor} that displays a {@link ProgressDialog}. */ -class ProgressTask implements ITaskMonitor { +public final class ProgressTask implements ITaskMonitor { private static final double MAX_COUNT = 10000.0; diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java similarity index 88% rename from tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java rename to tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java index 08f5485aa..c90df26e5 100755 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.sdkuilib.internal.repository; +package com.android.sdkuilib.internal.tasks; import com.android.sdklib.internal.repository.ITask; import com.android.sdklib.internal.repository.ITaskFactory; @@ -25,7 +25,7 @@ import org.eclipse.swt.widgets.Shell; * An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog * for each new task. */ -public class ProgressTaskFactory implements ITaskFactory { +public final class ProgressTaskFactory implements ITaskFactory { private final Shell mShell; diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java index 9ef76e2ac..8804c702b 100644 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java @@ -19,7 +19,6 @@ package com.android.sdkuilib.internal.widgets; import com.android.prefs.AndroidLocation; import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkManager; import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.avd.AvdManager.AvdInfo; 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 ab02b8d77..8826b4c0e 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 @@ -20,10 +20,14 @@ import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.ISdkLog; import com.android.sdklib.NullSdkLog; +import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.avd.AvdManager; import com.android.sdklib.internal.avd.AvdManager.AvdInfo; import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus; +import com.android.sdklib.internal.repository.ITask; +import com.android.sdklib.internal.repository.ITaskMonitor; import com.android.sdkuilib.internal.repository.icons.ImageFactory; +import com.android.sdkuilib.internal.tasks.ProgressTask; import com.android.sdkuilib.repository.UpdaterWindow; import org.eclipse.jface.dialogs.MessageDialog; @@ -49,16 +53,19 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; +import java.io.BufferedReader; +import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.util.ArrayList; /** * The AVD selector is a table that is added to the given parent composite. *
- * To use, create it using {@link #AvdSelector(Composite, AvdManager, DisplayMode)} then - * call {@link #setSelection(AvdInfo)}, {@link #setSelectionListener(SelectionListener)} - * and finally use {@link #getSelected()} to retrieve the selection. + * After using one of the constructors, call {@link #setSelection(AvdInfo)}, + * {@link #setSelectionListener(SelectionListener)} and finally use + * {@link #getSelected()} to retrieve the selection. */ public final class AvdSelector { private static int NUM_COL = 2; @@ -66,6 +73,7 @@ public final class AvdSelector { private final DisplayMode mDisplayMode; private AvdManager mAvdManager; + private final String mOsSdkPath; private Table mTable; private Button mDeleteButton; @@ -74,16 +82,20 @@ public final class AvdSelector { private Button mRefreshButton; private Button mManagerButton; private Button mUpdateButton; + private Button mStartButton; private SelectionListener mSelectionListener; private IAvdFilter mTargetFilter; + /** Defaults to true. Changed by the {@link #setEnabled(boolean)} method to represent the + * "global" enabled state on this composite. */ private boolean mIsEnabled = true; private ImageFactory mImageFactory; private Image mOkImage; private Image mBrokenImage; + /** * The display mode of the AVD Selector. */ @@ -170,15 +182,20 @@ public final class AvdSelector { * {@link IAndroidTarget} will be displayed. * * @param parent The parent composite where the selector will be added. + * @param osSdkPath The SDK root path. When not null, enables the start button to start + * an emulator on a given AVD. * @param manager the AVD manager. * @param filter When non-null, will allow filtering the AVDs to display. - * @param extraAction When non-null, displays an extra action button. * @param displayMode The display mode ({@link DisplayMode}). + * + * TODO: pass an ISdkLog and use it when reloading, starting the emulator, etc. */ public AvdSelector(Composite parent, + String osSdkPath, AvdManager manager, IAvdFilter filter, DisplayMode displayMode) { + mOsSdkPath = osSdkPath; mAvdManager = manager; mTargetFilter = filter; mDisplayMode = displayMode; @@ -265,6 +282,17 @@ public final class AvdSelector { } }); + mStartButton = new Button(buttons, SWT.PUSH | SWT.FLAT); + mStartButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + mStartButton.setText("Start..."); + mStartButton.setToolTipText("Starts the selected AVD."); + mStartButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + onStart(); + } + }); + Composite padding = new Composite(buttons, SWT.NONE); padding.setLayoutData(new GridData(GridData.FILL_VERTICAL)); @@ -327,9 +355,11 @@ public final class AvdSelector { * @param manager the AVD manager. * @param displayMode The display mode ({@link DisplayMode}). */ - public AvdSelector(Composite parent, AvdManager manager, + public AvdSelector(Composite parent, + String osSdkPath, + AvdManager manager, DisplayMode displayMode) { - this(parent, manager, (IAvdFilter)null /* filter */, displayMode); + this(parent, osSdkPath, manager, (IAvdFilter)null /* filter */, displayMode); } /** @@ -344,10 +374,11 @@ public final class AvdSelector { * @param displayMode The display mode ({@link DisplayMode}). */ public AvdSelector(Composite parent, + String osSdkPath, AvdManager manager, IAndroidTarget filter, DisplayMode displayMode) { - this(parent, manager, new TargetBasedFilter(filter), displayMode); + this(parent, osSdkPath, manager, new TargetBasedFilter(filter), displayMode); } /** * Sets the table grid layout data. @@ -373,7 +404,6 @@ public final class AvdSelector { * This must be called from the UI thread. * * @param reload if true, the AVD manager will reload the AVD from the disk. - * @throws AndroidLocationException if reload the AVD failed. * @return false if the reloading failed. This is always true if reload is *false.
*/
@@ -735,11 +765,13 @@ public final class AvdSelector {
}
/**
- * Updates the enable state of the Details, Delete and Update buttons.
+ * Updates the enable state of the Details, Start, Delete and Update buttons.
*/
private void enableActionButtons() {
if (mIsEnabled == false) {
mDetailsButton.setEnabled(false);
+ mStartButton.setEnabled(false);
+
if (mDeleteButton != null) {
mDeleteButton.setEnabled(false);
}
@@ -748,13 +780,20 @@ public final class AvdSelector {
}
} else {
AvdInfo selection = getTableSelection();
+ boolean hasSelection = selection != null;
+
+ mDetailsButton.setEnabled(hasSelection);
+ mStartButton.setEnabled(mOsSdkPath != null &&
+ hasSelection &&
+ selection != null &&
+ selection.getStatus() == AvdStatus.OK);
- mDetailsButton.setEnabled(selection != null);
if (mDeleteButton != null) {
- mDeleteButton.setEnabled(selection != null);
+ mDeleteButton.setEnabled(hasSelection);
}
if (mUpdateButton != null) {
- mUpdateButton.setEnabled(selection != null &&
+ mUpdateButton.setEnabled(hasSelection &&
+ selection != null &&
selection.getStatus() == AvdStatus.ERROR_IMAGE_DIR);
}
}
@@ -849,6 +888,113 @@ public final class AvdSelector {
refresh(true /*reload*/); // UpdaterWindow uses its own AVD manager so this one must reload.
}
+ private void onStart() {
+ AvdInfo avdInfo = getTableSelection();
+
+ if (avdInfo == null || mOsSdkPath == null) {
+ return;
+ }
+
+ String path = mOsSdkPath +
+ File.separator +
+ SdkConstants.OS_SDK_TOOLS_FOLDER +
+ SdkConstants.FN_EMULATOR;
+
+ final String avdName = avdInfo.getName();
+
+ // build the command line based on the available parameters.
+ ArrayList