Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(608)

Side by Side Diff: dart/editor/tools/plugins/com.google.dart.tools.debug.core/src/com/google/dart/tools/debug/core/mobile/MobileLaunchConfigurationDelegate.java

Issue 321583008: Merge to trunk cl - fixes/features for mobile support in the editor (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014, the Dart project authors. 2 * Copyright (c) 2014, the Dart project authors.
3 * 3 *
4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u se this file except 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u se this file except
5 * in compliance with the License. You may obtain a copy of the License at 5 * in compliance with the License. You may obtain a copy of the License at
6 * 6 *
7 * http://www.eclipse.org/legal/epl-v10.html 7 * http://www.eclipse.org/legal/epl-v10.html
8 * 8 *
9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License 9 * Unless required by applicable law or agreed to in writing, software distribut ed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K IND, either express
11 * or implied. See the License for the specific language governing permissions a nd limitations under 11 * or implied. See the License for the specific language governing permissions a nd limitations under
12 * the License. 12 * the License.
13 */ 13 */
14 package com.google.dart.tools.debug.core.mobile; 14 package com.google.dart.tools.debug.core.mobile;
15 15
16 import com.google.dart.engine.utilities.instrumentation.InstrumentationBuilder; 16 import com.google.dart.engine.utilities.instrumentation.InstrumentationBuilder;
17 import com.google.dart.tools.core.mobile.AndroidDebugBridge; 17 import com.google.dart.tools.core.mobile.AndroidDebugBridge;
18 import com.google.dart.tools.core.mobile.AndroidDevice;
18 import com.google.dart.tools.debug.core.DartDebugCorePlugin; 19 import com.google.dart.tools.debug.core.DartDebugCorePlugin;
19 import com.google.dart.tools.debug.core.DartLaunchConfigWrapper; 20 import com.google.dart.tools.debug.core.DartLaunchConfigWrapper;
20 import com.google.dart.tools.debug.core.DartLaunchConfigurationDelegate; 21 import com.google.dart.tools.debug.core.DartLaunchConfigurationDelegate;
21 import com.google.dart.tools.debug.core.DebugUIHelper; 22 import com.google.dart.tools.debug.core.DebugUIHelper;
22 import com.google.dart.tools.debug.core.pubserve.PubCallback; 23 import com.google.dart.tools.debug.core.pubserve.PubCallback;
23 import com.google.dart.tools.debug.core.pubserve.PubResult; 24 import com.google.dart.tools.debug.core.pubserve.PubResult;
24 import com.google.dart.tools.debug.core.pubserve.PubServeManager; 25 import com.google.dart.tools.debug.core.pubserve.PubServeManager;
26 import com.google.dart.tools.debug.core.pubserve.PubServeResourceResolver;
27 import com.google.dart.tools.debug.core.util.BrowserManager;
28 import com.google.dart.tools.debug.core.util.IRemoteConnectionDelegate;
29 import com.google.dart.tools.debug.core.util.IResourceResolver;
25 import com.google.dart.tools.debug.core.util.ResourceServer; 30 import com.google.dart.tools.debug.core.util.ResourceServer;
26 import com.google.dart.tools.debug.core.util.ResourceServerManager; 31 import com.google.dart.tools.debug.core.util.ResourceServerManager;
32 import com.google.dart.tools.debug.core.webkit.ChromiumTabInfo;
33 import com.google.dart.tools.debug.core.webkit.DefaultChromiumTabChooser;
34 import com.google.dart.tools.debug.core.webkit.IChromiumTabChooser;
27 35
28 import org.eclipse.core.resources.IResource; 36 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.runtime.CoreException; 37 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.IProgressMonitor; 38 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.core.runtime.IStatus; 39 import org.eclipse.core.runtime.IStatus;
40 import org.eclipse.core.runtime.NullProgressMonitor;
32 import org.eclipse.core.runtime.Status; 41 import org.eclipse.core.runtime.Status;
42 import org.eclipse.debug.core.DebugException;
33 import org.eclipse.debug.core.DebugPlugin; 43 import org.eclipse.debug.core.DebugPlugin;
34 import org.eclipse.debug.core.ILaunch; 44 import org.eclipse.debug.core.ILaunch;
35 import org.eclipse.debug.core.ILaunchConfiguration; 45 import org.eclipse.debug.core.ILaunchConfiguration;
46 import org.eclipse.debug.core.model.IDebugTarget;
36 47
37 import java.io.IOException; 48 import java.io.IOException;
38 import java.net.URI; 49 import java.net.URI;
39 import java.net.URISyntaxException; 50 import java.net.URISyntaxException;
51 import java.util.List;
40 52
41 /** 53 /**
42 * A LaunchConfigurationDelegate to launch in the browser on a connected device. 54 * A LaunchConfigurationDelegate to launch in the browser on a connected device.
43 */ 55 */
44 public class MobileLaunchConfigurationDelegate extends DartLaunchConfigurationDe legate { 56 public class MobileLaunchConfigurationDelegate extends DartLaunchConfigurationDe legate implements
57 IRemoteConnectionDelegate {
58
59 /**
60 * A class to choose a tab from the given list of tabs.
61 */
62 public static class ChromeTabChooser implements IChromiumTabChooser {
63 public ChromeTabChooser() {
64
65 }
66
67 @Override
68 public ChromiumTabInfo chooseTab(final List<ChromiumTabInfo> tabs) {
69 if (tabs.size() == 0) {
70 return null;
71 }
72
73 int tabCount = 0;
74
75 for (ChromiumTabInfo tab : tabs) {
76 if (!tab.isChromeExtension()) {
77 tabCount++;
78 }
79 }
80
81 if (tabCount == 1) {
82 return tabs.get(0);
83 }
84
85 for (ChromiumTabInfo tab : tabs) {
86 if (!tab.isChromeExtension()) {
87 return tab;
88 }
89
90 }
91
92 return new DefaultChromiumTabChooser().chooseTab(tabs);
93 }
94 }
45 95
46 private PubCallback<String> pubConnectionCallback = new PubCallback<String>() { 96 private PubCallback<String> pubConnectionCallback = new PubCallback<String>() {
47 @Override 97 @Override
48 public void handleResult(PubResult<String> result) { 98 public void handleResult(PubResult<String> result) {
49 if (result.isError()) { 99 if (result.isError()) {
50 DebugUIHelper.getHelper().showError( 100 DebugUIHelper.getHelper().showError(
51 "Launch Error", 101 "Launch Error",
52 "Pub serve communication error: " + result.getErrorMessage()); 102 "Pub serve communication error: " + result.getErrorMessage());
53 return; 103 return;
54 } 104 }
55 105
56 try { 106 try {
57 String launchUrl = result.getResult(); 107 String launchUrl = result.getResult();
58 launchOnMobile(launchUrl); 108 launchOnMobile(launchUrl, true, new NullProgressMonitor());
59 } catch (CoreException e) { 109 } catch (CoreException e) {
60 DartDebugCorePlugin.logError(e); 110 DartDebugCorePlugin.logError(e);
61 DebugUIHelper.getHelper().showError("Dartium Launch Error", e.getMessage ()); 111 DebugUIHelper.getHelper().showError("Dartium Launch Error", e.getMessage ());
62 } 112 }
63 } 113 }
64 114
65 }; 115 };
66 116
67 private DartLaunchConfigWrapper wrapper; 117 private DartLaunchConfigWrapper wrapper;
68 private static final String DEBUG_PORT = "9222"; 118
119 private static final int REMOTE_DEBUG_PORT = 9224;
69 120
70 @Override 121 @Override
71 public void doLaunch(ILaunchConfiguration configuration, String mode, ILaunch launch, 122 public void doLaunch(ILaunchConfiguration configuration, String mode, ILaunch launch,
72 IProgressMonitor monitor, InstrumentationBuilder instrumentation) throws C oreException { 123 IProgressMonitor monitor, InstrumentationBuilder instrumentation) throws C oreException {
73 124
74 wrapper = new DartLaunchConfigWrapper(configuration); 125 wrapper = new DartLaunchConfigWrapper(configuration);
75 wrapper.markAsLaunched(); 126 wrapper.markAsLaunched();
76 127
77 String launchUrl = ""; 128 String launchUrl = "";
78 129
130 boolean usePubServe = wrapper.getUsePubServe();
131
79 if (wrapper.getShouldLaunchFile()) { 132 if (wrapper.getShouldLaunchFile()) {
80 133
81 IResource resource = wrapper.getApplicationResource(); 134 IResource resource = wrapper.getApplicationResource();
82 if (resource == null) { 135 if (resource == null) {
83 throw new CoreException(new Status( 136 throw new CoreException(new Status(
84 IStatus.ERROR, 137 IStatus.ERROR,
85 DartDebugCorePlugin.PLUGIN_ID, 138 DartDebugCorePlugin.PLUGIN_ID,
86 "Html file could not be found")); 139 "Html file could not be found"));
87 } 140 }
88 141
89 instrumentation.metric("Resource-Class", resource.getClass().toString()); 142 instrumentation.metric("Resource-Class", resource.getClass().toString());
90 instrumentation.data("Resource-Name", resource.getName()); 143 instrumentation.data("Resource-Name", resource.getName());
91 144
92 try { 145 try {
93 boolean usePubServe = true; // TODO(keertip): get from launch config
94 if (usePubServe) { 146 if (usePubServe) {
95 PubServeManager manager = PubServeManager.getManager(); 147 PubServeManager manager = PubServeManager.getManager();
96 148
97 try { 149 try {
98 manager.serve(wrapper, pubConnectionCallback); 150 manager.serve(wrapper, pubConnectionCallback);
99 } catch (Exception e) { 151 } catch (Exception e) {
100 throw new CoreException(new Status( 152 throw new CoreException(new Status(
101 IStatus.ERROR, 153 IStatus.ERROR,
102 DartDebugCorePlugin.PLUGIN_ID, 154 DartDebugCorePlugin.PLUGIN_ID,
103 "Could not start pub serve or connect to pub\n" + manager.getStd ErrorString(), 155 "Could not start pub serve or connect to pub\n" + manager.getStd ErrorString(),
104 e)); 156 e));
105 } 157 }
106 158
107 } else { 159 } else {
108 launchUrl = getUrlFromResourceServer(resource); 160 launchUrl = getUrlFromResourceServer(resource);
109 launchOnMobile(launchUrl); 161 launchOnMobile(launchUrl, usePubServe, monitor);
110 } 162 }
111 163
112 } catch (Exception e) { 164 } catch (Exception e) {
113 throw new CoreException(new Status( 165 throw new CoreException(new Status(
114 IStatus.ERROR, 166 IStatus.ERROR,
115 DartDebugCorePlugin.PLUGIN_ID, 167 DartDebugCorePlugin.PLUGIN_ID,
116 "Unable to launch on device: " + e.getLocalizedMessage(), 168 "Unable to launch on device: " + e.getLocalizedMessage(),
117 e)); 169 e));
118 } 170 }
119 } else { 171 } else {
120 launchUrl = wrapper.getUrl(); 172 launchUrl = wrapper.getUrl();
121 try { 173 try {
122 String scheme = new URI(launchUrl).getScheme(); 174 String scheme = new URI(launchUrl).getScheme();
123 175
124 if (scheme == null) { // add scheme else browser will not launch 176 if (scheme == null) { // add scheme else browser will not launch
125 launchUrl = "http://" + launchUrl; 177 launchUrl = "http://" + launchUrl;
126 launchOnMobile(launchUrl); 178 launchOnMobile(launchUrl, usePubServe, monitor);
127 } 179 }
128 } catch (URISyntaxException e) { 180 } catch (URISyntaxException e) {
129 throw new CoreException(new Status( 181 throw new CoreException(new Status(
130 IStatus.ERROR, 182 IStatus.ERROR,
131 DartDebugCorePlugin.PLUGIN_ID, 183 DartDebugCorePlugin.PLUGIN_ID,
132 "Error in specified url")); 184 "Error in specified url"));
133 } 185 }
134 } 186 }
135 187
136 DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch); 188 DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
137 } 189 }
138 190
139 protected void launchOnMobile(String launchUrl) throws CoreException { 191 @Override
192 public IDebugTarget performRemoteConnection(String host, int port, IProgressMo nitor monitor,
193 boolean usePubServe) throws CoreException {
194
195 BrowserManager browserManager = new BrowserManager();
196
197 IResourceResolver resolver = null;
198 try {
199 resolver = usePubServe ? new PubServeResourceResolver() : ResourceServerMa nager.getServer();
200 } catch (IOException e) {
201 return null;
202 }
203
204 return browserManager.performRemoteConnection(
205 new ChromeTabChooser(),
206 host,
207 port,
208 monitor,
209 resolver);
210
211 }
212
213 protected void launchOnMobile(String launchUrl, boolean usePubServe, IProgress Monitor monitor)
214 throws CoreException {
140 215
141 AndroidDebugBridge devBridge = AndroidDebugBridge.getAndroidDebugBridge(); 216 AndroidDebugBridge devBridge = AndroidDebugBridge.getAndroidDebugBridge();
142 217
143 devBridge.startAdbServer(); 218 devBridge.startAdbServer();
144 String deviceId = devBridge.getConnectedDevice(); 219 AndroidDevice device = devBridge.getConnectedDevice();
145 if (deviceId == null) { 220 if (device == null) {
146 throw new CoreException(new Status( 221 throw new CoreException(new Status(
147 IStatus.ERROR, 222 IStatus.ERROR,
148 DartDebugCorePlugin.PLUGIN_ID, 223 DartDebugCorePlugin.PLUGIN_ID,
149 "No devices detected.\n\nConnect device, enable USB debugging and try again.")); 224 "No devices detected.\n\nConnect device, enable USB debugging and try again."));
150 } 225 }
226 if (device.getDeviceId() == null) {
227 throw new CoreException(new Status(
228 IStatus.ERROR,
229 DartDebugCorePlugin.PLUGIN_ID,
230 "Unauthorized device detected.\n\nAuthorize device and try again."));
231 }
151 232
152 if (wrapper.getLaunchContentShell()) { 233 if (wrapper.getInstallContentShell()) {
153 if (wrapper.getInstallContentShell()) { 234 if (!devBridge.installContentShellApk(device.getDeviceId())) {
154 if (!devBridge.installContentShellApk(deviceId)) { 235 throw new CoreException(new Status(
155 throw new CoreException(new Status( 236 IStatus.ERROR,
156 IStatus.ERROR, 237 DartDebugCorePlugin.PLUGIN_ID,
157 DartDebugCorePlugin.PLUGIN_ID, 238 "Failed to install content shell on mobile"));
158 "Failed to install content shell on mobile"));
159 }
160 } 239 }
161 devBridge.launchContentShell(deviceId, launchUrl); 240 }
162 } else { 241 devBridge.launchContentShell(device.getDeviceId(), launchUrl);
163 devBridge.launchChromeBrowser(launchUrl); 242
243 // check if remote connection is alive
244 if (!isRemoteConnected()) {
245 devBridge.setupPortForwarding(Integer.toString(REMOTE_DEBUG_PORT));
246 // TODO(keertip): check if host needs to be the ip for wifi connections
247 performRemoteConnection("localhost", REMOTE_DEBUG_PORT, monitor, usePubSer ve);
164 } 248 }
165 } 249 }
166 250
167 private String getUrlFromResourceServer(IResource resource) throws IOException , CoreException, 251 private String getUrlFromResourceServer(IResource resource) throws IOException , CoreException,
168 URISyntaxException { 252 URISyntaxException {
169 253
170 ResourceServer server = ResourceServerManager.getServer(); 254 ResourceServer server = ResourceServerManager.getServer();
171 String resPath = resource.getFullPath().toPortableString(); 255 String resPath = resource.getFullPath().toPortableString();
172 String localAddress = server.getLocalAddress(); 256 String localAddress = server.getLocalAddress();
173 if (localAddress == null) { 257 if (localAddress == null) {
174 // TODO (danrubel) Improve UX to help user work through this issue 258 // TODO (danrubel) Improve UX to help user work through this issue
175 throw new CoreException(new Status( 259 throw new CoreException(new Status(
176 IStatus.ERROR, 260 IStatus.ERROR,
177 DartDebugCorePlugin.PLUGIN_ID, 261 DartDebugCorePlugin.PLUGIN_ID,
178 "Unable to get local IP address")); 262 "Unable to get local IP address"));
179 } 263 }
180 264
181 URI uri = new URI("http", null, localAddress, server.getPort(), resPath, nul l, null); 265 URI uri = new URI("http", null, localAddress, server.getPort(), resPath, nul l, null);
182 266
183 String launchUrl = uri.toString(); 267 String launchUrl = uri.toString();
184 launchUrl = wrapper.appendQueryParams(launchUrl); 268 launchUrl = wrapper.appendQueryParams(launchUrl);
185 return launchUrl; 269 return launchUrl;
186 } 270 }
187 271
272 private boolean isRemoteConnected() {
273
274 IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebu gTargets();
275 for (IDebugTarget target : targets) {
276 try {
277 if (target.getName().equals("Remote") && !target.getProcess().isTerminat ed()) {
278 return true;
279 }
280 } catch (DebugException e) {
281
282 }
283 }
284 return false;
285 }
286
188 } 287 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698