• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.adt.internal.launch;
18 
19 import com.android.ide.eclipse.adt.AdtPlugin;
20 import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchConfiguration.TargetMode;
21 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
22 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
23 import com.android.ide.eclipse.ddms.DdmsPlugin;
24 import com.android.prefs.AndroidLocation.AndroidLocationException;
25 import com.android.sdklib.IAndroidTarget;
26 import com.android.sdklib.NullSdkLog;
27 import com.android.sdklib.internal.avd.AvdManager;
28 import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
29 import com.android.sdkuilib.internal.widgets.AvdSelector;
30 import com.android.sdkuilib.internal.widgets.AvdSelector.DisplayMode;
31 
32 import org.eclipse.core.resources.IProject;
33 import org.eclipse.core.runtime.CoreException;
34 import org.eclipse.debug.core.ILaunchConfiguration;
35 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
36 import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
37 import org.eclipse.jdt.core.IJavaProject;
38 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
39 import org.eclipse.jface.preference.IPreferenceStore;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.events.ModifyEvent;
42 import org.eclipse.swt.events.ModifyListener;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.graphics.Font;
46 import org.eclipse.swt.graphics.Image;
47 import org.eclipse.swt.layout.GridData;
48 import org.eclipse.swt.layout.GridLayout;
49 import org.eclipse.swt.widgets.Button;
50 import org.eclipse.swt.widgets.Combo;
51 import org.eclipse.swt.widgets.Composite;
52 import org.eclipse.swt.widgets.Group;
53 import org.eclipse.swt.widgets.Label;
54 import org.eclipse.swt.widgets.Text;
55 
56 /**
57  * Launch configuration tab to control the parameters of the Emulator
58  */
59 public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
60 
61     private final static String[][] NETWORK_SPEEDS = new String[][] {
62         { "Full", "full" }, //$NON-NLS-2$
63         { "GSM", "gsm" }, //$NON-NLS-2$
64         { "HSCSD", "hscsd" }, //$NON-NLS-2$
65         { "GPRS", "gprs" }, //$NON-NLS-2$
66         { "EDGE", "edge" }, //$NON-NLS-2$
67         { "UMTS", "umts" }, //$NON-NLS-2$
68         { "HSPDA", "hsdpa" }, //$NON-NLS-2$
69     };
70 
71     private final static String[][] NETWORK_LATENCIES = new String[][] {
72         { "None", "none" }, //$NON-NLS-2$
73         { "GPRS", "gprs" }, //$NON-NLS-2$
74         { "EDGE", "edge" }, //$NON-NLS-2$
75         { "UMTS", "umts" }, //$NON-NLS-2$
76     };
77 
78     private Button mAutoTargetButton;
79     private Button mManualTargetButton;
80 
81     private AvdSelector mPreferredAvdSelector;
82 
83     private Combo mSpeedCombo;
84 
85     private Combo mDelayCombo;
86 
87     private Group mEmulatorOptionsGroup;
88 
89     private Text mEmulatorCLOptions;
90 
91     private Button mWipeDataButton;
92 
93     private Button mNoBootAnimButton;
94 
95     private Label mPreferredAvdLabel;
96 
97     private IAndroidTarget mProjectTarget;
98 
99     /**
100      * Returns the emulator ready speed option value.
101      * @param value The index of the combo selection.
102      */
getSpeed(int value)103     public static String getSpeed(int value) {
104         try {
105             return NETWORK_SPEEDS[value][1];
106         } catch (ArrayIndexOutOfBoundsException e) {
107             return NETWORK_SPEEDS[LaunchConfigDelegate.DEFAULT_SPEED][1];
108         }
109     }
110 
111     /**
112      * Returns the emulator ready network latency value.
113      * @param value The index of the combo selection.
114      */
getDelay(int value)115     public static String getDelay(int value) {
116         try {
117             return NETWORK_LATENCIES[value][1];
118         } catch (ArrayIndexOutOfBoundsException e) {
119             return NETWORK_LATENCIES[LaunchConfigDelegate.DEFAULT_DELAY][1];
120         }
121     }
122 
123     /**
124      *
125      */
EmulatorConfigTab()126     public EmulatorConfigTab() {
127     }
128 
129     /* (non-Javadoc)
130      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
131      */
createControl(Composite parent)132     public void createControl(Composite parent) {
133         Font font = parent.getFont();
134 
135         // reload the AVDs to make sure we are up to date
136         try {
137             Sdk.getCurrent().getAvdManager().reloadAvds(NullSdkLog.getLogger());
138         } catch (AndroidLocationException e1) {
139             // this happens if the AVD Manager failed to find the folder in which the AVDs are
140             // stored. There isn't much we can do at this point.
141         }
142 
143         Composite topComp = new Composite(parent, SWT.NONE);
144         setControl(topComp);
145         GridLayout topLayout = new GridLayout();
146         topLayout.numColumns = 1;
147         topLayout.verticalSpacing = 0;
148         topComp.setLayout(topLayout);
149         topComp.setFont(font);
150 
151         GridData gd;
152         GridLayout layout;
153 
154         // radio button for the target mode
155         Group targetModeGroup = new Group(topComp, SWT.NONE);
156         targetModeGroup.setText("Deployment Target Selection Mode");
157         gd = new GridData(GridData.FILL_HORIZONTAL);
158         targetModeGroup.setLayoutData(gd);
159         layout = new GridLayout();
160         layout.numColumns = 1;
161         targetModeGroup.setLayout(layout);
162         targetModeGroup.setFont(font);
163 
164         mManualTargetButton = new Button(targetModeGroup, SWT.RADIO);
165         mManualTargetButton.setText("Manual");
166         // Since there are only 2 radio buttons, we can put a listener on only one (they
167         // are both called on select and unselect event.
168 
169         // add the radio button
170         mAutoTargetButton = new Button(targetModeGroup, SWT.RADIO);
171         mAutoTargetButton.setText("Automatic");
172         mAutoTargetButton.setSelection(true);
173         mAutoTargetButton.addSelectionListener(new SelectionAdapter() {
174             // called when selection changes
175             @Override
176             public void widgetSelected(SelectionEvent e) {
177                 updateLaunchConfigurationDialog();
178 
179                 boolean auto = mAutoTargetButton.getSelection();
180                 mPreferredAvdSelector.setEnabled(auto);
181                 mPreferredAvdLabel.setEnabled(auto);
182             }
183         });
184 
185         Composite offsetComp = new Composite(targetModeGroup, SWT.NONE);
186         offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
187         layout = new GridLayout(1, false);
188         layout.marginRight = layout.marginHeight = 0;
189         layout.marginLeft = 30;
190         offsetComp.setLayout(layout);
191 
192         mPreferredAvdLabel = new Label(offsetComp, SWT.NONE);
193         mPreferredAvdLabel.setText("Select a preferred Android Virtual Device for deployment:");
194 
195         // create the selector with no manager, we'll reset the manager every time this is
196         // displayed to ensure we have the latest one (dialog is reused but SDK could have
197         // been changed in between.
198         mPreferredAvdSelector = new AvdSelector(offsetComp,
199                 Sdk.getCurrent().getSdkLocation(),
200                 null /* avd manager */,
201                 DisplayMode.SIMPLE_CHECK);
202         mPreferredAvdSelector.setTableHeightHint(100);
203         mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
204             @Override
205             public void widgetSelected(SelectionEvent e) {
206                 updateLaunchConfigurationDialog();
207             }
208         });
209 
210         // emulator size
211         mEmulatorOptionsGroup = new Group(topComp, SWT.NONE);
212         mEmulatorOptionsGroup.setText("Emulator launch parameters:");
213         mEmulatorOptionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
214         layout = new GridLayout();
215         layout.numColumns = 2;
216         mEmulatorOptionsGroup.setLayout(layout);
217         mEmulatorOptionsGroup.setFont(font);
218 
219         // network options
220         new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Speed:");
221 
222         mSpeedCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY);
223         for (String[] speed : NETWORK_SPEEDS) {
224             mSpeedCombo.add(speed[0]);
225         }
226         mSpeedCombo.addSelectionListener(new SelectionAdapter() {
227             // called when selection changes
228             @Override
229             public void widgetSelected(SelectionEvent e) {
230                 updateLaunchConfigurationDialog();
231             }
232         });
233         mSpeedCombo.pack();
234 
235         new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Latency:");
236 
237         mDelayCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY);
238 
239         for (String[] delay : NETWORK_LATENCIES) {
240             mDelayCombo.add(delay[0]);
241         }
242         mDelayCombo.addSelectionListener(new SelectionAdapter() {
243             // called when selection changes
244             @Override
245             public void widgetSelected(SelectionEvent e) {
246                 updateLaunchConfigurationDialog();
247             }
248         });
249         mDelayCombo.pack();
250 
251         // wipe data option
252         mWipeDataButton = new Button(mEmulatorOptionsGroup, SWT.CHECK);
253         mWipeDataButton.setText("Wipe User Data");
254         mWipeDataButton.setToolTipText("Check this if you want to wipe your user data each time you start the emulator. You will be prompted for confirmation when the emulator starts.");
255         gd = new GridData(GridData.FILL_HORIZONTAL);
256         gd.horizontalSpan = 2;
257         mWipeDataButton.setLayoutData(gd);
258         mWipeDataButton.addSelectionListener(new SelectionAdapter() {
259             @Override
260             public void widgetSelected(SelectionEvent e) {
261                 updateLaunchConfigurationDialog();
262             }
263         });
264 
265         // no boot anim option
266         mNoBootAnimButton = new Button(mEmulatorOptionsGroup, SWT.CHECK);
267         mNoBootAnimButton.setText("Disable Boot Animation");
268         mNoBootAnimButton.setToolTipText("Check this if you want to disable the boot animation. This can help the emulator start faster on slow machines.");
269         gd = new GridData(GridData.FILL_HORIZONTAL);
270         gd.horizontalSpan = 2;
271         mNoBootAnimButton.setLayoutData(gd);
272         mNoBootAnimButton.addSelectionListener(new SelectionAdapter() {
273             @Override
274             public void widgetSelected(SelectionEvent e) {
275                 updateLaunchConfigurationDialog();
276             }
277         });
278 
279         // custom command line option for emulator
280         Label l = new Label(mEmulatorOptionsGroup, SWT.NONE);
281         l.setText("Additional Emulator Command Line Options");
282         gd = new GridData(GridData.FILL_HORIZONTAL);
283         gd.horizontalSpan = 2;
284         l.setLayoutData(gd);
285 
286         mEmulatorCLOptions = new Text(mEmulatorOptionsGroup, SWT.BORDER);
287         gd = new GridData(GridData.FILL_HORIZONTAL);
288         gd.horizontalSpan = 2;
289         mEmulatorCLOptions.setLayoutData(gd);
290         mEmulatorCLOptions.addModifyListener(new ModifyListener() {
291             public void modifyText(ModifyEvent e) {
292                 updateLaunchConfigurationDialog();
293             }
294         });
295     }
296 
297     /* (non-Javadoc)
298      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
299      */
getName()300     public String getName() {
301         return "Target";
302     }
303 
304     @Override
getImage()305     public Image getImage() {
306         return DdmsPlugin.getImageLoader().loadImage("emulator.png", null); //$NON-NLS-1$
307     }
308 
309 
updateAvdList(AvdManager avdManager)310     private void updateAvdList(AvdManager avdManager) {
311         if (avdManager == null) {
312             avdManager = Sdk.getCurrent().getAvdManager();
313         }
314 
315         mPreferredAvdSelector.setManager(avdManager);
316         mPreferredAvdSelector.setFilter(mProjectTarget);
317         mPreferredAvdSelector.refresh(false);
318     }
319 
320     /* (non-Javadoc)
321      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
322      */
initializeFrom(ILaunchConfiguration configuration)323     public void initializeFrom(ILaunchConfiguration configuration) {
324         AvdManager avdManager = Sdk.getCurrent().getAvdManager();
325 
326         TargetMode mode = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == automatic
327         try {
328             mode = TargetMode.getMode(configuration.getAttribute(
329                     LaunchConfigDelegate.ATTR_TARGET_MODE, mode.getValue()));
330         } catch (CoreException e) {
331             // let's not do anything here, we'll use the default value
332         }
333         mAutoTargetButton.setSelection(mode.getValue());
334         mManualTargetButton.setSelection(!mode.getValue());
335 
336         // look for the project name to get its target.
337         String stringValue = "";
338         try {
339             stringValue = configuration.getAttribute(
340                     IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, stringValue);
341         } catch (CoreException ce) {
342             // let's not do anything here, we'll use the default value
343         }
344 
345         IProject project = null;
346 
347         // get the list of existing Android projects from the workspace.
348         IJavaProject[] projects = BaseProjectHelper.getAndroidProjects();
349         if (projects != null) {
350             // look for the project whose name we read from the configuration.
351             for (IJavaProject p : projects) {
352                 if (p.getElementName().equals(stringValue)) {
353                     project = p.getProject();
354                     break;
355                 }
356             }
357         }
358 
359         // update the AVD list
360         if (project != null) {
361             mProjectTarget = Sdk.getCurrent().getTarget(project);
362         }
363 
364         updateAvdList(avdManager);
365 
366         stringValue = "";
367         try {
368             stringValue = configuration.getAttribute(LaunchConfigDelegate.ATTR_AVD_NAME,
369                     stringValue);
370         } catch (CoreException e) {
371             // let's not do anything here, we'll use the default value
372         }
373 
374         if (stringValue != null && stringValue.length() > 0 && avdManager != null) {
375             AvdInfo targetAvd = avdManager.getAvd(stringValue, true /*validAvdOnly*/);
376             mPreferredAvdSelector.setSelection(targetAvd);
377         } else {
378             mPreferredAvdSelector.setSelection(null);
379         }
380 
381         boolean value = LaunchConfigDelegate.DEFAULT_WIPE_DATA;
382         try {
383             value = configuration.getAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA, value);
384         } catch (CoreException e) {
385             // let's not do anything here, we'll use the default value
386         }
387         mWipeDataButton.setSelection(value);
388 
389         value = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM;
390         try {
391             value = configuration.getAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM, value);
392         } catch (CoreException e) {
393             // let's not do anything here, we'll use the default value
394         }
395         mNoBootAnimButton.setSelection(value);
396 
397         int index = -1;
398 
399         index = LaunchConfigDelegate.DEFAULT_SPEED;
400         try {
401             index = configuration.getAttribute(LaunchConfigDelegate.ATTR_SPEED,
402                     index);
403         } catch (CoreException e) {
404             // let's not do anything here, we'll use the default value
405         }
406         if (index == -1) {
407             mSpeedCombo.clearSelection();
408         } else {
409             mSpeedCombo.select(index);
410         }
411 
412         index = LaunchConfigDelegate.DEFAULT_DELAY;
413         try {
414             index = configuration.getAttribute(LaunchConfigDelegate.ATTR_DELAY,
415                     index);
416         } catch (CoreException e) {
417             // let's not do anything here, we'll put a proper value in
418             // performApply anyway
419         }
420         if (index == -1) {
421             mDelayCombo.clearSelection();
422         } else {
423             mDelayCombo.select(index);
424         }
425 
426         String commandLine = null;
427         try {
428             commandLine = configuration.getAttribute(
429                     LaunchConfigDelegate.ATTR_COMMANDLINE, ""); //$NON-NLS-1$
430         } catch (CoreException e) {
431             // let's not do anything here, we'll use the default value
432         }
433         if (commandLine != null) {
434             mEmulatorCLOptions.setText(commandLine);
435         }
436     }
437 
438     /* (non-Javadoc)
439      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
440      */
performApply(ILaunchConfigurationWorkingCopy configuration)441     public void performApply(ILaunchConfigurationWorkingCopy configuration) {
442         configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
443                 mAutoTargetButton.getSelection());
444         AvdInfo avd = mPreferredAvdSelector.getSelected();
445         if (avd != null) {
446             configuration.setAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, avd.getName());
447         } else {
448             configuration.setAttribute(LaunchConfigDelegate.ATTR_AVD_NAME, (String)null);
449         }
450         configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
451                 mSpeedCombo.getSelectionIndex());
452         configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
453                 mDelayCombo.getSelectionIndex());
454         configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE,
455                 mEmulatorCLOptions.getText());
456         configuration.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
457                 mWipeDataButton.getSelection());
458         configuration.setAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
459                 mNoBootAnimButton.getSelection());
460    }
461 
462     /* (non-Javadoc)
463      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
464      */
setDefaults(ILaunchConfigurationWorkingCopy configuration)465     public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
466         configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
467                 LaunchConfigDelegate.DEFAULT_TARGET_MODE.getValue());
468         configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED,
469                 LaunchConfigDelegate.DEFAULT_SPEED);
470         configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY,
471                 LaunchConfigDelegate.DEFAULT_DELAY);
472         configuration.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA,
473                 LaunchConfigDelegate.DEFAULT_WIPE_DATA);
474         configuration.setAttribute(LaunchConfigDelegate.ATTR_NO_BOOT_ANIM,
475                 LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM);
476 
477         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
478         String emuOptions = store.getString(AdtPlugin.PREFS_EMU_OPTIONS);
479         configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE, emuOptions);
480    }
481 }
482