| 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 |