/* | |
* Copyright (C) 2012 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.motorola.studio.android.emulator.device.ui; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.Collection; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Properties; | |
import org.eclipse.core.runtime.Path; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.jface.preference.IPreferenceNode; | |
import org.eclipse.jface.preference.PreferenceDialog; | |
import org.eclipse.jface.preference.PreferenceManager; | |
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.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.DirectoryDialog; | |
import org.eclipse.swt.widgets.FileDialog; | |
import org.eclipse.swt.widgets.Group; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.Link; | |
import org.eclipse.swt.widgets.Text; | |
import org.eclipse.ui.PlatformUI; | |
import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog; | |
import com.android.sdklib.IAndroidTarget; | |
import com.android.sdklib.ISystemImage; | |
import com.android.sdklib.SdkConstants; | |
import com.android.sdklib.internal.avd.AvdInfo; | |
import com.motorola.studio.android.adt.SdkUtils; | |
import com.motorola.studio.android.common.log.StudioLogger; | |
import com.motorola.studio.android.emulator.device.IAndroidDeviceConstants; | |
import com.motorola.studio.android.emulator.device.IDevicePropertiesConstants; | |
import com.motorola.studio.android.emulator.device.definition.AndroidEmuDefMgr; | |
import com.motorola.studio.android.emulator.i18n.EmulatorNLS; | |
/** | |
* DESCRIPTION: | |
* <br> | |
* This class implements the UI for showing all Android Emulator Device Instance main information, | |
* such as its name, description, etc. | |
* <br> | |
* It extends the AbstractPropertiesComposite so as to use its common functionalities. | |
* <br> | |
* RESPONSIBILITY: | |
* <br> | |
* - Show Android Emulator Device Instance main information on the UI | |
* <br> | |
* COLABORATORS: | |
* <br> | |
* AbstractPropertiesComposite: extends this class | |
* <br> | |
* USAGE: | |
* <br> | |
* This class should be added as a regular composite whenever main information on Android Emulator | |
* Device Instance is necessary to be shown and edited on the UI. It can either allow of stop the | |
* editing of the name of the instance, while other information is always editable. | |
*/ | |
//@SuppressWarnings("restriction") | |
@SuppressWarnings("restriction") | |
public class PropertiesMainComposite extends AbstractPropertiesComposite | |
{ | |
private static final String ORG_ECLIPSE_UI_NET_NET_PREFERENCES = | |
"org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$ | |
private final AndroidEmuDefMgr emuDefMgr = AndroidEmuDefMgr.getInstance(); | |
private String name = ""; //$NON-NLS-1$ | |
private String skinId = ""; //$NON-NLS-1$ | |
private String timeout = ""; //$NON-NLS-1$ | |
private boolean useVnc; | |
private boolean useProxy; | |
private boolean useSnapshots; | |
// VM Settings | |
private IAndroidTarget vmTarget = null; | |
private String vmSkin = ""; //$NON-NLS-1$ | |
private String sdCardType = ""; //$NON-NLS-1$ | |
private String sdCardValue = ""; //$NON-NLS-1$ | |
private String vmPath = ""; //$NON-NLS-1$ | |
private boolean usingDefaultVmPath; | |
private String abiType = ""; | |
/* | |
* SD Card | |
*/ | |
private static final String SDCARD_TYPE_NONE = "NONE"; //$NON-NLS-1$ | |
private static final String SDCARD_TYPE_PATH = "PATH"; //$NON-NLS-1$ | |
private static final String SDCARD_TYPE_SIZE = "SIZE"; //$NON-NLS-1$ | |
private static final String SDCARD_PATH_EXTENSION = ".img"; //$NON-NLS-1$ | |
private static final String[] SDCARD_SIZE_UNITS = new String[] | |
{ | |
"KB", "MB" //$NON-NLS-1$ //$NON-NLS-2$ | |
}; | |
private Button saveSnapshotButton; | |
private Button startFromSnapshotButton; | |
private boolean saveSnapshots; | |
private boolean startFromSnapshots; | |
private Combo abiTypeCombo; | |
/** | |
* Creates a PropertiesMainComposite object. | |
* | |
* @param parent the parent composite | |
* @param name the instance name | |
* @param description the instance description | |
* @param emulatorDefId the instance emulator definition id | |
* @param isNameEditable whether the name should be editable or not | |
* @param areOtherFieldsEditable True if the user will be able to edit other data in the composite; false otherwise | |
*/ | |
public PropertiesMainComposite(Composite parent, String name, String emulatorDefId, | |
String timeout, boolean useVnc, boolean useProxy, boolean useSnapshot, | |
boolean saveSnapshot, boolean startFromSnapshot, IAndroidTarget vmTarget, | |
String vmSkin, String vmPath, String abiType, boolean showName, | |
boolean areVmSettingsEditable, boolean areOtherFieldsEditable) | |
{ | |
super(parent); | |
this.name = name; | |
this.timeout = timeout; | |
this.useVnc = useVnc; | |
this.useProxy = useProxy; | |
this.abiType = abiType; | |
skinId = emuDefMgr.getSkinId(emulatorDefId); | |
this.vmTarget = vmTarget; | |
this.vmSkin = vmSkin; | |
this.vmPath = vmPath; | |
this.useSnapshots = useSnapshot; | |
this.saveSnapshots = saveSnapshot; | |
this.startFromSnapshots = startFromSnapshot; | |
createUI(showName, areVmSettingsEditable, areOtherFieldsEditable); | |
//Set context Help (not available yet) | |
PlatformUI.getWorkbench().getHelpSystem() | |
.setHelp(parent, IAndroidDeviceConstants.MAIN_PAGE_HELP); | |
} | |
/** | |
* Creates a PropertiesMainComposite object with instance name editing not allowed. | |
* | |
* @param parent the parent composite | |
* @param name the instance name | |
* @param description the instance description | |
* @param emulatorDefId the instance emulator definition name | |
*/ | |
public PropertiesMainComposite(Composite parent, String emulatorDefId, String timeout, | |
boolean useVnc, boolean useProxy, boolean useSnapshot, boolean saveSnapshot, | |
boolean startFromSnapshot, IAndroidTarget vmTarget, String vmSkin, String vmPath, | |
String abiType) | |
{ | |
this(parent, "", emulatorDefId, timeout, useVnc, useProxy, useSnapshot, saveSnapshot, | |
startFromSnapshot, vmTarget, vmSkin, vmPath, abiType, false, true, true); | |
//Set context Help (not available yet) | |
PlatformUI.getWorkbench().getHelpSystem() | |
.setHelp(parent, IAndroidDeviceConstants.MAIN_PAGE_HELP); | |
} | |
/** | |
* @param showName | |
* @param areVmSettingsEditable | |
* @param areOtherFieldsEditable | |
*/ | |
private void createUI(boolean showName, boolean areVmSettingsEditable, | |
boolean areOtherFieldsEditable) | |
{ | |
GridData data; | |
Composite mainComposite = this; | |
Collection<Control> otherFields = new HashSet<Control>(); | |
setMainLayout(2); | |
if (showName) | |
{ | |
Label nameLabel = new Label(mainComposite, SWT.READ_ONLY); | |
nameLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_NameLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
nameLabel.setLayoutData(data); | |
Text nameTextLabel = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
nameTextLabel.setText(name); | |
data = new GridData(SWT.FILL, SWT.NULL, true, false); | |
nameTextLabel.setLayoutData(data); | |
} | |
/* | |
* (Not) Editable area | |
*/ | |
if (areVmSettingsEditable) | |
{ | |
createEditableVmUI(); | |
} | |
else | |
{ | |
createNotEditableVmUI(); | |
} | |
/* | |
* Emulator proxy settings | |
*/ | |
Group proxyGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
proxyGroup.setText(EmulatorNLS.PropertiesMainComposite_ProxySettings_GroupTitle); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); | |
proxyGroup.setLayoutData(data); | |
proxyGroup.setLayout(new GridLayout(3, false)); | |
final Button proxyChkbox = new Button(proxyGroup, SWT.CHECK); | |
proxyChkbox.setText(EmulatorNLS.PropertiesMainComposite_ProxySettings_CheckboxLabel); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
proxyChkbox.setSelection(useProxy); | |
proxyChkbox.setLayoutData(data); | |
proxyChkbox.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
useProxy = proxyChkbox.getSelection(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
Link networkSettings = new Link(proxyGroup, SWT.NONE); | |
networkSettings.setText(EmulatorNLS.PropertiesMainComposite_ProxySettings_LinkToPreference); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1); | |
networkSettings.setLayoutData(data); | |
networkSettings.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
openNetworkPreferences(); | |
} | |
}); | |
//Snapshot group | |
Group snapshotGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
snapshotGroup.setText(EmulatorNLS.PropertiesMainComposite_SnapshotSettings); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); | |
snapshotGroup.setLayoutData(data); | |
snapshotGroup.setLayout(new GridLayout(3, false)); | |
final Button enableSnapshotButton = new Button(snapshotGroup, SWT.CHECK); | |
enableSnapshotButton.setText(EmulatorNLS.PropertiesMainComposite_UseSnapshot); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
enableSnapshotButton.setLayoutData(data); | |
enableSnapshotButton.setEnabled(areVmSettingsEditable); | |
enableSnapshotButton.setSelection(useSnapshots); | |
enableSnapshotButton.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
useSnapshots = enableSnapshotButton.getSelection(); | |
notifyCompositeChangeListeners(); | |
startFromSnapshotButton.setEnabled(useSnapshots); | |
saveSnapshotButton.setEnabled(useSnapshots); | |
} | |
}); | |
startFromSnapshotButton = new Button(snapshotGroup, SWT.CHECK); | |
startFromSnapshotButton.setText(EmulatorNLS.PropertiesMainComposite_startFromSnapshot); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
startFromSnapshotButton.setLayoutData(data); | |
startFromSnapshotButton.setEnabled(useSnapshots); | |
startFromSnapshotButton.setSelection(startFromSnapshots); | |
startFromSnapshotButton.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
startFromSnapshots = startFromSnapshotButton.getSelection(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
saveSnapshotButton = new Button(snapshotGroup, SWT.CHECK); | |
saveSnapshotButton.setText(EmulatorNLS.PropertiesMainComposite_SaveSnapshot); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
saveSnapshotButton.setLayoutData(data); | |
saveSnapshotButton.setEnabled(useSnapshots); | |
saveSnapshotButton.setSelection(saveSnapshots); | |
saveSnapshotButton.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
saveSnapshots = saveSnapshotButton.getSelection(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
otherFields.add(proxyGroup); | |
otherFields.add(proxyChkbox); | |
otherFields.add(networkSettings); | |
otherFields.add(snapshotGroup); | |
/* | |
* Emulator Window mode area | |
*/ | |
//Only for windows and linux platforms | |
if (!Platform.getOS().equals(Platform.OS_MACOSX)) | |
{ | |
Group windowGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
windowGroup | |
.setText(EmulatorNLS.UI_PropertiesMainComposite_EmulatorWindowMode_GroupTitle); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); | |
windowGroup.setLayoutData(data); | |
windowGroup.setLayout(new GridLayout(3, false)); | |
final Button nativeRadio = new Button(windowGroup, SWT.RADIO); | |
nativeRadio | |
.setText(EmulatorNLS.UI_PropertiesMainComposite_EmulatorWindowMode_NativeLabel); | |
nativeRadio.setSelection(!useVnc); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
nativeRadio.setLayoutData(data); | |
nativeRadio.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
useVnc = !nativeRadio.getSelection(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
final Button vncRadio = new Button(windowGroup, SWT.RADIO); | |
vncRadio.setText(EmulatorNLS.UI_PropertiesMainComposite_EmulatorWindowMode_VncLabel); | |
vncRadio.setSelection(useVnc); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
vncRadio.setLayoutData(data); | |
otherFields.add(windowGroup); | |
otherFields.add(nativeRadio); | |
otherFields.add(vncRadio); | |
} | |
/* | |
* Timeout | |
*/ | |
Label timeoutLabel = new Label(mainComposite, SWT.READ_ONLY); | |
timeoutLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_TimeoutLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
timeoutLabel.setLayoutData(data); | |
final Text timeoutText = new Text(mainComposite, SWT.SINGLE | SWT.BORDER); | |
otherFields.add(timeoutText); | |
timeoutText.setText(timeout); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
timeoutText.setLayoutData(data); | |
timeoutText.addModifyListener(new ModifyListener() | |
{ | |
public void modifyText(ModifyEvent e) | |
{ | |
timeout = timeoutText.getText().trim(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
addInstanceListener(otherFields); | |
updateWidgetEnableStatus(areOtherFieldsEditable, otherFields); | |
} | |
@SuppressWarnings("unchecked") | |
protected void openNetworkPreferences() | |
{ | |
// Makes the network preferences dialog manager | |
PreferenceManager manager = PlatformUI.getWorkbench().getPreferenceManager(); | |
IPreferenceNode networkNode = null; | |
for (IPreferenceNode node : (List<IPreferenceNode>) manager | |
.getElements(PreferenceManager.PRE_ORDER)) | |
{ | |
if (node.getId().equals(ORG_ECLIPSE_UI_NET_NET_PREFERENCES)) | |
{ | |
networkNode = node; | |
break; | |
} | |
} | |
PreferenceManager prefMan = new PreferenceManager(); | |
if (networkNode != null) | |
{ | |
prefMan.addToRoot(networkNode); | |
} | |
PreferenceDialog networkPreferencesDialog = | |
new WorkbenchPreferenceDialog(getShell(), prefMan); | |
networkPreferencesDialog.create(); | |
networkPreferencesDialog.open(); | |
} | |
/** | |
* Creates the not editable UI for the VM settings. | |
*/ | |
private void createNotEditableVmUI() | |
{ | |
GridData data; | |
Composite mainComposite = this; | |
Label tagetLabel = new Label(mainComposite, SWT.READ_ONLY); | |
tagetLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_TargetLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
tagetLabel.setLayoutData(data); | |
final Text targetText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
targetText.setText(vmTarget.getName()); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
targetText.setLayoutData(data); | |
Label abiTypeLabel = new Label(mainComposite, SWT.READ_ONLY); | |
abiTypeLabel.setText(EmulatorNLS.PropertiesMainComposite_ABITypeLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
abiTypeLabel.setLayoutData(data); | |
final Text abiTypeText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
abiTypeText.setText(AvdInfo.getPrettyAbiType(abiType)); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
abiTypeText.setLayoutData(data); | |
Label skinLabel = new Label(mainComposite, SWT.READ_ONLY); | |
skinLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_SkinLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
skinLabel.setLayoutData(data); | |
final Text vmSkinText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
vmSkinText.setText(vmSkin); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
vmSkinText.setLayoutData(data); | |
Label pathLabel = new Label(mainComposite, SWT.READ_ONLY); | |
pathLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_PathLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
pathLabel.setLayoutData(data); | |
final Text pathText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
pathText.setText(vmPath); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
data.widthHint = 100; | |
pathText.setLayoutData(data); | |
/* | |
* SD Card info | |
*/ | |
AvdInfo vmInfo = SdkUtils.getValidVm(name); | |
Properties configFile = new Properties(); | |
BufferedReader input = null; | |
try | |
{ | |
// it's necessary to read the file instead of load the Properties file because | |
// there are "\" in the path, which are removed by the Properties class load method, since | |
// they mean line break in a properties file | |
input = new BufferedReader(new FileReader(vmInfo.getConfigFile())); | |
String line = null; | |
String[] property = null; | |
while ((line = input.readLine()) != null) | |
{ | |
property = line.split("="); //$NON-NLS-1$ | |
if ((property[0] != null) && (property[1] != null)) | |
{ | |
if ((!property[0].equals("")) && (!property[1].equals(""))) //$NON-NLS-1$ //$NON-NLS-2$ | |
{ | |
configFile.put(property[0], property[1]); | |
} | |
} | |
} | |
if (configFile.getProperty(IDevicePropertiesConstants.configSDCardPath) != null) | |
{ | |
Label sdCardPathLabel = new Label(mainComposite, SWT.READ_ONLY); | |
sdCardPathLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardPathLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
sdCardPathLabel.setLayoutData(data); | |
final Text sdCardPathText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
sdCardPathText.setText(configFile | |
.getProperty(IDevicePropertiesConstants.configSDCardPath)); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
data.widthHint = 100; | |
sdCardPathText.setLayoutData(data); | |
} | |
if (configFile.getProperty(IDevicePropertiesConstants.configSDCardSize) != null) | |
{ | |
Label sdCardPathLabel = new Label(mainComposite, SWT.READ_ONLY); | |
sdCardPathLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardSizeLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
sdCardPathLabel.setLayoutData(data); | |
final Text sdCardPathText = new Text(mainComposite, SWT.WRAP | SWT.READ_ONLY); | |
sdCardPathText.setText(configFile | |
.getProperty(IDevicePropertiesConstants.configSDCardSize)); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
sdCardPathText.setLayoutData(data); | |
} | |
} | |
catch (FileNotFoundException e) | |
{ | |
StudioLogger.error("Could not find config file for AVD: " + name); //$NON-NLS-1$ | |
} | |
catch (IOException e) | |
{ | |
StudioLogger.error("Could not read config file for AVD: " + name); //$NON-NLS-1$ | |
} | |
finally | |
{ | |
try | |
{ | |
if (input != null) | |
{ | |
input.close(); | |
} | |
} | |
catch (IOException e) | |
{ | |
StudioLogger.error("Could not close input stream: ", e.getMessage()); //$NON-NLS-1$ | |
} | |
} | |
} | |
/** | |
* Creates the editable UI for the VM settings. | |
*/ | |
private void createEditableVmUI() | |
{ | |
GridData data; | |
Composite mainComposite = this; | |
Label tagetLabel = new Label(mainComposite, SWT.READ_ONLY); | |
tagetLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_TargetLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
tagetLabel.setLayoutData(data); | |
final Combo targetCombo = new Combo(mainComposite, SWT.READ_ONLY); | |
populateTargetCombo(targetCombo); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); | |
targetCombo.setLayoutData(data); | |
Label skinLabel = new Label(mainComposite, SWT.READ_ONLY); | |
skinLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_SkinLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
skinLabel.setLayoutData(data); | |
final Combo vmSkinCombo = new Combo(mainComposite, SWT.READ_ONLY); | |
populateSkinCombo(vmSkinCombo); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); | |
vmSkinCombo.setLayoutData(data); | |
vmSkinCombo.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
if ((vmSkinCombo != null) && !"".equals(vmSkinCombo.getText())) //$NON-NLS-1$ | |
{ | |
vmSkin = (String) vmSkinCombo.getData(vmSkinCombo.getText()); | |
} | |
else | |
{ | |
vmSkin = ""; //$NON-NLS-1$ | |
} | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
Label abiTypeLabel = new Label(mainComposite, SWT.READ_ONLY); | |
abiTypeLabel.setText(EmulatorNLS.PropertiesMainComposite_ABITypeLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
abiTypeLabel.setLayoutData(data); | |
abiTypeCombo = new Combo(mainComposite, SWT.READ_ONLY); | |
populateAbiTypeCombo(abiTypeCombo); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); | |
abiTypeCombo.setLayoutData(data); | |
abiTypeCombo.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
if ((vmSkinCombo != null) && !"".equals(vmSkinCombo.getText())) //$NON-NLS-1$ | |
{ | |
abiType = (String) abiTypeCombo.getData(abiTypeCombo.getText()); | |
} | |
else | |
{ | |
abiType = SdkConstants.ABI_ARMEABI; | |
} | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
targetCombo.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
IAndroidTarget newTarget = null; | |
if ((targetCombo != null) && !"".equals(targetCombo.getText())) //$NON-NLS-1$ | |
{ | |
newTarget = (IAndroidTarget) targetCombo.getData(targetCombo.getText()); | |
} | |
if (newTarget != vmTarget) | |
{ | |
vmTarget = newTarget; | |
populateSkinCombo(vmSkinCombo); | |
populateAbiTypeCombo(abiTypeCombo); | |
notifyCompositeChangeListeners(); | |
} | |
} | |
}); | |
Group vmPathGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
vmPathGroup.setText(EmulatorNLS.UI_PropertiesMainComposite_PathGroupTitle); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); | |
vmPathGroup.setLayoutData(data); | |
vmPathGroup.setLayout(new GridLayout(3, false)); | |
usingDefaultVmPath = vmPath.equals(IDevicePropertiesConstants.defaultVmPath); | |
final Button vmPathCheckbox = new Button(vmPathGroup, SWT.CHECK); | |
vmPathCheckbox.setText(EmulatorNLS.UI_PropertiesMainComposite_UseDefaultPath); | |
vmPathCheckbox.setSelection(usingDefaultVmPath); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
vmPathCheckbox.setLayoutData(data); | |
Label pathLabel = new Label(vmPathGroup, SWT.READ_ONLY); | |
pathLabel.setText(EmulatorNLS.UI_PropertiesMainComposite_PathLabel); | |
data = new GridData(SWT.LEFT, SWT.CENTER, false, false); | |
pathLabel.setLayoutData(data); | |
final Text pathText = new Text(vmPathGroup, SWT.SINGLE | SWT.BORDER); | |
pathText.setText(vmPath); | |
pathText.setEnabled(!usingDefaultVmPath); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
data.widthHint = 100; | |
pathText.setLayoutData(data); | |
final Button pathBrowseButton = new Button(vmPathGroup, SWT.PUSH); | |
pathBrowseButton.setText(EmulatorNLS.UI_General_BrowseButtonLabel); | |
pathBrowseButton.setEnabled(!usingDefaultVmPath); | |
data = new GridData(SWT.FILL, SWT.FILL, false, false); | |
pathBrowseButton.setLayoutData(data); | |
vmPathCheckbox.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
usingDefaultVmPath = vmPathCheckbox.getSelection(); | |
pathText.setEnabled(!usingDefaultVmPath); | |
pathBrowseButton.setEnabled(!usingDefaultVmPath); | |
if (usingDefaultVmPath) | |
{ | |
vmPath = IDevicePropertiesConstants.defaultVmPath; | |
} | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
pathText.addModifyListener(new ModifyListener() | |
{ | |
public void modifyText(ModifyEvent e) | |
{ | |
vmPath = pathText.getText().trim(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
pathBrowseButton.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
DirectoryDialog dirDialog = new DirectoryDialog(getShell(), SWT.OPEN); | |
if (!vmPath.trim().equals("")) //$NON-NLS-1$ | |
{ | |
dirDialog.setFilterPath(vmPath); | |
} | |
else | |
{ | |
dirDialog.setFilterPath("/"); //$NON-NLS-1$ | |
} | |
dirDialog.setText(EmulatorNLS.UI_PropertiesMainComposite_PathGroupTitle); | |
String vmPath = dirDialog.open(); | |
if (vmPath != null) | |
{ | |
pathText.setText(vmPath); | |
notifyCompositeChangeListeners(); | |
} | |
} | |
}); | |
/* | |
* SD Card Area | |
*/ | |
sdCardType = SDCARD_TYPE_NONE; | |
Group sdCardGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
sdCardGroup.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardLabel); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); | |
sdCardGroup.setLayoutData(data); | |
sdCardGroup.setLayout(new GridLayout(3, false)); | |
// none | |
final Button noneSDCardCheckbox = new Button(sdCardGroup, SWT.RADIO); | |
noneSDCardCheckbox.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardNoneLabel); | |
noneSDCardCheckbox.setSelection(true); | |
data = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1); | |
noneSDCardCheckbox.setLayoutData(data); | |
noneSDCardCheckbox.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
sdCardType = SDCARD_TYPE_NONE; | |
sdCardValue = ""; //$NON-NLS-1$ | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
// existing | |
final Button existingSDCardCheckbox = new Button(sdCardGroup, SWT.RADIO); | |
existingSDCardCheckbox.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardExistingLabel); | |
final Text existingSDCardPath = new Text(sdCardGroup, SWT.SINGLE | SWT.BORDER); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
data.widthHint = 100; | |
existingSDCardPath.setLayoutData(data); | |
existingSDCardPath.setEnabled(false); | |
final Button existingSDCardButton = new Button(sdCardGroup, SWT.PUSH); | |
existingSDCardButton.setText(EmulatorNLS.UI_General_BrowseButtonLabel); | |
data = new GridData(SWT.FILL, SWT.FILL, false, false); | |
existingSDCardButton.setLayoutData(data); | |
existingSDCardButton.setEnabled(false); | |
existingSDCardCheckbox.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
sdCardType = SDCARD_TYPE_PATH; | |
existingSDCardPath.setEnabled(existingSDCardCheckbox.getSelection()); | |
existingSDCardButton.setEnabled(existingSDCardCheckbox.getSelection()); | |
sdCardValue = existingSDCardPath.getText(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
existingSDCardPath.addModifyListener(new ModifyListener() | |
{ | |
public void modifyText(ModifyEvent e) | |
{ | |
sdCardValue = existingSDCardPath.getText(); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
existingSDCardButton.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
String selectedPath = null; | |
FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN); | |
String[] filterExtensions = | |
{ | |
"*" + SDCARD_PATH_EXTENSION //$NON-NLS-1$ | |
}; | |
fileDialog.setFilterExtensions(filterExtensions); | |
selectedPath = fileDialog.open(); | |
if (selectedPath != null) | |
{ | |
existingSDCardPath.setText(selectedPath); | |
} | |
} | |
}); | |
// new | |
final Button newSDCardCheckbox = new Button(sdCardGroup, SWT.RADIO); | |
newSDCardCheckbox.setText(EmulatorNLS.UI_PropertiesMainComposite_SDCardNewLabel); | |
final Text newSDCardSize = new Text(sdCardGroup, SWT.SINGLE | SWT.BORDER); | |
data = new GridData(SWT.FILL, SWT.TOP, true, false); | |
data.widthHint = 100; | |
newSDCardSize.setLayoutData(data); | |
newSDCardSize.setEnabled(false); | |
final Combo newSDCardUnit = new Combo(sdCardGroup, SWT.READ_ONLY); | |
for (String unit : SDCARD_SIZE_UNITS) | |
{ | |
newSDCardUnit.add(unit); | |
} | |
newSDCardUnit.select(0); | |
newSDCardUnit.setEnabled(false); | |
data = new GridData(SWT.FILL, SWT.FILL, false, false); | |
newSDCardUnit.setLayoutData(data); | |
newSDCardCheckbox.addSelectionListener(new SelectionAdapter() | |
{ | |
@Override | |
public void widgetSelected(SelectionEvent e) | |
{ | |
sdCardType = SDCARD_TYPE_SIZE; | |
sdCardValue = newSDCardSize.getText(); | |
newSDCardSize.setEnabled(newSDCardCheckbox.getSelection()); | |
newSDCardUnit.setEnabled(newSDCardCheckbox.getSelection()); | |
sdCardValue = newSDCardSize.getText() + newSDCardUnit.getText().charAt(0); | |
notifyCompositeChangeListeners(); | |
} | |
}); | |
ModifyListener newSDCardListener = new ModifyListener() | |
{ | |
public void modifyText(ModifyEvent e) | |
{ | |
sdCardValue = newSDCardSize.getText() + newSDCardUnit.getText().charAt(0); | |
notifyCompositeChangeListeners(); | |
} | |
}; | |
newSDCardSize.addModifyListener(newSDCardListener); | |
newSDCardUnit.addModifyListener(newSDCardListener); | |
} | |
private void populateAbiTypeCombo(Combo abiTypeCombo) | |
{ | |
// System Images represents the ABI types | |
ISystemImage[] images = vmTarget.getSystemImages(); | |
// in case no images are found, get try its parent | |
if ((images == null) || ((images.length == 0) && !vmTarget.isPlatform())) | |
{ | |
images = vmTarget.getParent().getSystemImages(); | |
} | |
// always clean abi combo since it will be reloaded | |
abiTypeCombo.removeAll(); | |
int i = 0; | |
if ((images != null) && (images.length > 0)) | |
{ | |
for (ISystemImage image : images) | |
{ | |
String prettyAbiName = AvdInfo.getPrettyAbiType(image.getAbiType()); | |
abiTypeCombo.add(prettyAbiName); | |
abiTypeCombo.setData(prettyAbiName, image.getAbiType()); | |
if (image.getAbiType().equals(abiType)) | |
{ | |
abiTypeCombo.select(i); | |
} | |
i++; | |
} | |
if (abiTypeCombo.getSelectionIndex() == -1) | |
{ | |
abiTypeCombo.select(0); | |
abiType = (String) abiTypeCombo.getData(abiTypeCombo.getItem(0)); | |
} | |
} | |
} | |
/** | |
* Populate VM Target combo box. | |
* | |
* @param targetCombo | |
*/ | |
private void populateTargetCombo(Combo targetCombo) | |
{ | |
IAndroidTarget[] targets = SdkUtils.getAllTargets(); | |
if ((targets != null) && (targets.length > 0)) | |
{ | |
for (int i = 0; i < targets.length; i++) | |
{ | |
String label = | |
targets[i].isPlatform() ? targets[i].getName() : targets[i].getName() | |
+ " (" + targets[i].getParent().getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ | |
targetCombo.add(label); | |
targetCombo.setData(label, targets[i]); | |
if (targets[i].getName().equals(vmTarget.getName())) | |
{ | |
targetCombo.select(i); | |
} | |
} | |
} | |
//Set context Help (not available yet) | |
PlatformUI.getWorkbench().getHelpSystem() | |
.setHelp(this, IAndroidDeviceConstants.MAIN_PAGE_HELP); | |
} | |
/** | |
* Populate VM Skin combo box. | |
* | |
* @param skinCombo | |
*/ | |
private void populateSkinCombo(Combo skinCombo) | |
{ | |
skinCombo.removeAll(); | |
skinCombo.clearSelection(); | |
if (vmTarget != null) | |
{ | |
String[] skins = vmTarget.getSkins(); | |
String defaultSkin = vmTarget.getDefaultSkin(); | |
for (int i = 0; i < skins.length; i++) | |
{ | |
skinCombo.add(skins[i]); | |
skinCombo.setData(skins[i], skins[i]); | |
if (skins[i].equals(defaultSkin)) | |
{ | |
skinCombo.select(i); | |
vmSkin = defaultSkin; | |
} | |
} | |
// if there is no selection, select the first | |
if (skinCombo.getSelectionIndex() < 0) | |
{ | |
if (skinCombo.getItemCount() > 0) | |
{ | |
skinCombo.select(0); | |
vmSkin = skinCombo.getItem(0); | |
} | |
} | |
skinCombo.setEnabled(true); | |
} | |
else | |
{ | |
skinCombo.setEnabled(false); | |
} | |
//Set context Help (not available yet) | |
PlatformUI.getWorkbench().getHelpSystem() | |
.setHelp(this, IAndroidDeviceConstants.MAIN_PAGE_HELP); | |
} | |
public String getSkinId() | |
{ | |
return skinId; | |
} | |
/** | |
* Retrieves the timeout. | |
* | |
* @return the timeout | |
*/ | |
public String getTimeout() | |
{ | |
return timeout; | |
} | |
public String getUseVnc() | |
{ | |
return (useVnc ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); //$NON-NLS-1$ //$NON-NLS-2$ | |
} | |
public String getUseProxy() | |
{ | |
return (useProxy ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); //$NON-NLS-1$ //$NON-NLS-2$ | |
} | |
/** | |
* Retrieves the error message associated to this composites current state. | |
* The order of precedence of error is the same as the fields displayed on the | |
* UI, which means errors on fields drawn first are shown with a higher precedence | |
* than the errors of fields drawn last. | |
* The instance description field is the only non required field. | |
* | |
* @return the error message, or <code>null</code> if there are no errors | |
*/ | |
@Override | |
public String getErrorMessage() | |
{ | |
String errorMessage = null; | |
// VM Settings Check | |
if ("".equals(vmTarget)) //$NON-NLS-1$ | |
{ | |
//Check if Target isn't empty | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_VmTargetEmpty; | |
} | |
else if ("".equals(vmSkin)) //$NON-NLS-1$ | |
{ | |
//Check if Skin isn't empty | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_VmSkinEmpty; | |
} | |
else | |
{ | |
if (!usingDefaultVmPath) | |
{ | |
//Check if Path is valid ("" is valid too) | |
File vmPathLocation = new File(vmPath); | |
if ((!vmPathLocation.exists()) || (!vmPathLocation.isDirectory())) | |
{ | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_VmPathInvalid; | |
} | |
} | |
} | |
//ABI Type | |
if (errorMessage == null) | |
{ | |
if ((abiTypeCombo != null) | |
&& ((abiTypeCombo.getItemCount() == 0) || (abiTypeCombo.getSelectionIndex() == -1))) //$NON-NLS-1$ | |
{ | |
//no item available or not ABI selected | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_ABINotAvailable; | |
} | |
} | |
// SD Card | |
if (errorMessage == null) | |
{ | |
if (sdCardType.equalsIgnoreCase(SDCARD_TYPE_PATH)) | |
{ | |
if (sdCardValue == null) //$NON-NLS-1$ | |
{ | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_MissingSDCardPath; | |
} | |
else if (!isValidSDCard(sdCardValue)) | |
{ | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_SDCardPathIsNotValid; | |
} | |
} | |
else if (sdCardType.equalsIgnoreCase(SDCARD_TYPE_SIZE)) | |
{ | |
int sdcardSize = -1; | |
String unit = | |
sdCardValue.length() > 0 ? sdCardValue.substring(sdCardValue.length() - 1) | |
.toLowerCase() : "k"; //$NON-NLS-1$ | |
if ((sdCardValue == null) || (sdCardValue.equals(""))) //$NON-NLS-1$ | |
{ | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_MissingSDCardSize; | |
} | |
else | |
{ | |
try | |
{ | |
sdcardSize = | |
Integer.parseInt(sdCardValue.substring(0, sdCardValue.length() - 1)); | |
} | |
catch (NumberFormatException e) | |
{ | |
//do nothing | |
} | |
if ((unit.equals("m") && (sdcardSize < 9)) //$NON-NLS-1$ | |
|| (unit.equals("k") && (sdcardSize < (9 * 1024)))) //$NON-NLS-1$ | |
{ | |
errorMessage = | |
EmulatorNLS.ERR_PropertiesMainComposite_SDCardSizeIsNotPositiveInteger; | |
} | |
} | |
} | |
} | |
//Timeout | |
if (errorMessage == null) | |
{ | |
if (timeout.equals("")) //$NON-NLS-1$ | |
{ | |
errorMessage = EmulatorNLS.ERR_PropertiesMainComposite_MissingTimeoutValue; | |
} | |
else | |
{ | |
if (!isPositiveInteger(timeout)) | |
{ | |
errorMessage = | |
EmulatorNLS.ERR_PropertiesMainComposite_TimeoutValueIsNotPositiveInteger; | |
} | |
} | |
} | |
return errorMessage; | |
} | |
/** | |
* Check if a string is a valid SD Card Path | |
* | |
* @param text the string to be analyzed | |
* @return true if the string is a valid SD Card path, false otherwise | |
*/ | |
private boolean isValidSDCard(String text) | |
{ | |
boolean result = true; | |
File file = new File(text); | |
if ((!file.exists()) || (file.isDirectory()) | |
|| (!SDCARD_PATH_EXTENSION.equals("." + (new Path(text)).getFileExtension()))) //$NON-NLS-1$ | |
{ | |
result = false; | |
} | |
return result; | |
} | |
/** | |
* Check if a string is a positive integer | |
* | |
* @param text the string to be analyzed | |
* @return true if the string is a positive integer, false otherwise | |
*/ | |
private boolean isPositiveInteger(String text) | |
{ | |
int intValue = 0; | |
boolean isPositive = true; | |
try | |
{ | |
intValue = Integer.parseInt(text); | |
} | |
catch (NumberFormatException e) | |
{ | |
isPositive = false; | |
} | |
if (intValue <= 0) | |
{ | |
isPositive = false; | |
} | |
return isPositive; | |
} | |
/** | |
* Retrieves the VM Target. | |
* | |
* @return the vmTarget | |
*/ | |
public IAndroidTarget getVmTarget() | |
{ | |
return vmTarget; | |
} | |
/** | |
* Retrieves the Abi Type. | |
* | |
* @return the VM Abi Type | |
*/ | |
public String getAbiType() | |
{ | |
return abiType != null ? abiType : SdkConstants.ABI_ARMEABI; | |
} | |
/** | |
* Retrieves the VM Skin. | |
* | |
* @return the vmSkin | |
*/ | |
public String getVmSkin() | |
{ | |
return vmSkin; | |
} | |
/** | |
* Retrieves the VM Path. | |
* | |
* @return the vmPath | |
*/ | |
public String getVmPath() | |
{ | |
return vmPath + File.separator + name + IDevicePropertiesConstants.defaultVmFolderSuffix; | |
} | |
/** | |
* Retrieves the SD Card info | |
* | |
* @return the sdCard | |
*/ | |
public String getSDCard() | |
{ | |
return sdCardValue; | |
} | |
/** | |
* Set the name of the AVD | |
* @param name: a not null String with the name of the AVD | |
*/ | |
public void setName(String name) | |
{ | |
this.name = name == null ? "" : name; //$NON-NLS-1$ | |
} | |
/** | |
* @return | |
*/ | |
public String getUseSnapshot() | |
{ | |
return (useSnapshots ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); | |
} | |
/** | |
* @return | |
*/ | |
public String getstartFromSnapshot() | |
{ | |
return (startFromSnapshots ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); | |
} | |
/** | |
* @return | |
*/ | |
public String getSaveSnapshot() | |
{ | |
return (saveSnapshots ? Boolean.TRUE.toString() : Boolean.FALSE.toString()); | |
} | |
} |