| /* |
| * 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.launch; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.ui.ILaunchShortcut; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.ui.IEditorPart; |
| |
| import com.motorola.studio.android.adt.ISerialNumbered; |
| import com.motorola.studio.android.adt.SdkUtils; |
| import com.motorola.studio.android.common.log.StudioLogger; |
| import com.motorola.studio.android.devices.DevicesManager; |
| import com.motorola.studio.android.launch.i18n.LaunchNLS; |
| |
| public class LaunchConfigurationShortcut implements ILaunchShortcut |
| { |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String) |
| */ |
| public void launch(ISelection selection, String mode) |
| { |
| ILaunchConfiguration launchConfiguration = |
| getLaunchConfigurationForSelection(selection, true); |
| handleLaunch(mode, launchConfiguration); |
| |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String) |
| */ |
| public void launch(IEditorPart editor, String mode) |
| { |
| IResource resource = (IResource) editor.getEditorInput().getAdapter(IResource.class); |
| if (resource != null) |
| { |
| ILaunchConfiguration launchConfiguration = |
| getLaunchConfigurationForResource(resource, true); |
| handleLaunch(mode, launchConfiguration); |
| } |
| } |
| |
| private void handleLaunch(String mode, ILaunchConfiguration launchConfiguration) |
| { |
| if (launchConfiguration != null) |
| { |
| final ILaunchConfiguration config = launchConfiguration; |
| final String launchMode = mode; |
| |
| Job job = new Job("Launch Job") |
| { |
| |
| @Override |
| protected IStatus run(IProgressMonitor monitor) |
| { |
| IStatus status = Status.OK_STATUS; |
| try |
| { |
| config.launch(launchMode, monitor); |
| } |
| catch (CoreException e) |
| { |
| status = |
| new Status( |
| IStatus.ERROR, |
| LaunchPlugin.PLUGIN_ID, |
| LaunchNLS.ERR_LaunchConfigurationShortcut_CannotLaunchSelectedResourceMsg, |
| e); |
| } |
| return status; |
| } |
| }; |
| |
| job.schedule(); |
| } |
| else |
| { |
| LaunchUtils.showErrorDialog(LaunchNLS.ERR_LaunchConfigurationShortcut_MsgTitle, |
| LaunchNLS.ERR_LaunchConfigurationShortcut_CannotLaunchSelectedResourceMsg); |
| } |
| } |
| |
| /** |
| * Gets a launch configuration for a desired selection |
| * |
| * @param selection The selection |
| * @param create If the launch configuration does not exist, does it must be created? |
| * |
| * @return The launch configuration for the selection |
| */ |
| |
| private ILaunchConfiguration getLaunchConfigurationForSelection(ISelection selection, |
| boolean create) |
| { |
| ILaunchConfiguration config = null; |
| IStructuredSelection newSelection; |
| Object selectedObject; |
| IResource selectedResource = null; |
| |
| if (selection instanceof IStructuredSelection) |
| { |
| newSelection = (IStructuredSelection) selection; |
| selectedObject = newSelection.getFirstElement(); |
| |
| if (selectedObject instanceof IResource) |
| { |
| selectedResource = (IResource) selectedObject; |
| } |
| else if (selectedObject instanceof IJavaElement) |
| { |
| selectedResource = ((IJavaElement) selectedObject).getResource(); |
| } |
| |
| if (selectedResource != null) |
| { |
| config = getLaunchConfigurationForResource(selectedResource, create); |
| } |
| } |
| |
| return config; |
| } |
| |
| /** |
| * Gets a launch configuration for a resource |
| * |
| * @param resource The resource |
| * @param create If the launch configuration does not exist, does it must be created? |
| * |
| * @return The launch configuration for the resource |
| */ |
| private ILaunchConfiguration getLaunchConfigurationForResource(IResource resource, |
| boolean create) |
| { |
| IResource app; |
| IResource project; |
| ILaunchConfiguration config = null; |
| |
| if (resource != null) |
| { |
| if (resource.getType() == IResource.PROJECT) |
| { |
| project = resource; |
| } |
| else |
| { |
| project = resource.getProject(); |
| } |
| // Try to retrieve an existent launch configuration |
| config = findLaunchConfiguration(project); |
| |
| if ((config == null) && create) |
| { |
| // No launch configuration could be found. Try to create a |
| // launch configuration with the first runnable activity |
| app = getFirstActivity((IProject) project); |
| |
| // If no application could be found, use the project |
| // to create the launch configuration |
| app = app == null ? resource : app; |
| config = createLaunchConfiguration(app); |
| } |
| |
| } |
| |
| return config; |
| } |
| |
| /** |
| * Finds a launch configuration for a descriptor, a mpkg file or a project |
| * |
| * @param resource A descriptor, a mpkg file or a project |
| * |
| * @return A launch configuration or null if it could not be found |
| */ |
| private ILaunchConfiguration findLaunchConfiguration(IResource resource) |
| { |
| ILaunchConfiguration launchConfig = null; |
| |
| if (resource != null) |
| { |
| try |
| { |
| List<ILaunchConfiguration> projectLC = |
| getProjectLaunchConfigurations(resource.getProject()); |
| |
| if ((resource.getType() == IResource.PROJECT) |
| || (resource.getType() == IResource.FILE)) |
| { |
| // If the resource is a project, return the first launch configuration found |
| // for the project |
| if (!projectLC.isEmpty()) |
| { |
| launchConfig = projectLC.iterator().next(); |
| } |
| } |
| } |
| catch (CoreException e) |
| { |
| StudioLogger.error( |
| LaunchConfigurationShortcut.class, |
| "Error searching for launch configuration for resource: " |
| + resource.getName(), e); |
| } |
| } |
| |
| return launchConfig; |
| } |
| |
| /** |
| * Scan for all LaunchConfigurations associated with a project. |
| * @param selectedResource, the project itself or any file within the project to be scanned |
| * @return List with all LaunchConfiguration associated with a project or an empty List if none is found. |
| * @throws CoreException |
| */ |
| protected List<ILaunchConfiguration> getProjectLaunchConfigurations(IProject project) |
| throws CoreException |
| { |
| List<ILaunchConfiguration> matches; |
| |
| ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchConfigurationType motodevLaunchType = |
| launchManager |
| .getLaunchConfigurationType(ILaunchConfigurationConstants.LAUNCH_CONFIGURATION_TYPE_EXTENSION_ID); |
| |
| ILaunchConfiguration[] motodevLaunchConfigurations = |
| launchManager.getLaunchConfigurations(motodevLaunchType); |
| matches = new ArrayList<ILaunchConfiguration>(motodevLaunchConfigurations.length); |
| for (ILaunchConfiguration launchConfiguration : motodevLaunchConfigurations) |
| { |
| if (launchConfiguration.getAttribute(ILaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| "").equals(project.getName())) //$NON-NLS-1$ |
| { |
| matches.add(launchConfiguration); |
| } |
| } |
| |
| return matches; |
| } |
| |
| /** |
| * Gets the first runnable application/widget for a project. It can be a |
| * application/widget root folder or a mpkg file |
| * |
| * @param project The project |
| * |
| * @return The first runnable application/widget or null if it does not exist |
| */ |
| private IResource getFirstActivity(IProject project) |
| { |
| IResource app = null; |
| |
| String[] allActivities = LaunchUtils.getProjectActivities(project); |
| |
| if ((allActivities != null) && (allActivities.length >= 1)) |
| { |
| app = project.getFile(allActivities[0]); |
| } |
| |
| return app; |
| } |
| |
| /** |
| * Creates a launch configuration based on a resource |
| * |
| * @param resource The resource |
| * |
| * @return A launch configuration |
| */ |
| private ILaunchConfiguration createLaunchConfiguration(IResource resource) |
| { |
| ILaunchConfiguration config = null; |
| ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunchConfigurationType motodevLaunchType = |
| launchManager |
| .getLaunchConfigurationType(ILaunchConfigurationConstants.LAUNCH_CONFIGURATION_TYPE_EXTENSION_ID); |
| String projectName; |
| |
| String configBaseName = resource.getName(); |
| |
| String launchConfigurationName = |
| launchManager.generateLaunchConfigurationName(configBaseName); |
| try |
| { |
| ILaunchConfigurationWorkingCopy workingCopy = |
| motodevLaunchType.newInstance(null, launchConfigurationName); |
| |
| //Set Defaults |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| ILaunchConfigurationConstants.DEFAULT_VALUE); |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_ACTIVITY, |
| ILaunchConfigurationConstants.DEFAULT_VALUE); |
| // It is default not to exist Preferred AVD attribute, so we just set the Studio's |
| // device instance name attribute here |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, |
| (String) null); |
| LaunchUtils.setADTLaunchConfigurationDefaults(workingCopy); |
| |
| //Launch Settings |
| IProject project = resource.getProject(); |
| projectName = project.getName(); |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName); |
| |
| if (resource.getType() != IResource.PROJECT) |
| { |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_ACTIVITY, |
| resource.getName()); |
| } |
| |
| String deviceName = getSelectedInstanceName(project); |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_DEVICE_INSTANCE_NAME, |
| deviceName); |
| // Preferred AVD name shall only exist in the launch configuration if an AVD is selected |
| Collection<String> validAvds = SdkUtils.getAllValidVmNames(); |
| if (validAvds.contains(deviceName)) |
| { |
| workingCopy.setAttribute( |
| ILaunchConfigurationConstants.ATTR_ADT_DEVICE_INSTANCE_NAME, deviceName); |
| } |
| |
| if (workingCopy.getAttribute(ILaunchConfigurationConstants.ATTR_ACTIVITY, |
| ILaunchConfigurationConstants.DEFAULT_VALUE).equals("")) |
| { |
| workingCopy.setAttribute(ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION, |
| ILaunchConfigurationConstants.ATTR_LAUNCH_ACTION_DEFAULT); |
| } |
| |
| config = workingCopy.doSave(); |
| } |
| catch (CoreException e) |
| { |
| StudioLogger.error(LaunchConfigurationShortcut.class, |
| "Error creating launch configuration for resource: " + resource.getName(), e); |
| } |
| |
| return config; |
| } |
| |
| /** |
| * Get a available and compatible instance name. |
| * This method seeks within all registered instances, following the criteria: |
| * Phone device with "full" compatibility (API version = project min. API) |
| * Phone device with "partial" compatibility (API version > project min. API) |
| * Emulator device with "full" compatibility (API version = project min. API) |
| * Emulator device with "partial" compatibility (API version = project min. API) |
| * @param project |
| */ |
| protected String getSelectedInstanceName(IProject project) |
| { |
| String selectedDevice = ""; |
| |
| //get all instances according ddms |
| Collection<ISerialNumbered> instances = DevicesManager.getInstance().getAllDevicesSorted(); |
| String candidate = ""; |
| for (ISerialNumbered instance : instances) |
| { |
| |
| IStatus compatible = LaunchUtils.isCompatible(project, instance); |
| if (compatible.isOK()) |
| { |
| selectedDevice = instance.getDeviceName(); |
| break; |
| } |
| else if (compatible.getSeverity() == IStatus.WARNING) |
| { |
| candidate = instance.getDeviceName(); |
| } |
| |
| } |
| if ((selectedDevice.equals("")) && !candidate.equals("")) |
| { |
| selectedDevice = candidate; |
| } |
| |
| return selectedDevice; |
| } |
| |
| } |