/* * 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.wizards.monkey; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.osgi.util.NLS; import org.eclipse.sequoyah.device.framework.events.IInstanceListener; import org.eclipse.sequoyah.device.framework.events.InstanceEvent; import org.eclipse.sequoyah.device.framework.events.InstanceEventManager; import org.eclipse.sequoyah.device.framework.model.IInstance; 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.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.plugin.AbstractUIPlugin; import com.motorola.studio.android.AndroidPlugin; import com.motorola.studio.android.adt.DDMSFacade; import com.motorola.studio.android.adt.ISerialNumbered; import com.motorola.studio.android.common.log.StudioLogger; import com.motorola.studio.android.devices.DevicesManager; import com.motorola.studio.android.i18n.AndroidNLS; import com.motorola.studio.android.wizards.elements.sorting.TableItemSortStringSetActionListener; /** * Implements the Main tab of the Monkey Launch Configuration. */ public class MonkeyConfigurationTab extends AbstractLaunchConfigurationTab { private MonkeyConfigurationTabTable packageTable; private Map<String, String> availablePackages = null; private static final String contextId = AndroidPlugin.PLUGIN_ID + ".monkey"; private final boolean filterSystem; private static final Object UPDATE_WIDGETS_EVENT = new Object(); private Text countCombo = null; private String deviceName = ""; private String eventCount = ""; private Button deviceNameBrowseButton = null; private final Button defaultLauncherButton = null; private Composite mainComposite; private List<?> selectedPackagesPreference = null; /** * Determines whether the filter is active. * * @return Returns whether the filter is active. */ boolean isFilterSystem() { return filterSystem; } /** * Get the list of selected packages preference. * * @return Returns the list of selected packages preference. */ List<?> getSelectedPackagesPreference() { return selectedPackagesPreference; } /** * Call the method {@link #updateLaunchConfigurationDialog}. */ void callUpdateLaunchConfigurationDialog() { updateLaunchConfigurationDialog(); } private boolean firstTime = false; /* * This listener follows changes made on devices and fires updates. */ private final IInstanceListener instanceListener = new IInstanceListener() { private void fireUpdate() { PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { updateDeviceChooserButton(); updateLaunchConfigurationDialog(); } }); } public void instanceUpdated(InstanceEvent instanceevent) { fireUpdate(); } public void instanceUnloaded(InstanceEvent instanceevent) { fireUpdate(); } public void instanceTransitioned(InstanceEvent instanceevent) { fireUpdate(); } public void instanceLoaded(InstanceEvent instanceevent) { fireUpdate(); } public void instanceDeleted(InstanceEvent instanceevent) { fireUpdate(); } public void instanceCreated(InstanceEvent instanceevent) { fireUpdate(); } public void instanceAboutToTransition(InstanceEvent instanceevent) { fireUpdate(); } }; private void updateDeviceChooserButton() { // button is always enabled deviceNameBrowseButton.setEnabled(true); } public MonkeyConfigurationTab(boolean filterSystem) { this.filterSystem = filterSystem; } public void createControl(Composite parent) { Composite mainComposite = new Composite(parent, SWT.FILL); this.mainComposite = mainComposite; mainComposite.setLayout(new GridLayout(3, false)); /* * Device */ // Device Name Label Label deviceNameLabel = new Label(mainComposite, SWT.NONE); deviceNameLabel.setText(AndroidNLS.UI_MonkeyComposite_DeviceNameLabel); GridData deviceGridData = new GridData(SWT.LEFT, SWT.CENTER, false, false); deviceNameLabel.setLayoutData(deviceGridData); // Device Name Text final Text deviceNameText = new Text(mainComposite, SWT.SINGLE | SWT.BORDER); deviceNameText.setText(deviceName); deviceGridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1); deviceNameText.setLayoutData(deviceGridData); addDeviceNameTextListeners(deviceNameText); // Device Name Browse Button deviceNameBrowseButton = new Button(mainComposite, SWT.PUSH); deviceGridData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); deviceNameBrowseButton.setLayoutData(deviceGridData); deviceNameBrowseButton.setText(AndroidNLS.UI_General_BrowseButtonLabel); deviceNameBrowseButton.addSelectionListener(new SelectionAdapter() { /* * (non-Javadoc) * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { DeviceSelectionDialog dialog = new DeviceSelectionDialog(getShell(), AndroidNLS.UI_MonkeyComposite_SelectDeviceScreenMessage); dialog.setTitle(AndroidNLS.UI_MonkeyComposite_SelectDeviceScreenTitle); dialog.setMultipleSelection(false); dialog.setValidator(new ISelectionStatusValidator() { public IStatus validate(Object[] selection) { IStatus status = new Status(IStatus.OK, AndroidPlugin.PLUGIN_ID, ""); if (selection.length == 0) { status = new Status(IStatus.ERROR, AndroidPlugin.PLUGIN_ID, "No selected instance"); } return status; } }); int res = dialog.open(); if (res == IDialogConstants.OK_ID) { ISerialNumbered serialNumbered = (ISerialNumbered) dialog.getFirstResult(); String selectedDevice = ((IInstance) serialNumbered).getName(); packageTable.removeAllTableItems(); deviceNameText.setText(selectedDevice); } } }); InstanceEventManager.getInstance().addInstanceListener(instanceListener); /* *Device end */ packageTable = new MonkeyConfigurationTabTable(mainComposite, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION, AndroidNLS.UninstallAppWizardPage_Loading_Applications, this); packageTable.setTableHeaderVisible(true); GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); packageTable.setLayoutData(layoutData); TableColumn packageNameColumn = packageTable.addTableColumn(SWT.CENTER); TableColumn isSystemColumn = packageTable.addTableColumn(SWT.CENTER); packageNameColumn.setText(AndroidNLS.UninstallAppWizardPage_ColumnPackageName); isSystemColumn.setText(AndroidNLS.UninstallAppWizardPage_ColumnPackageKiind); packageNameColumn.setWidth(200); isSystemColumn.setWidth(200); packageNameColumn.addSelectionListener(new TableItemSortStringSetActionListener()); isSystemColumn.addSelectionListener(new TableItemSortStringSetActionListener()); packageTable.setTableLinesVisible(false); packageTable.pack(); packageTable.redraw(); packageTable.addTableSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { firstTime = false; if ((packageTable != null) && (packageTable.getTableItems().length > 0) && (!packageTable.getTableItem(0).getText(0) .contains(AndroidNLS.UninstallAppWizardPage_Loading_Applications))) { selectedPackagesPreference = getPackageList(); updateLaunchConfigurationDialog(); } } public void widgetDefaultSelected(SelectionEvent e) { //do nothing } }); layoutData = new GridData(SWT.NONE, SWT.CENTER, false, false, 1, 1); layoutData.verticalIndent = 3; Label label = new Label(mainComposite, SWT.LEFT); label.setText(AndroidNLS.MonkeyWizardPage_CountCommand); label.setLayoutData(layoutData); layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); layoutData.verticalIndent = 3; countCombo = new Text(mainComposite, SWT.SINGLE | SWT.WRAP | SWT.BORDER); countCombo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { if (e.data == UPDATE_WIDGETS_EVENT) { countCombo.setText(eventCount); } else { eventCount = countCombo.getText(); updateLaunchConfigurationDialog(); } } }); countCombo.setLayoutData(layoutData); mainComposite.addListener(SWT.Modify, new Listener() { /* * (non-Javadoc) * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event e) { countCombo.notifyListeners(SWT.Modify, e); deviceNameText.notifyListeners(SWT.Modify, e); if (defaultLauncherButton != null) { defaultLauncherButton.notifyListeners(SWT.Selection, e); } } }); PlatformUI.getWorkbench().getHelpSystem().setHelp(mainComposite, contextId); setControl(mainComposite); } /** * Add a listener to the deviceNameText field. * @param deviceNameText */ private void addDeviceNameTextListeners(final Text deviceNameText) { deviceNameText.addModifyListener(new ModifyListener() { /* * (non-Javadoc) * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) */ public void modifyText(ModifyEvent e) { if (e.data == UPDATE_WIDGETS_EVENT) { //handling when pressing Revert button if ((deviceName != null) && (!deviceName.equals(deviceNameText.getText()))) { firstTime = true; } deviceNameText.setText(deviceName); } else { if (!deviceName.equals(deviceNameText.getText()) || (firstTime)) { deviceName = deviceNameText.getText(); packageTable.removeAllTableItems(); if (!deviceName.equals("")) { DevicesManager deviceManager = DevicesManager.getInstance(); if (deviceManager != null) { ISerialNumbered serialNumbered = deviceManager.getDeviceByName(deviceName); if (serialNumbered != null) { final String serialNumber = serialNumbered.getSerialNumber(); if (serialNumber != null) { // initiating Loading thread packageTable.removeAllTableItems(); if (availablePackages != null) { availablePackages.clear(); } // call service to populate the table packageTable.populateTableAsynchronously(serialNumber); } } } } } updateLaunchConfigurationDialog(); } } }); } /** * Verify if the deviceName is a valid online device instance. * @param deviceName * @return true if the deviceName is a valid instance. */ private boolean validDevice(String deviceName) { boolean valid = false; ISerialNumbered sequoyahInstance = DevicesManager.getInstance().getDeviceByName(deviceName); if ((sequoyahInstance != null) && DDMSFacade.isDeviceOnline(sequoyahInstance.getSerialNumber())) { valid = true; } return valid; } /** * Verify if all required fields are fulfilled with valid values. * @return true if the required fields are correctly fulfilled. */ private boolean validatePage() { boolean complete = true; setErrorMessage(null); setMessage(null); if ((!deviceName.equals("")) && (!validDevice(deviceName))) { setErrorMessage(AndroidNLS.ERR_MonkeyWizardPage_Device); packageTable.removeAllTableItems(); complete = false; } if ((complete) && (!countCombo.getText().equals(""))) { try { int i = Integer.parseInt(countCombo.getText().toString()); if (i <= 0) { complete = false; } } catch (Exception e) { complete = false; } if (!complete) { String msg = NLS.bind( AndroidNLS.ERR_PropertiesMainComposite_Monkey_NumberMustBePositiveInteger, AndroidNLS.MonkeyWizardPage_CountCommand); setErrorMessage(msg); } } if (complete) { if (deviceName.equals("")) { setMessage(AndroidNLS.UI_MonkeyComposite_SelectDeviceScreenMessage); complete = false; } else if ((packageTable != null) && (packageTable.getTableSelectionCount() <= 0)) { setMessage(AndroidNLS.ERR_MonkeyWizardPage_Package); complete = false; } else if (countCombo.getText().equals("")) { setMessage(AndroidNLS.ERR_MonkeyWizardPage_CountCommand); complete = false; } } return complete; } /** * get the value for the event count * @return */ public String getCount() { return countCombo.getText().toString(); } /** * get the list of selected packages to run monkey * @return */ public List<String> getPackageList() { List<String> selectedPackages = new ArrayList<String>(); if (packageTable != null) { for (TableItem item : packageTable.getTableSelection()) { selectedPackages.add(item.getText(0)); } } return selectedPackages; } public String getName() { return AndroidNLS.UI_MonkeyComposite_TabMainName; } /** * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() */ @Override public Image getImage() { return AbstractUIPlugin.imageDescriptorFromPlugin(AndroidPlugin.PLUGIN_ID, IMonkeyConfigurationConstants.MOTODEV_APP_ICO).createImage(); } @Override public void dispose() { InstanceEventManager.getInstance().removeInstanceListener(instanceListener); super.dispose(); } public void initializeFrom(ILaunchConfiguration configuration) { try { if (deviceName.equals("")) { firstTime = true; } else { firstTime = false; } deviceName = configuration.getAttribute( IMonkeyConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, IMonkeyConfigurationConstants.DEFAULT_VALUE); eventCount = configuration.getAttribute(IMonkeyConfigurationConstants.ATTR_EVENT_COUNT_NAME, IMonkeyConfigurationConstants.DEFAULT_COUNT_VALUE); selectedPackagesPreference = configuration.getAttribute( IMonkeyConfigurationConstants.ATTR_SELECTED_PACKAGES, (List<?>) null); // Handling Revert button effect on the list of packages if (((packageTable != null) && (packageTable.getTableItems().length > 0) && (!packageTable .getTableItem(0).getText(0) .contains(AndroidNLS.UninstallAppWizardPage_Loading_Applications)))) { List<?> selectedPackages = getPackageList(); if ((selectedPackagesPreference == null) || (!selectedPackagesPreference.containsAll(selectedPackages))) { packageTable.deselectAllTableItems(); if (selectedPackagesPreference != null) { TableItem[] itemsP = new TableItem[selectedPackagesPreference.size()]; int i = 0; for (TableItem item : packageTable.getTableItems()) { if (selectedPackagesPreference.contains(item.getText(0))) { itemsP[i] = item; i++; } } packageTable.setTableSelection(itemsP); } } } Event e = new Event(); e.type = SWT.Modify; e.data = UPDATE_WIDGETS_EVENT; mainComposite.notifyListeners(SWT.Modify, e); } catch (CoreException e) { StudioLogger.error(MonkeyConfigurationTab.class, "Failed to initialize Monkey Launch Configuration:" + e.getMessage()); } } public void performApply(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, deviceName); configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_EVENT_COUNT_NAME, eventCount); configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_SELECTED_PACKAGES, selectedPackagesPreference); } public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, IMonkeyConfigurationConstants.DEFAULT_VALUE); configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_EVENT_COUNT_NAME, IMonkeyConfigurationConstants.DEFAULT_COUNT_VALUE); configuration.setAttribute(IMonkeyConfigurationConstants.ATTR_SELECTED_PACKAGES, (List<?>) null); if (mainComposite != null) { Event e = new Event(); e.type = SWT.Modify; e.data = UPDATE_WIDGETS_EVENT; mainComposite.notifyListeners(SWT.Modify, e); } } /** * @see ILaunchConfigurationTab#isValid(ILaunchConfiguration) */ @Override public boolean isValid(ILaunchConfiguration launchConfig) { return validatePage(); } }