OLD | NEW |
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.ui.internal.mobile; | 14 package com.google.dart.tools.debug.ui.internal.mobile; |
15 | 15 |
16 import com.google.dart.tools.core.mobile.AndroidDebugBridge; | 16 import com.google.dart.tools.core.mobile.AndroidDebugBridge; |
| 17 import com.google.dart.tools.core.mobile.AndroidDevice; |
17 import com.google.dart.tools.core.model.DartSdkManager; | 18 import com.google.dart.tools.core.model.DartSdkManager; |
18 import com.google.dart.tools.debug.core.DartLaunchConfigWrapper; | 19 import com.google.dart.tools.debug.core.DartLaunchConfigWrapper; |
19 import com.google.dart.tools.debug.ui.internal.DartDebugUIPlugin; | 20 import com.google.dart.tools.debug.ui.internal.DartDebugUIPlugin; |
20 import com.google.dart.tools.debug.ui.internal.util.LaunchTargetComposite; | 21 import com.google.dart.tools.debug.ui.internal.util.LaunchTargetComposite; |
21 | 22 |
22 import org.eclipse.debug.core.ILaunchConfiguration; | 23 import org.eclipse.debug.core.ILaunchConfiguration; |
23 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; | 24 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
24 import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; | 25 import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; |
25 import org.eclipse.jface.layout.GridDataFactory; | 26 import org.eclipse.jface.layout.GridDataFactory; |
26 import org.eclipse.jface.layout.GridLayoutFactory; | 27 import org.eclipse.jface.layout.GridLayoutFactory; |
(...skipping 15 matching lines...) Expand all Loading... |
42 | 43 |
43 import java.util.concurrent.atomic.AtomicBoolean; | 44 import java.util.concurrent.atomic.AtomicBoolean; |
44 | 45 |
45 /** | 46 /** |
46 * Main tab for Mobile launch configurations | 47 * Main tab for Mobile launch configurations |
47 */ | 48 */ |
48 public class MobileMainTab extends AbstractLaunchConfigurationTab { | 49 public class MobileMainTab extends AbstractLaunchConfigurationTab { |
49 | 50 |
50 private static final String MOBILE_STATUS_PREFIX = "Mobile status: "; | 51 private static final String MOBILE_STATUS_PREFIX = "Mobile status: "; |
51 private static final String DEVICE_CONNECTED = "Connected"; | 52 private static final String DEVICE_CONNECTED = "Connected"; |
| 53 private static final String DEVICE_NOT_AUTHORIZED = "Connected mobile is not a
uthorized"; |
52 private static final String DEVICE_NOT_FOUND = "No mobile found or USB develop
ment not enabled on mobile"; | 54 private static final String DEVICE_NOT_FOUND = "No mobile found or USB develop
ment not enabled on mobile"; |
53 | 55 |
54 private LaunchTargetComposite launchTargetGroup; | 56 private LaunchTargetComposite launchTargetGroup; |
55 private Button dartBrowserButton; | |
56 private Button installDartBrowserButton; | 57 private Button installDartBrowserButton; |
57 private Label statusLabel; | 58 private Label statusLabel; |
58 | 59 |
59 private boolean deviceConnected = false; | 60 private AndroidDevice connectedDevice = null; |
60 private final AtomicBoolean monitorDeviceConnection = new AtomicBoolean(false)
; | 61 private final AtomicBoolean monitorDeviceConnection = new AtomicBoolean(false)
; |
| 62 private Button usePubServeButton; |
61 | 63 |
62 @Override | 64 @Override |
63 public void activated(ILaunchConfigurationWorkingCopy workingCopy) { | 65 public void activated(ILaunchConfigurationWorkingCopy workingCopy) { |
64 startMonitorDeviceConnectionInBackground(statusLabel.getDisplay()); | 66 startMonitorDeviceConnectionInBackground(statusLabel.getDisplay()); |
65 super.activated(workingCopy); | 67 super.activated(workingCopy); |
66 } | 68 } |
67 | 69 |
68 @Override | 70 @Override |
69 public void createControl(Composite parent) { | 71 public void createControl(Composite parent) { |
70 Composite composite = new Composite(parent, SWT.NONE); | 72 Composite composite = new Composite(parent, SWT.NONE); |
71 GridLayoutFactory.swtDefaults().spacing(1, 3).applyTo(composite); | 73 GridLayoutFactory.swtDefaults().spacing(1, 3).applyTo(composite); |
72 | 74 |
73 launchTargetGroup = new LaunchTargetComposite(composite, SWT.NONE); | 75 launchTargetGroup = new LaunchTargetComposite(composite, SWT.NONE); |
74 launchTargetGroup.addListener(SWT.Modify, new Listener() { | 76 launchTargetGroup.addListener(SWT.Modify, new Listener() { |
75 | 77 |
76 @Override | 78 @Override |
77 public void handleEvent(Event event) { | 79 public void handleEvent(Event event) { |
78 notifyPanelChanged(); | 80 notifyPanelChanged(); |
79 } | 81 } |
80 }); | 82 }); |
81 | 83 |
82 // Browser selection group | 84 // Browser selection group |
83 Group group = new Group(composite, SWT.NONE); | 85 Group group = new Group(composite, SWT.NONE); |
84 group.setText("Browser settings"); | 86 group.setText("Browser settings"); |
85 GridDataFactory.fillDefaults().grab(true, false).applyTo(group); | 87 GridDataFactory.fillDefaults().grab(true, false).applyTo(group); |
86 GridLayoutFactory.swtDefaults().numColumns(3).applyTo(group); | 88 GridLayoutFactory.swtDefaults().numColumns(3).applyTo(group); |
87 ((GridLayout) group.getLayout()).marginBottom = 4; | 89 ((GridLayout) group.getLayout()).marginBottom = 4; |
88 | 90 |
89 dartBrowserButton = new Button(group, SWT.CHECK); | 91 installDartBrowserButton = new Button(group, SWT.CHECK); |
90 dartBrowserButton.setText("Launch in a Dart Content Shell Browser"); | 92 installDartBrowserButton.setText("Automatically install Dart Content Shell B
rowser on first launch"); |
91 dartBrowserButton.addSelectionListener(new SelectionAdapter() { | 93 GridDataFactory.swtDefaults().span(2, 1).grab(true, false).applyTo(installDa
rtBrowserButton); |
| 94 |
| 95 // pub serve setting |
| 96 group = new Group(composite, SWT.NONE); |
| 97 group.setText("Pub settings"); |
| 98 GridDataFactory.fillDefaults().grab(true, false).applyTo(group); |
| 99 GridLayoutFactory.swtDefaults().numColumns(3).applyTo(group); |
| 100 ((GridLayout) group.getLayout()).marginBottom = 5; |
| 101 usePubServeButton = new Button(group, SWT.CHECK); |
| 102 usePubServeButton.setText("Use pub to serve the application"); |
| 103 GridDataFactory.swtDefaults().span(3, 1).applyTo(usePubServeButton); |
| 104 usePubServeButton.addSelectionListener(new SelectionAdapter() { |
92 @Override | 105 @Override |
93 public void widgetSelected(SelectionEvent e) { | 106 public void widgetSelected(SelectionEvent e) { |
94 notifyPanelChanged(); | 107 notifyPanelChanged(); |
95 installDartBrowserButton.setEnabled(dartBrowserButton.getSelection()); | |
96 installDartBrowserButton.setSelection(dartBrowserButton.getSelection()); | |
97 } | 108 } |
98 }); | 109 }); |
99 GridDataFactory.swtDefaults().span(2, 1).grab(true, false).applyTo(dartBrows
erButton); | 110 Label label = new Label(group, SWT.NONE); |
100 | 111 label.setText("(requires port forwarding setup using Chrome > Tools > Inspec
t Devices)"); |
101 installDartBrowserButton = new Button(group, SWT.CHECK); | 112 GridDataFactory.swtDefaults().span(3, 1).indent(18, 0).applyTo(label); |
102 installDartBrowserButton.setText("Automatically install Dart Content Shell B
rowser on first mobile launch"); | |
103 GridDataFactory.swtDefaults().span(2, 1).grab(true, false).indent(20, 0).app
lyTo( | |
104 installDartBrowserButton); | |
105 | 113 |
106 // Status and setup group | 114 // Status and setup group |
107 group = new Group(composite, SWT.NONE); | 115 group = new Group(composite, SWT.NONE); |
108 group.setText("Status and first time setup"); | 116 group.setText("Status and first time setup"); |
109 GridDataFactory.fillDefaults().grab(true, false).applyTo(group); | 117 GridDataFactory.fillDefaults().grab(true, false).applyTo(group); |
110 GridLayoutFactory.swtDefaults().numColumns(1).applyTo(group); | 118 GridLayoutFactory.swtDefaults().numColumns(1).applyTo(group); |
111 ((GridLayout) group.getLayout()).marginBottom = 4; | 119 ((GridLayout) group.getLayout()).marginBottom = 4; |
112 | 120 |
113 statusLabel = new Label(group, SWT.NONE); | 121 statusLabel = new Label(group, SWT.NONE); |
114 GridDataFactory.fillDefaults().grab(true, false).applyTo(statusLabel); | 122 GridDataFactory.fillDefaults().grab(true, false).applyTo(statusLabel); |
(...skipping 17 matching lines...) Expand all Loading... |
132 setControl(null); | 140 setControl(null); |
133 } | 141 } |
134 | 142 |
135 } | 143 } |
136 | 144 |
137 @Override | 145 @Override |
138 public String getErrorMessage() { | 146 public String getErrorMessage() { |
139 if (performSdkCheck() != null) { | 147 if (performSdkCheck() != null) { |
140 return performSdkCheck(); | 148 return performSdkCheck(); |
141 } | 149 } |
142 if (!deviceConnected) { | 150 if (connectedDevice == null) { |
143 return DEVICE_NOT_FOUND; | 151 return DEVICE_NOT_FOUND; |
144 } | 152 } |
| 153 if (!connectedDevice.isAuthorized()) { |
| 154 return DEVICE_NOT_AUTHORIZED; |
| 155 } |
145 return launchTargetGroup.getErrorMessage(); | 156 return launchTargetGroup.getErrorMessage(); |
146 } | 157 } |
147 | 158 |
148 /** | 159 /** |
149 * Answer the image to show in the configuration tab or <code>null</code> if n
one | 160 * Answer the image to show in the configuration tab or <code>null</code> if n
one |
150 */ | 161 */ |
151 @Override | 162 @Override |
152 public Image getImage() { | 163 public Image getImage() { |
153 return DartDebugUIPlugin.getImage("android.png"); //$NON-NLS-1$ | 164 return DartDebugUIPlugin.getImage("android.png"); //$NON-NLS-1$ |
154 } | 165 } |
(...skipping 23 matching lines...) Expand all Loading... |
178 launchTargetGroup.setUrlTextValue(wrapper.getUrl()); | 189 launchTargetGroup.setUrlTextValue(wrapper.getUrl()); |
179 | 190 |
180 launchTargetGroup.setSourceDirectoryTextValue(wrapper.getSourceDirectoryName
()); | 191 launchTargetGroup.setSourceDirectoryTextValue(wrapper.getSourceDirectoryName
()); |
181 | 192 |
182 if (wrapper.getShouldLaunchFile()) { | 193 if (wrapper.getShouldLaunchFile()) { |
183 launchTargetGroup.setHtmlButtonSelection(true); | 194 launchTargetGroup.setHtmlButtonSelection(true); |
184 } else { | 195 } else { |
185 launchTargetGroup.setHtmlButtonSelection(false); | 196 launchTargetGroup.setHtmlButtonSelection(false); |
186 } | 197 } |
187 | 198 |
188 dartBrowserButton.setSelection(wrapper.getLaunchContentShell()); | |
189 installDartBrowserButton.setSelection(wrapper.getInstallContentShell()); | 199 installDartBrowserButton.setSelection(wrapper.getInstallContentShell()); |
| 200 usePubServeButton.setSelection(wrapper.getUsePubServe()); |
190 } | 201 } |
191 | 202 |
192 /** | 203 /** |
193 * Store the value specified in the UI into the launch configuration | 204 * Store the value specified in the UI into the launch configuration |
194 */ | 205 */ |
195 @Override | 206 @Override |
196 public void performApply(ILaunchConfigurationWorkingCopy config) { | 207 public void performApply(ILaunchConfigurationWorkingCopy config) { |
197 | 208 |
198 DartLaunchConfigWrapper wrapper = new DartLaunchConfigWrapper(config); | 209 DartLaunchConfigWrapper wrapper = new DartLaunchConfigWrapper(config); |
199 wrapper.setShouldLaunchFile(launchTargetGroup.getHtmlButtonSelection()); | 210 wrapper.setShouldLaunchFile(launchTargetGroup.getHtmlButtonSelection()); |
200 | 211 |
201 String fileUrl = launchTargetGroup.getHtmlFileName(); | 212 String fileUrl = launchTargetGroup.getHtmlFileName(); |
202 | 213 |
203 if (fileUrl.indexOf('?') == -1) { | 214 if (fileUrl.indexOf('?') == -1) { |
204 wrapper.setApplicationName(fileUrl); | 215 wrapper.setApplicationName(fileUrl); |
205 wrapper.setUrlQueryParams(""); | 216 wrapper.setUrlQueryParams(""); |
206 } else { | 217 } else { |
207 int index = fileUrl.indexOf('?'); | 218 int index = fileUrl.indexOf('?'); |
208 | 219 |
209 wrapper.setApplicationName(fileUrl.substring(0, index)); | 220 wrapper.setApplicationName(fileUrl.substring(0, index)); |
210 wrapper.setUrlQueryParams(fileUrl.substring(index + 1)); | 221 wrapper.setUrlQueryParams(fileUrl.substring(index + 1)); |
211 } | 222 } |
212 | 223 |
213 wrapper.setUrl(launchTargetGroup.getUrlString()); | 224 wrapper.setUrl(launchTargetGroup.getUrlString()); |
214 wrapper.setSourceDirectoryName(launchTargetGroup.getSourceDirectory()); | 225 wrapper.setSourceDirectoryName(launchTargetGroup.getSourceDirectory()); |
215 wrapper.setLaunchContentShell(dartBrowserButton.getSelection()); | |
216 wrapper.setInstallContentShell(installDartBrowserButton.getSelection()); | 226 wrapper.setInstallContentShell(installDartBrowserButton.getSelection()); |
| 227 wrapper.setUsePubServe(usePubServeButton.getSelection()); |
217 } | 228 } |
218 | 229 |
219 @Override | 230 @Override |
220 public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { | 231 public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { |
221 DartLaunchConfigWrapper wrapper = new DartLaunchConfigWrapper(configuration)
; | 232 DartLaunchConfigWrapper wrapper = new DartLaunchConfigWrapper(configuration)
; |
222 wrapper.setShouldLaunchFile(true); | 233 wrapper.setShouldLaunchFile(true); |
223 wrapper.setApplicationName(""); //$NON-NLS-1$ | 234 wrapper.setApplicationName(""); //$NON-NLS-1$ |
224 wrapper.setLaunchContentShell(true); | 235 wrapper.setLaunchContentShell(true); |
| 236 wrapper.setUsePubServe(false); |
225 } | 237 } |
226 | 238 |
227 private void notifyPanelChanged() { | 239 private void notifyPanelChanged() { |
228 setDirty(true); | 240 setDirty(true); |
229 updateLaunchConfigurationDialog(); | 241 updateLaunchConfigurationDialog(); |
230 } | 242 } |
231 | 243 |
232 private String performSdkCheck() { | 244 private String performSdkCheck() { |
233 if (!DartSdkManager.getManager().hasSdk()) { | 245 if (!DartSdkManager.getManager().hasSdk()) { |
234 return "Dart SDK is not installed (" | 246 return "Dart SDK is not installed (" |
235 + DartSdkManager.getManager().getSdk().getDart2JsExecutable() + ")"; | 247 + DartSdkManager.getManager().getSdk().getDart2JsExecutable() + ")"; |
236 } else { | 248 } else { |
237 return null; | 249 return null; |
238 } | 250 } |
239 } | 251 } |
240 | 252 |
241 /** | 253 /** |
242 * Start the background process that monitors device connection via ADB | 254 * Start the background process that monitors device connection via ADB |
243 */ | 255 */ |
244 private void startMonitorDeviceConnectionInBackground(final Display display) { | 256 private void startMonitorDeviceConnectionInBackground(final Display display) { |
245 if (!monitorDeviceConnection.get()) { | 257 if (!monitorDeviceConnection.get()) { |
246 monitorDeviceConnection.set(true); | 258 monitorDeviceConnection.set(true); |
247 Thread thread = new Thread("Monitor mobile connection") { | 259 Thread thread = new Thread("Monitor mobile connection") { |
248 @Override | 260 @Override |
249 public void run() { | 261 public void run() { |
250 | 262 |
251 AndroidDebugBridge devBridge = AndroidDebugBridge.getAndroidDebugBridg
e(); | 263 AndroidDebugBridge devBridge = AndroidDebugBridge.getAndroidDebugBridg
e(); |
252 boolean wasDeviceConnected = devBridge.getConnectedDevice() != null; | 264 AndroidDevice oldDevice = devBridge.getConnectedDevice(); |
253 update(wasDeviceConnected); | 265 update(oldDevice); |
254 | 266 |
255 while (monitorDeviceConnection.get()) { | 267 while (monitorDeviceConnection.get()) { |
256 final boolean isDeviceConnected = devBridge.getConnectedDevice() !=
null; | 268 AndroidDevice newDevice = devBridge.getConnectedDevice(); |
257 if (wasDeviceConnected != isDeviceConnected) { | 269 if (!AndroidDevice.isEqual(oldDevice, newDevice)) { |
258 wasDeviceConnected = isDeviceConnected; | 270 oldDevice = newDevice; |
259 update(isDeviceConnected); | 271 update(oldDevice); |
260 } | 272 } |
261 try { | 273 try { |
262 Thread.sleep(1000); | 274 Thread.sleep(1000); |
263 } catch (InterruptedException e) { | 275 } catch (InterruptedException e) { |
264 //$FALL-THROUGH$ | 276 //$FALL-THROUGH$ |
265 } | 277 } |
266 } | 278 } |
267 } | 279 } |
268 | 280 |
269 private void update(final boolean isDeviceConnected) { | 281 private void update(final AndroidDevice device) { |
270 display.asyncExec(new Runnable() { | 282 display.asyncExec(new Runnable() { |
271 @Override | 283 @Override |
272 public void run() { | 284 public void run() { |
273 updateMobileStatus(isDeviceConnected); | 285 updateMobileStatus(device); |
274 } | 286 } |
275 }); | 287 }); |
276 } | 288 } |
277 }; | 289 }; |
278 thread.setDaemon(true); | 290 thread.setDaemon(true); |
279 thread.start(); | 291 thread.start(); |
280 } | 292 } |
281 } | 293 } |
282 | 294 |
283 /** | 295 /** |
284 * Stop the background process that monitors device connection via ADB | 296 * Stop the background process that monitors device connection via ADB |
285 */ | 297 */ |
286 private void stopMonitorDeviceConnectionInBackground() { | 298 private void stopMonitorDeviceConnectionInBackground() { |
287 monitorDeviceConnection.set(false); | 299 monitorDeviceConnection.set(false); |
288 } | 300 } |
289 | 301 |
290 /** | 302 /** |
291 * Update the mobile status. Must be called on the UI thread. | 303 * Update the mobile status. Must be called on the UI thread. |
292 * | 304 * |
293 * @param isDeviceConnected {@code true} if a mobile device is currently conne
cted | 305 * @param isDeviceConnected {@code true} if a mobile device is currently conne
cted |
294 */ | 306 */ |
295 private void updateMobileStatus(boolean isDeviceConnected) { | 307 private void updateMobileStatus(AndroidDevice device) { |
296 deviceConnected = isDeviceConnected; | 308 connectedDevice = device; |
297 if (statusLabel != null && !statusLabel.isDisposed()) { | 309 if (statusLabel != null && !statusLabel.isDisposed()) { |
298 statusLabel.setText(MOBILE_STATUS_PREFIX | 310 String status; |
299 + (deviceConnected ? DEVICE_CONNECTED : DEVICE_NOT_FOUND)); | 311 if (device == null) { |
| 312 status = DEVICE_NOT_FOUND; |
| 313 } else if (!device.isAuthorized()) { |
| 314 status = DEVICE_NOT_AUTHORIZED; |
| 315 } else { |
| 316 status = DEVICE_CONNECTED; |
| 317 } |
| 318 statusLabel.setText(MOBILE_STATUS_PREFIX + status); |
300 updateLaunchConfigurationDialog(); | 319 updateLaunchConfigurationDialog(); |
301 } | 320 } |
302 } | 321 } |
303 } | 322 } |
OLD | NEW |