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