Merge change 5767 into donut

* changes:
  AVD creation dialog.
This commit is contained in:
Android (Google) Code Review
2009-06-30 05:17:48 -07:00
6 changed files with 507 additions and 50 deletions

View File

@@ -239,6 +239,9 @@ class Main {
*/
private void showMainWindow() {
try {
// display a message talking about the command line version
System.out.printf("No command line parameters provided, launching UI.\n" +
"See 'android --help' for operations from the command line.\n");
UpdaterWindow window = new UpdaterWindow(
mSdkLog,
mOsSdkFolder,

View File

@@ -311,7 +311,7 @@ public final class AvdManager {
private final ArrayList<AvdInfo> mAllAvdList = new ArrayList<AvdInfo>();
private AvdInfo[] mValidAvdList;
private AvdInfo[] mBrokenAvdList;
private final SdkManager mSdk;
private final SdkManager mSdkManager;
/**
* TODO remove this field. Each caller should give its own logger to the methods
@@ -323,12 +323,19 @@ public final class AvdManager {
*/
private ISdkLog mSdkLog;
public AvdManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
mSdk = sdk;
public AvdManager(SdkManager sdkManager, ISdkLog sdkLog) throws AndroidLocationException {
mSdkManager = sdkManager;
mSdkLog = sdkLog;
buildAvdList(mAllAvdList);
}
/**
* Returns the {@link SdkManager} associated with the {@link AvdManager}.
*/
public SdkManager getSdkManager() {
return mSdkManager;
}
/**
* Changes the current {@link ISdkLog}.
*
@@ -407,7 +414,7 @@ public final class AvdManager {
}
} else {
synchronized (mAllAvdList) {
for (AvdInfo info : getValidAvds()) {
for (AvdInfo info : mAllAvdList) {
if (info.getName().equals(name)) {
return info;
}
@@ -558,7 +565,7 @@ public final class AvdManager {
String path = sdcardFile.getAbsolutePath();
// execute mksdcard with the proper parameters.
File toolsFolder = new File(mSdk.getLocation(), SdkConstants.FD_TOOLS);
File toolsFolder = new File(mSdkManager.getLocation(), SdkConstants.FD_TOOLS);
File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
if (mkSdCard.isFile() == false) {
@@ -712,7 +719,7 @@ public final class AvdManager {
String imageFullPath = target.getPath(IAndroidTarget.IMAGES);
// make this path relative to the SDK location
String sdkLocation = mSdk.getLocation();
String sdkLocation = mSdkManager.getLocation();
if (imageFullPath.startsWith(sdkLocation) == false) {
// this really really should not happen.
assert false;
@@ -757,7 +764,7 @@ public final class AvdManager {
String path = skin.getAbsolutePath();
// make this path relative to the SDK location
String sdkLocation = mSdk.getLocation();
String sdkLocation = mSdkManager.getLocation();
if (path.startsWith(sdkLocation) == false) {
// this really really should not happen.
mSdkLog.error(null, "Target location is not inside the SDK.");
@@ -841,9 +848,9 @@ public final class AvdManager {
File f = avdInfo.getIniFile();
if (f != null && f.exists()) {
log.printf("Deleting file %1$s", f.getCanonicalPath());
log.printf("Deleting file %1$s\n", f.getCanonicalPath());
if (!f.delete()) {
log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath());
error = true;
}
}
@@ -852,10 +859,10 @@ public final class AvdManager {
if (path != null) {
f = new File(path);
if (f.exists()) {
log.printf("Deleting folder %1$s", f.getCanonicalPath());
log.printf("Deleting folder %1$s\n", f.getCanonicalPath());
recursiveDelete(f);
if (!f.delete()) {
log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath());
error = true;
}
}
@@ -864,10 +871,10 @@ public final class AvdManager {
removeAvd(avdInfo);
if (error) {
log.printf("\nAVD '%1$s' deleted with errors. See errors above.",
log.printf("\nAVD '%1$s' deleted with errors. See errors above.\n",
avdInfo.getName());
} else {
log.printf("\nAVD '%1$s' deleted.", avdInfo.getName());
log.printf("\nAVD '%1$s' deleted.\n", avdInfo.getName());
return true;
}
@@ -1031,7 +1038,7 @@ public final class AvdManager {
Map<String, String> properties = null;
if (targetHash != null) {
target = mSdk.getTargetFromHashString(targetHash);
target = mSdkManager.getTargetFromHashString(targetHash);
}
// load the AVD properties.
@@ -1055,13 +1062,13 @@ public final class AvdManager {
if (properties != null) {
String imageSysDir = properties.get(AVD_INI_IMAGES_1);
if (imageSysDir != null) {
File f = new File(mSdk.getLocation() + File.separator + imageSysDir);
File f = new File(mSdkManager.getLocation() + File.separator + imageSysDir);
if (f.isDirectory() == false) {
validImageSysdir = false;
} else {
imageSysDir = properties.get(AVD_INI_IMAGES_2);
if (imageSysDir != null) {
f = new File(mSdk.getLocation() + File.separator + imageSysDir);
f = new File(mSdkManager.getLocation() + File.separator + imageSysDir);
if (f.isDirectory() == false) {
validImageSysdir = false;
}

View File

@@ -114,7 +114,7 @@ public class UpdaterWindowImpl {
fl.marginHeight = fl.marginWidth = 5;
mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));
mAndroidSdkUpdater.setSize(745, 433);
mAndroidSdkUpdater.setText("Android SDK Updater");
mAndroidSdkUpdater.setText("Android SDK");
mSashForm = new SashForm(mAndroidSdkUpdater, SWT.NONE);

View File

@@ -0,0 +1,448 @@
/*
* 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.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;
import com.android.sdkuilib.internal.repository.icons.ImageFactory;
import com.android.sdkuilib.internal.widgets.AvdSelector.SdkLog;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import java.io.File;
import java.util.TreeMap;
public class AvdCreationDialog extends Dialog {
private final AvdManager mAvdManager;
private final TreeMap<String, IAndroidTarget> mCurrentTargets =
new TreeMap<String, IAndroidTarget>();
private Text mAvdName;
private Combo mTargetCombo;
private Text mSdCard;
private Button mBrowseSdCard;
private Combo mSkinCombo;
private Button mForceCreation;
private Button mOkButton;
private Label mStatusIcon;
private Label mStatusLabel;
private Composite mStatusComposite;
private final ImageFactory mImageFactory;
/**
* Callback when the AVD name is changed.
* Enables the force checkbox if the name is a duplicate.
*/
private class CreateNameModifyListener implements ModifyListener {
public void modifyText(ModifyEvent e) {
String name = mAvdName.getText().trim();
AvdInfo avdMatch = mAvdManager.getAvd(name, false /*validAvdOnly*/);
if (avdMatch != null) {
mForceCreation.setEnabled(true);
} else {
mForceCreation.setEnabled(false);
mForceCreation.setSelection(false);
}
validatePage();
}
}
private class ValidateListener extends SelectionAdapter implements ModifyListener {
public void modifyText(ModifyEvent e) {
validatePage();
}
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
validatePage();
}
}
protected AvdCreationDialog(Shell parentShell, AvdManager avdManager,
ImageFactory imageFactory) {
super(parentShell);
mAvdManager = avdManager;
mImageFactory = imageFactory;
}
@Override
public void create() {
super.create();
Point p = getShell().getSize();
p.x += 130;
getShell().setSize(p);
}
@Override
protected Control createContents(Composite parent) {
Control control = super.createContents(parent);
getShell().setText("Create new AVD");
mOkButton = getButton(IDialogConstants.OK_ID);
validatePage();
return control;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite top = new Composite(parent, SWT.NONE);
top.setLayoutData(new GridData(GridData.FILL_BOTH));
top.setLayout(new GridLayout(3, false));
Label label = new Label(top, SWT.NONE);
label.setText("Name:");
mAvdName = new Text(top, SWT.BORDER);
mAvdName.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
true, false, 2, 1));
mAvdName.addModifyListener(new CreateNameModifyListener());
label = new Label(top, SWT.NONE);
label.setText("Target:");
mTargetCombo = new Combo(top, SWT.READ_ONLY | SWT.DROP_DOWN);
mTargetCombo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
true, false, 2, 1));
mTargetCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
reloadSkinCombo();
validatePage();
}
});
label = new Label(top, SWT.NONE);
label.setText("SD Card:");
ValidateListener validateListener = new ValidateListener();
mSdCard = new Text(top, SWT.BORDER);
mSdCard.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mSdCard.addModifyListener(validateListener);
mBrowseSdCard = new Button(top, SWT.PUSH);
mBrowseSdCard.setText("Browse...");
mBrowseSdCard.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
onBrowseSdCard();
validatePage();
}
});
label = new Label(top, SWT.NONE);
label.setText("Skin");
mSkinCombo = new Combo(top, SWT.READ_ONLY | SWT.DROP_DOWN);
mSkinCombo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
true, false, 2, 1));
// dummies for alignment
label = new Label(top, SWT.NONE);
mForceCreation = new Button(top, SWT.CHECK);
mForceCreation.setText("Force");
mForceCreation.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
true, false, 2, 1));
mForceCreation.setEnabled(false);
mForceCreation.addSelectionListener(validateListener);
// add a separator to separate from the ok/cancel button
label = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1));
// add stuff for the error display
mStatusComposite = new Composite(top, SWT.NONE);
mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER,
true, false, 3, 1));
GridLayout gl;
mStatusComposite.setLayout(gl = new GridLayout(2, false));
gl.marginHeight = gl.marginWidth = 0;
mStatusIcon = new Label(mStatusComposite, SWT.NONE);
mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING,
false, false));
mStatusLabel = new Label(mStatusComposite, SWT.NONE);
mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mStatusLabel.setText(" \n "); //$NON-NLS-1$
reloadTargetCombo();
return top;
}
@Override
protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
if (id == IDialogConstants.OK_ID) {
label = "Create AVD";
}
return super.createButton(parent, id, label, defaultButton);
}
@Override
protected void okPressed() {
if (onCreate()) {
super.okPressed();
}
}
private void onBrowseSdCard() {
FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN);
dlg.setText("Choose SD Card image file.");
String fileName = dlg.open();
if (fileName != null) {
mSdCard.setText(fileName);
}
}
private void reloadTargetCombo() {
String selected = null;
int index = mTargetCombo.getSelectionIndex();
if (index >= 0) {
selected = mTargetCombo.getItem(index);
}
mCurrentTargets.clear();
mTargetCombo.removeAll();
boolean found = false;
index = -1;
SdkManager sdkManager = mAvdManager.getSdkManager();
if (sdkManager != null) {
for (IAndroidTarget target : sdkManager.getTargets()) {
String name = String.format("%s - %s",
target.getName(),
target.getApiVersionName());
mCurrentTargets.put(name, target);
mTargetCombo.add(name);
if (!found) {
index++;
found = name.equals(selected);
}
}
}
mTargetCombo.setEnabled(mCurrentTargets.size() > 0);
if (found) {
mTargetCombo.select(index);
}
reloadSkinCombo();
}
private void reloadSkinCombo() {
String selected = null;
int index = mSkinCombo.getSelectionIndex();
if (index >= 0) {
selected = mSkinCombo.getItem(index);
}
mSkinCombo.removeAll();
mSkinCombo.setEnabled(false);
index = mTargetCombo.getSelectionIndex();
if (index >= 0) {
String targetName = mTargetCombo.getItem(index);
boolean found = false;
IAndroidTarget target = mCurrentTargets.get(targetName);
if (target != null) {
mSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin()));
index = -1;
for (String skin : target.getSkins()) {
mSkinCombo.add(skin);
if (!found) {
index++;
found = skin.equals(selected);
}
}
mSkinCombo.setEnabled(true);
if (found) {
mSkinCombo.select(index);
} else {
mSkinCombo.select(0); // default
}
}
}
}
/**
* Validates the fields, displays errors and warnings.
* Enables the finish button if there are no errors.
*/
private void validatePage() {
String error = null;
// Validate AVD name
String avdName = mAvdName.getText().trim();
boolean hasAvdName = avdName.length() > 0;
if (hasAvdName && !AvdManager.RE_AVD_NAME.matcher(avdName).matches()) {
error = String.format(
"AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
avdName, AvdManager.CHARS_AVD_NAME);
}
// Validate target
if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() < 0) {
error = "A target must be selected in order to create an AVD.";
}
// Validate SDCard path or value
if (error == null) {
String sdName = mSdCard.getText().trim();
if (sdName.length() > 0 &&
!new File(sdName).isFile() &&
!AvdManager.SDCARD_SIZE_PATTERN.matcher(sdName).matches()) {
error = "SD Card must be either a file path or a size\nsuch as 128K or 64M.";
}
}
// Check for duplicate AVD name
if (hasAvdName && error == null) {
AvdInfo avdMatch = mAvdManager.getAvd(avdName, false /*validAvdOnly*/);
if (avdMatch != null && !mForceCreation.getSelection()) {
error = String.format(
"The AVD name '%s' is already used.\n" +
"Check \"Force\" to override existing AVD.",
avdName);
}
}
// Validate the create button
boolean can_create = hasAvdName && error == null;
if (can_create) {
can_create &= mTargetCombo.getSelectionIndex() >= 0;
}
mOkButton.setEnabled(can_create);
// -- update UI
if (error != null) {
mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png"));
mStatusLabel.setText(error);
} else {
mStatusIcon.setImage(null);
mStatusLabel.setText(" \n "); //$NON-NLS-1$
}
mStatusComposite.pack(true);
}
/**
* Creates an AVD from the values in the UI. Called when the user presses the OK button.
*/
private boolean onCreate() {
String avdName = mAvdName.getText().trim();
String sdName = mSdCard.getText().trim();
int targetIndex = mTargetCombo.getSelectionIndex();
int skinIndex = mSkinCombo.getSelectionIndex();
boolean force = mForceCreation.getSelection();
if (avdName.length() == 0 || targetIndex < 0) {
return false;
}
String targetName = mTargetCombo.getItem(targetIndex);
IAndroidTarget target = mCurrentTargets.get(targetName);
if (target == null) {
return false;
}
String skinName = null;
if (skinIndex > 0) {
// index 0 is the default, we don't use it
skinName = mSkinCombo.getItem(skinIndex);
}
SdkLog log = new SdkLog(String.format("Result of creating AVD '%s':", avdName),
getContents().getDisplay());
File avdFolder;
try {
avdFolder = new File(
AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
avdName + AvdManager.AVD_FOLDER_EXTENSION);
} catch (AndroidLocationException e) {
return false;
}
ISdkLog oldLog = null;
boolean success = false;
try {
// Temporarily change the AvdManager's logger for ours, since the API no longer
// takes a logger argument.
// TODO revisit this later. See comments in AvdManager#mSdkLog.
oldLog = mAvdManager.setSdkLog(log);
AvdInfo avdInfo = mAvdManager.createAvd(
avdFolder,
avdName,
target,
skinName,
sdName,
null, // hardwareConfig,
force);
success = avdInfo != null;
} finally {
mAvdManager.setSdkLog(oldLog);
}
log.displayResult(success);
return success;
}
}

View File

@@ -22,8 +22,6 @@ import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
@@ -85,12 +83,6 @@ final class AvdDetailsDialog extends Dialog {
*/
private void createContents() {
mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
mDialogShell.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
onShellClosed(e);
}
});
mDialogShell.setLayout(new GridLayout(1, false));
mDialogShell.setSize(450, 300);
mDialogShell.setText(getText());
@@ -130,7 +122,7 @@ final class AvdDetailsDialog extends Dialog {
sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
}
if (sdcard != null) {
displayValue(c, "sdcard:", sdcard);
displayValue(c, "SD Card:", sdcard);
}
// display other hardware
@@ -185,10 +177,6 @@ final class AvdDetailsDialog extends Dialog {
l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
}
private void onShellClosed(ShellEvent e) {
// TODO Auto-generated method stub
}
/**
* Centers the dialog in its parent shell.
*/

View File

@@ -25,6 +25,7 @@ import com.android.sdklib.internal.avd.AvdManager.AvdInfo.AvdStatus;
import com.android.sdkuilib.internal.repository.icons.ImageFactory;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
@@ -64,10 +65,10 @@ public final class AvdSelector {
private final DisplayMode mDisplayMode;
private Button mManagerButton;
private IAvdFilter mTargetFilter;
private AvdManager mManager;
private AvdManager mAvdManager;
private Image mOkImage;
private Image mBrokenImage;
private ImageFactory mIconFactory;
private ImageFactory mImageFactory;
/**
* The display mode of the AVD Selector.
@@ -164,7 +165,7 @@ public final class AvdSelector {
AvdManager manager,
IAvdFilter filter,
DisplayMode displayMode) {
mManager = manager;
mAvdManager = manager;
mTargetFilter = filter;
mDisplayMode = displayMode;
@@ -177,7 +178,7 @@ public final class AvdSelector {
group.setFont(parent.getFont());
group.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent arg0) {
mIconFactory.dispose();
mImageFactory.dispose();
}
});
@@ -200,7 +201,12 @@ public final class AvdSelector {
Button newButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
newButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
newButton.setText("New...");
// TODO handle 'new' button.
newButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
onNew();
}
});
Button deleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT);
deleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
@@ -262,9 +268,9 @@ public final class AvdSelector {
column3.setText("API Level");
// get some bitmaps.
mIconFactory = new ImageFactory(parent.getDisplay());
mOkImage = mIconFactory.getImageByName("accept_icon16.png");
mBrokenImage = mIconFactory.getImageByName("reject_icon16.png");
mImageFactory = new ImageFactory(parent.getDisplay());
mOkImage = mImageFactory.getImageByName("accept_icon16.png");
mBrokenImage = mImageFactory.getImageByName("reject_icon16.png");
adjustColumnsWidth(mTable, column0, column1, column2, column3);
setupSelectionListener(mTable);
@@ -331,7 +337,7 @@ public final class AvdSelector {
public boolean refresh(boolean reload) {
if (reload) {
try {
mManager.reloadAvds();
mAvdManager.reloadAvds();
} catch (AndroidLocationException e) {
return false;
}
@@ -352,7 +358,7 @@ public final class AvdSelector {
* @param manager the AVD manager.
*/
public void setManager(AvdManager manager) {
mManager = manager;
mAvdManager = manager;
}
/**
@@ -595,11 +601,11 @@ public final class AvdSelector {
// get the AVDs
AvdInfo avds[] = null;
if (mManager != null) {
if (mAvdManager != null) {
if (mDisplayMode == DisplayMode.MANAGER) {
avds = mManager.getAllAvds();
avds = mAvdManager.getAllAvds();
} else {
avds = mManager.getValidAvds();
avds = mAvdManager.getValidAvds();
}
}
@@ -647,6 +653,14 @@ public final class AvdSelector {
}
}
private void onNew() {
AvdCreationDialog dlg = new AvdCreationDialog(mTable.getShell(), mAvdManager,
mImageFactory);
if (dlg.open() == Window.OK) {
refresh(false /*reload*/);
}
}
private void onDetails() {
final AvdInfo avdInfo = getSelected();
@@ -683,20 +697,20 @@ public final class AvdSelector {
display);
// delete the AVD
boolean success = mManager.deleteAvd(avdInfo, log);
boolean success = mAvdManager.deleteAvd(avdInfo, log);
// display the result
log.displayResult(success);
if (success) {
refresh(false);
refresh(false /*reload*/);
}
}
/**
* Collects all log from the AVD action and displays it in a dialog.
*/
private class SdkLog implements ISdkLog {
static class SdkLog implements ISdkLog {
final ArrayList<String> logMessages = new ArrayList<String>();
private final String mMessage;
@@ -730,9 +744,8 @@ public final class AvdSelector {
*/
public void displayResult(final boolean success) {
if (logMessages.size() > 0) {
final StringBuilder sb = new StringBuilder(mMessage + "\n");
final StringBuilder sb = new StringBuilder(mMessage + "\n\n");
for (String msg : logMessages) {
sb.append('\n');
sb.append(msg);
}
@@ -754,6 +767,4 @@ public final class AvdSelector {
}
}
}
}