1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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.pdt.internal; 18 19 import com.android.ide.eclipse.ddms.IDebuggerConnector; 20 21 import org.eclipse.core.resources.IProject; 22 import org.eclipse.core.runtime.CoreException; 23 import org.eclipse.debug.core.DebugPlugin; 24 import org.eclipse.debug.core.ILaunchConfiguration; 25 import org.eclipse.debug.core.ILaunchConfigurationType; 26 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; 27 import org.eclipse.debug.core.ILaunchManager; 28 import org.eclipse.debug.ui.DebugUITools; 29 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; 30 31 import java.util.HashMap; 32 import java.util.Map; 33 34 /** 35 * Implementation of the com.android.ide.ddms.debuggerConnector extension point. 36 */ 37 public class DebuggerConnector extends DevTreeProjectProvider implements IDebuggerConnector { 38 39 private final static String ATTR_CONNECT_MAP_PORT = "port"; //$NON-NLS-1$ 40 private final static String ATTR_CONNECT_MAP_HOSTNAME = "hostname"; //$NON-NLS-1$ 41 42 @Override isWorkspaceApp(String appName)43 public boolean isWorkspaceApp(String appName) { 44 return getProject() != null; 45 } 46 47 @Override connectDebugger(String appName, int appPort, int selectedPort)48 public boolean connectDebugger(String appName, int appPort, int selectedPort) { 49 IProject project = getProject(); 50 51 if (project != null) { 52 // get the launch manager 53 ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); 54 55 // get the config for the remote launch config. 56 ILaunchConfigurationType configType = manager.getLaunchConfigurationType( 57 IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION); 58 59 String projectName = project.getName(); 60 61 // look for an existing launch config 62 ILaunchConfiguration config = findConfig(manager, configType, projectName, 63 selectedPort); 64 65 if (config == null) { 66 // Didn't find a matching config, so we make one. 67 // It'll be made in the "working copy" object first. 68 ILaunchConfigurationWorkingCopy wc = null; 69 70 try { 71 // make the working copy object with a unique name 72 wc = configType.newInstance(null, 73 manager.generateUniqueLaunchConfigurationNameFrom(projectName)); 74 75 // set the project name 76 wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, 77 projectName); 78 79 // set the connect map info 80 Map<String, String> connectMap = new HashMap<String, String>(); 81 connectMap.put(ATTR_CONNECT_MAP_PORT, Integer.toString(selectedPort)); 82 connectMap.put(ATTR_CONNECT_MAP_HOSTNAME, "localhost"); //$NON-NLS-1$ 83 wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, connectMap); 84 85 // set the VM connector ID 86 wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, 87 IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR); 88 89 // save the working copy to get the launch config object which we return. 90 config = wc.doSave(); 91 92 } catch (CoreException e) { 93 94 } 95 96 } 97 98 if (config != null) { 99 DebugUITools.launch(config, ILaunchManager.DEBUG_MODE); 100 return true; 101 } 102 } 103 104 return false; 105 } 106 107 /** 108 * Looks for and returns an existing {@link ILaunchConfiguration} object for a 109 * specified project and connection port. 110 * @param manager The {@link ILaunchManager}. 111 * @param type The {@link ILaunchConfigurationType}. 112 * @param projectName The name of the project 113 * @param connectionPort the remote connection port. 114 * @return an existing <code>ILaunchConfiguration</code> object matching the project, or 115 * <code>null</code>. 116 */ findConfig(ILaunchManager manager, ILaunchConfigurationType type, String projectName, int connectionPort)117 private static ILaunchConfiguration findConfig(ILaunchManager manager, 118 ILaunchConfigurationType type, 119 String projectName, int connectionPort) { 120 try { 121 ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type); 122 123 // look for one set up for the project with a debug equal to the selected debug port. 124 for (ILaunchConfiguration config : configs) { 125 126 Map<?, ?> attributes = config.getAttributes(); 127 128 String name = (String) attributes.get( 129 IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME); 130 131 if (name == null || name.equals(projectName) == false) { 132 continue; 133 } 134 135 Map<?, ?> connectMap = (Map<?, ?>) attributes.get( 136 IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP); 137 138 if (connectMap != null) { 139 String portStr = (String) connectMap.get(ATTR_CONNECT_MAP_PORT); 140 if (portStr != null) { 141 Integer port = Integer.valueOf(portStr); 142 if (connectionPort == port) { 143 return config; 144 } 145 } 146 } 147 148 } 149 } catch (CoreException e) { 150 } 151 152 // didn't find anything that matches. Return null 153 return null; 154 } 155 } 156