FileDocCategorySizeDatePackage
DeviceChooserDialog.javaAPI DocAndroid 1.5 API27228Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.adt.launch

DeviceChooserDialog

public class DeviceChooserDialog extends org.eclipse.jface.dialogs.Dialog implements com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener
A dialog that lets the user choose a device to deploy an application. The user can either choose an exiting running device (including running emulators) or start a new emulator using an Android Virtual Device configuration that matches the current project.

Fields Summary
private static final int
ICON_WIDTH
private static final String
PREFS_COL_SERIAL
private static final String
PREFS_COL_STATE
private static final String
PREFS_COL_AVD
private static final String
PREFS_COL_TARGET
private static final String
PREFS_COL_DEBUG
private org.eclipse.swt.widgets.Table
mDeviceTable
private org.eclipse.jface.viewers.TableViewer
mViewer
private com.android.sdkuilib.AvdSelector
mPreferredAvdSelector
private org.eclipse.swt.graphics.Image
mDeviceImage
private org.eclipse.swt.graphics.Image
mEmulatorImage
private org.eclipse.swt.graphics.Image
mMatchImage
private org.eclipse.swt.graphics.Image
mNoMatchImage
private org.eclipse.swt.graphics.Image
mWarningImage
private final DeviceChooserResponse
mResponse
private final String
mPackageName
private final com.android.sdklib.IAndroidTarget
mProjectTarget
private final com.android.ide.eclipse.adt.sdk.Sdk
mSdk
private final com.android.sdklib.avd.AvdManager.AvdInfo[]
mFullAvdList
private org.eclipse.swt.widgets.Button
mDeviceRadioButton
private boolean
mDisableAvdSelectionChange
Constructors Summary
public DeviceChooserDialog(org.eclipse.swt.widgets.Shell parent, DeviceChooserResponse response, String packageName, com.android.sdklib.IAndroidTarget projectTarget)

        super(parent);
        mResponse = response;
        mPackageName = packageName;
        mProjectTarget = projectTarget;
        mSdk = Sdk.getCurrent();
        
        // get the full list of Android Virtual Devices
        AvdManager avdManager = mSdk.getAvdManager();
        if (avdManager != null) {
            mFullAvdList = avdManager.getValidAvds();
        } else {
            mFullAvdList = null;
        }

        loadImages();
    
Methods Summary
protected voidcancelPressed()

        cleanup();
        super.cancelPressed();
    
private voidcleanup()

        // done listening.
        AndroidDebugBridge.removeDeviceChangeListener(this);

        mEmulatorImage.dispose();
        mDeviceImage.dispose();
        mMatchImage.dispose();
        mNoMatchImage.dispose();
        mWarningImage.dispose();
    
protected org.eclipse.swt.widgets.ControlcreateContents(org.eclipse.swt.widgets.Composite parent)

        Control content = super.createContents(parent);
        
        // this must be called after createContents() has happened so that the
        // ok button has been created (it's created after the call to createDialogArea)
        updateDefaultSelection();

        return content;
    
protected org.eclipse.swt.widgets.ControlcreateDialogArea(org.eclipse.swt.widgets.Composite parent)

        Composite top = new Composite(parent, SWT.NONE);
        top.setLayout(new GridLayout(1, true));

        mDeviceRadioButton = new Button(top, SWT.RADIO);
        mDeviceRadioButton.setText("Choose a running Android device");
        mDeviceRadioButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean deviceMode = mDeviceRadioButton.getSelection();

                mDeviceTable.setEnabled(deviceMode);
                mPreferredAvdSelector.setEnabled(!deviceMode);

                if (deviceMode) {
                    handleDeviceSelection();
                } else {
                    mResponse.setAvdToLaunch(mPreferredAvdSelector.getFirstSelected());
                }
                
                enableOkButton();
            }
        });
        mDeviceRadioButton.setSelection(true);
        

        // offset the selector from the radio button
        Composite offsetComp = new Composite(top, SWT.NONE);
        offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        GridLayout layout = new GridLayout(1, false);
        layout.marginRight = layout.marginHeight = 0;
        layout.marginLeft = 30;
        offsetComp.setLayout(layout);

        IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore(); 
        mDeviceTable = new Table(offsetComp, SWT.SINGLE | SWT.FULL_SELECTION);
        GridData gd;
        mDeviceTable.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
        gd.heightHint = 100;

        mDeviceTable.setHeaderVisible(true);
        mDeviceTable.setLinesVisible(true);

        TableHelper.createTableColumn(mDeviceTable, "Serial Number",
                SWT.LEFT, "AAA+AAAAAAAAAAAAAAAAAAA", //$NON-NLS-1$
                PREFS_COL_SERIAL, store);

        TableHelper.createTableColumn(mDeviceTable, "AVD Name",
                SWT.LEFT, "engineering", //$NON-NLS-1$
                PREFS_COL_AVD, store);

        TableHelper.createTableColumn(mDeviceTable, "Target",
                SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$
                PREFS_COL_TARGET, store);

        TableHelper.createTableColumn(mDeviceTable, "Debug",
                SWT.LEFT, "Debug", //$NON-NLS-1$
                PREFS_COL_DEBUG, store);

        TableHelper.createTableColumn(mDeviceTable, "State",
                SWT.LEFT, "bootloader", //$NON-NLS-1$
                PREFS_COL_STATE, store);

        // create the viewer for it
        mViewer = new TableViewer(mDeviceTable);
        mViewer.setContentProvider(new ContentProvider());
        mViewer.setLabelProvider(new LabelProvider());
        mViewer.setInput(AndroidDebugBridge.getBridge());

        mDeviceTable.addSelectionListener(new SelectionAdapter() {
            /**
             * Handles single-click selection on the device selector.
             * {@inheritDoc}
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                handleDeviceSelection();
            }

            /**
             * Handles double-click selection on the device selector.
             * Note that the single-click handler will probably already have been called.
             * {@inheritDoc}
             */
            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                handleDeviceSelection();
                if (isOkButtonEnabled()) {
                    okPressed();
                }
            }
        });
        
        Button radio2 = new Button(top, SWT.RADIO);
        radio2.setText("Launch a new Android Virtual Device");

        // offset the selector from the radio button
        offsetComp = new Composite(top, SWT.NONE);
        offsetComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        layout = new GridLayout(1, false);
        layout.marginRight = layout.marginHeight = 0;
        layout.marginLeft = 30;
        offsetComp.setLayout(layout);
        
        mPreferredAvdSelector = new AvdSelector(offsetComp, getNonRunningAvds(), mProjectTarget);
        mPreferredAvdSelector.setTableHeightHint(100);
        mPreferredAvdSelector.setEnabled(false);
        mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
            /**
             * Handles single-click selection on the AVD selector.
             * {@inheritDoc}
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (mDisableAvdSelectionChange == false) {
                    mResponse.setAvdToLaunch(mPreferredAvdSelector.getFirstSelected());
                    enableOkButton();
                }
            }
            
            /**
             * Handles double-click selection on the AVD selector.
             * 
             * Note that the single-click handler will probably already have been called
             * but the selected item can have changed in between.
             * 
             * {@inheritDoc}
             */
            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                widgetSelected(e);
                if (isOkButtonEnabled()) {
                    okPressed();
                }
            }
        });
        
        AndroidDebugBridge.addDeviceChangeListener(this);

        return top;
    
public voiddeviceChanged(com.android.ddmlib.Device device, int changeMask)
Sent when a device data changed, or when clients are started/terminated on the device.

This is sent from a non UI thread.

param
device the device that was updated.
param
changeMask the mask indicating what changed.
see
IDeviceChangeListener#deviceChanged(Device, int)

        if ((changeMask & (Device.CHANGE_STATE | Device.CHANGE_BUILD_INFO)) != 0) {
            final DeviceChooserDialog dialog = this;
            exec(new Runnable() {
                public void run() {
                    if (mDeviceTable.isDisposed() == false) {
                        // refresh the device
                        mViewer.refresh(device);
                        
                        // update the defaultSelection.
                        updateDefaultSelection();
                    
                        // update the display of AvdInfo (since it's filtered to only display
                        // non running AVD). This is done on deviceChanged because the avd name
                        // of a (emulator) device may be updated as the emulator boots.
                        refillAvdList();

                        // if the changed device is the current selection,
                        // we update the OK button based on its state.
                        if (device == mResponse.getDeviceToUse()) {
                            enableOkButton();
                        }

                    } else {
                        // table is disposed, we need to do something.
                        // lets remove ourselves from the listener.
                        AndroidDebugBridge.removeDeviceChangeListener(dialog);
                    }
                }
            });
        }
    
public voiddeviceConnected(com.android.ddmlib.Device device)
Sent when the a device is connected to the {@link AndroidDebugBridge}.

This is sent from a non UI thread.

param
device the new device.
see
IDeviceChangeListener#deviceConnected(Device)

        final DeviceChooserDialog dialog = this;
        exec(new Runnable() {
            public void run() {
                if (mDeviceTable.isDisposed() == false) {
                    // refresh all
                    mViewer.refresh();
                    
                    // update the selection
                    updateDefaultSelection();
                    
                    // update the display of AvdInfo (since it's filtered to only display
                    // non running AVD.)
                    refillAvdList();
                } else {
                    // table is disposed, we need to do something.
                    // lets remove ourselves from the listener.
                    AndroidDebugBridge.removeDeviceChangeListener(dialog);
                }

            }
        });
    
public voiddeviceDisconnected(com.android.ddmlib.Device device)
Sent when the a device is connected to the {@link AndroidDebugBridge}.

This is sent from a non UI thread.

param
device the new device.
see
IDeviceChangeListener#deviceDisconnected(Device)

        deviceConnected(device);
    
private voidenableOkButton()
Enables or disables the OK button of the dialog based on various selections in the dialog.

        Button okButton = getButton(IDialogConstants.OK_ID);
        
        if (isDeviceMode()) {
            okButton.setEnabled(mResponse.getDeviceToUse() != null &&
                    mResponse.getDeviceToUse().isOnline());
        } else {
            okButton.setEnabled(mResponse.getAvdToLaunch() != null);
        }
    
private voidexec(java.lang.Runnable runnable)
Executes the {@link Runnable} in the UI thread.

param
runnable the runnable to execute.

        try {
            Display display = mDeviceTable.getDisplay();
            display.asyncExec(runnable);
        } catch (SWTException e) {
            // tree is disposed, we need to do something. lets remove ourselves from the listener.
            AndroidDebugBridge.removeDeviceChangeListener(this);
        }
    
private com.android.sdklib.avd.AvdManager.AvdInfo[]getNonRunningAvds()
Returns the list of {@link AvdInfo} that are not already running in an emulator.

        ArrayList<AvdInfo> list = new ArrayList<AvdInfo>();
        
        Device[] devices = AndroidDebugBridge.getBridge().getDevices();
        
        // loop through all the Avd and put the one that are not running in the list.
        avdLoop: for (AvdInfo info : mFullAvdList) {
            for (Device d : devices) {
                if (info.getName().equals(d.getAvdName())) {
                    continue avdLoop;
                }
            }
            list.add(info);
        }
        
        return list.toArray(new AvdInfo[list.size()]);
    
private static java.lang.StringgetStateString(com.android.ddmlib.Device d)
Returns a display string representing the state of the device.

param
d the device

        DeviceState deviceState = d.getState();
        if (deviceState == DeviceState.ONLINE) {
            return "Online";
        } else if (deviceState == DeviceState.OFFLINE) {
            return "Offline";
        } else if (deviceState == DeviceState.BOOTLOADER) {
            return "Bootloader";
        }

        return "??";
    
private voidhandleDeviceSelection()

        int count = mDeviceTable.getSelectionCount();
        if (count != 1) {
            handleSelection(null);
        } else {
            int index = mDeviceTable.getSelectionIndex();
            Object data = mViewer.getElementAt(index);
            if (data instanceof Device) {
                handleSelection((Device)data);
            } else {
                handleSelection(null);
            }
        }
    
private voidhandleSelection(com.android.ddmlib.Device device)

        mResponse.setDeviceToUse(device);
        enableOkButton();
    
private booleanisDeviceMode()
Returns whether the dialog is in "device" mode (true), or in "avd" mode (false).

        return mDeviceRadioButton.getSelection();
    
private booleanisOkButtonEnabled()
Returns true if the ok button is enabled.

        Button okButton = getButton(IDialogConstants.OK_ID);
        return okButton.isEnabled();
    
private voidloadImages()

        IImageLoader ddmsLoader = DdmsPlugin.getImageLoader();
        Display display = DdmsPlugin.getDisplay();
        IImageLoader adtLoader = AdtPlugin.getImageLoader();

        if (mDeviceImage == null) {
            mDeviceImage = ImageHelper.loadImage(ddmsLoader, display,
                    "device.png", //$NON-NLS-1$
                    ICON_WIDTH, ICON_WIDTH,
                    display.getSystemColor(SWT.COLOR_RED));
        }
        if (mEmulatorImage == null) {
            mEmulatorImage = ImageHelper.loadImage(ddmsLoader, display,
                    "emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
                    display.getSystemColor(SWT.COLOR_BLUE));
        }
        
        if (mMatchImage == null) {
            mMatchImage = ImageHelper.loadImage(adtLoader, display,
                    "match.png", //$NON-NLS-1$
                    ICON_WIDTH, ICON_WIDTH,
                    display.getSystemColor(SWT.COLOR_GREEN));
        }

        if (mNoMatchImage == null) {
            mNoMatchImage = ImageHelper.loadImage(adtLoader, display,
                    "error.png", //$NON-NLS-1$
                    ICON_WIDTH, ICON_WIDTH,
                    display.getSystemColor(SWT.COLOR_RED));
        }

        if (mWarningImage == null) {
            mWarningImage = ImageHelper.loadImage(adtLoader, display,
                    "warning.png", //$NON-NLS-1$
                    ICON_WIDTH, ICON_WIDTH,
                    display.getSystemColor(SWT.COLOR_YELLOW));
        }

    
protected voidokPressed()

        cleanup();
        super.okPressed();
    
private voidrefillAvdList()
Refills the AVD list keeping the current selection.

        AvdInfo[] array = getNonRunningAvds();
        
        // save the current selection
        AvdInfo selected = mPreferredAvdSelector.getFirstSelected();
        
        // disable selection change.
        mDisableAvdSelectionChange = true;
        
        // set the new list in the selector
        mPreferredAvdSelector.setAvds(array, mProjectTarget);
        
        // attempt to reselect the proper avd if needed
        if (selected != null) {
            if (mPreferredAvdSelector.setSelection(selected) == false) {
                // looks like the selection is lost. this can happen if an emulator
                // running the AVD that was selected was launched from outside of Eclipse).
                mResponse.setAvdToLaunch(null);
                enableOkButton();
            }
        }
        
        // enable the selection change
        mDisableAvdSelectionChange = false;
    
private voidupdateDefaultSelection()
Look for a default device to select. This is done by looking for the running clients on each device and finding one similar to the one being launched.

This is done every time the device list changed unless there is a already selection.

        if (mDeviceTable.getSelectionCount() == 0) {
            AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
            
            Device[] devices = bridge.getDevices();
            
            for (Device device : devices) {
                Client[] clients = device.getClients();
                
                for (Client client : clients) {
                    
                    if (mPackageName.equals(client.getClientData().getClientDescription())) {
                        // found a match! Select it.
                        mViewer.setSelection(new StructuredSelection(device));
                        handleSelection(device);
                        
                        // and we're done.
                        return;
                    }
                }
            }
        }

        handleDeviceSelection();