Commit b780c076 authored by Devon Carew's avatar Devon Carew

add --start-paused,--debug-port flags

parent 5a21ef24
...@@ -9,7 +9,9 @@ import 'package:crypto/crypto.dart'; ...@@ -9,7 +9,9 @@ import 'package:crypto/crypto.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/os.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../build_configuration.dart'; import '../build_configuration.dart';
import '../device.dart'; import '../device.dart';
...@@ -33,8 +35,6 @@ class AndroidDeviceDiscovery extends DeviceDiscovery { ...@@ -33,8 +35,6 @@ class AndroidDeviceDiscovery extends DeviceDiscovery {
} }
class AndroidDevice extends Device { class AndroidDevice extends Device {
static const int _observatoryPort = 8181;
static final String defaultDeviceID = 'default_android_device'; static final String defaultDeviceID = 'default_android_device';
String productID; String productID;
...@@ -240,22 +240,37 @@ class AndroidDevice extends Device { ...@@ -240,22 +240,37 @@ class AndroidDevice extends Device {
return true; return true;
} }
void _forwardObservatoryPort() { Future _forwardObservatoryPort(int port) async {
// Set up port forwarding for observatory. bool portWasZero = port == 0;
String portString = 'tcp:$_observatoryPort';
if (port == 0) {
// Auto-bind to a port. Set up forwarding for that port. Emit a stdout
// message similar to the command-line VM, so that tools can parse the output.
// "Observatory listening on http://127.0.0.1:52111"
port = await findAvailablePort();
}
try { try {
runCheckedSync(adbCommandForDevice(<String>['forward', portString, portString])); // Set up port forwarding for observatory.
runCheckedSync(adbCommandForDevice(<String>[
'forward', 'tcp:$port', 'tcp:$observatoryDefaultPort'
]));
if (portWasZero)
printStatus('Observatory listening on http://127.0.0.1:$port');
} catch (e) { } catch (e) {
printError('Unable to forward observatory port ($_observatoryPort):\n$e'); printError('Unable to forward Observatory port $port: $e');
} }
} }
bool startBundle(AndroidApk apk, String bundlePath, { Future<bool> startBundle(AndroidApk apk, String bundlePath, {
bool checked: true, bool checked: true,
bool traceStartup: false, bool traceStartup: false,
String route, String route,
bool clearLogs: false bool clearLogs: false,
}) { bool startPaused: false,
int debugPort: observatoryDefaultPort
}) async {
printTrace('$this startBundle'); printTrace('$this startBundle');
if (!FileSystemEntity.isFileSync(bundlePath)) { if (!FileSystemEntity.isFileSync(bundlePath)) {
...@@ -263,7 +278,7 @@ class AndroidDevice extends Device { ...@@ -263,7 +278,7 @@ class AndroidDevice extends Device {
return false; return false;
} }
_forwardObservatoryPort(); await _forwardObservatoryPort(debugPort);
if (clearLogs) if (clearLogs)
this.clearLogs(); this.clearLogs();
...@@ -280,6 +295,8 @@ class AndroidDevice extends Device { ...@@ -280,6 +295,8 @@ class AndroidDevice extends Device {
cmd.addAll(['--ez', 'enable-checked-mode', 'true']); cmd.addAll(['--ez', 'enable-checked-mode', 'true']);
if (traceStartup) if (traceStartup)
cmd.addAll(['--ez', 'trace-startup', 'true']); cmd.addAll(['--ez', 'trace-startup', 'true']);
if (startPaused)
cmd.addAll(['--ez', 'start-paused', 'true']);
if (route != null) if (route != null)
cmd.addAll(['--es', 'route', route]); cmd.addAll(['--es', 'route', route]);
cmd.add(apk.launchActivity); cmd.add(apk.launchActivity);
...@@ -295,31 +312,35 @@ class AndroidDevice extends Device { ...@@ -295,31 +312,35 @@ class AndroidDevice extends Device {
String route, String route,
bool checked: true, bool checked: true,
bool clearLogs: false, bool clearLogs: false,
bool startPaused: false,
int debugPort: observatoryDefaultPort,
Map<String, dynamic> platformArgs Map<String, dynamic> platformArgs
}) { }) async {
return flx.buildInTempDir( flx.DirectoryResult buildResult = await flx.buildInTempDir(
toolchain, toolchain,
mainPath: mainPath mainPath: mainPath
).then((flx.DirectoryResult buildResult) { );
printTrace('Starting bundle for $this.');
printTrace('Starting bundle for $this.');
try {
if (startBundle( try {
package, if (await startBundle(
buildResult.localBundlePath, package,
checked: checked, buildResult.localBundlePath,
traceStartup: platformArgs['trace-startup'], checked: checked,
route: route, traceStartup: platformArgs['trace-startup'],
clearLogs: clearLogs route: route,
)) { clearLogs: clearLogs,
return true; startPaused: startPaused,
} else { debugPort: debugPort
return false; )) {
} return true;
} finally { } else {
buildResult.dispose(); return false;
} }
}); } finally {
buildResult.dispose();
}
} }
Future<bool> stopApp(ApplicationPackage app) async { Future<bool> stopApp(ApplicationPackage app) async {
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const int observatoryDefaultPort = 8181;
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'dart:io'; import 'dart:io';
final OperatingSystemUtils os = new OperatingSystemUtils._(); final OperatingSystemUtils os = new OperatingSystemUtils._();
...@@ -31,3 +32,10 @@ class _WindowsUtils implements OperatingSystemUtils { ...@@ -31,3 +32,10 @@ class _WindowsUtils implements OperatingSystemUtils {
return new ProcessResult(0, 0, null, null); return new ProcessResult(0, 0, null, null);
} }
} }
Future<int> findAvailablePort() async {
ServerSocket socket = await ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
int port = socket.port;
await socket.close();
return port;
}
...@@ -8,6 +8,7 @@ import 'dart:io'; ...@@ -8,6 +8,7 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../device.dart'; import '../device.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -58,6 +59,13 @@ class StartCommand extends StartCommandBase { ...@@ -58,6 +59,13 @@ class StartCommand extends StartCommandBase {
argParser.addFlag('clear-logs', argParser.addFlag('clear-logs',
defaultsTo: true, defaultsTo: true,
help: 'Clear log history before starting the app.'); help: 'Clear log history before starting the app.');
argParser.addFlag('start-paused',
defaultsTo: false,
negatable: false,
help: 'Start in a paused mode and wait for a debugger to connect.');
argParser.addOption('debug-port',
defaultsTo: observatoryDefaultPort.toString(),
help: 'Listen to the given port for a debug connection.');
} }
@override @override
...@@ -71,6 +79,15 @@ class StartCommand extends StartCommandBase { ...@@ -71,6 +79,15 @@ class StartCommand extends StartCommandBase {
bool clearLogs = argResults['clear-logs']; bool clearLogs = argResults['clear-logs'];
int debugPort;
try {
debugPort = int.parse(argResults['debug-port']);
} catch (error) {
printError('Invalid port for `--debug-port`: $error');
return 1;
}
int result = await startApp( int result = await startApp(
devices, devices,
applicationPackages, applicationPackages,
...@@ -81,7 +98,9 @@ class StartCommand extends StartCommandBase { ...@@ -81,7 +98,9 @@ class StartCommand extends StartCommandBase {
checked: argResults['checked'], checked: argResults['checked'],
traceStartup: argResults['trace-startup'], traceStartup: argResults['trace-startup'],
route: argResults['route'], route: argResults['route'],
clearLogs: clearLogs clearLogs: clearLogs,
startPaused: argResults['start-paused'],
debugPort: debugPort
); );
printTrace('Finished start command.'); printTrace('Finished start command.');
...@@ -99,7 +118,9 @@ Future<int> startApp( ...@@ -99,7 +118,9 @@ Future<int> startApp(
bool checked: true, bool checked: true,
bool traceStartup: false, bool traceStartup: false,
String route, String route,
bool clearLogs: false bool clearLogs: false,
bool startPaused: false,
int debugPort: observatoryDefaultPort
}) async { }) async {
String mainPath = findMainDartFile(target); String mainPath = findMainDartFile(target);
...@@ -144,6 +165,8 @@ Future<int> startApp( ...@@ -144,6 +165,8 @@ Future<int> startApp(
route: route, route: route,
checked: checked, checked: checked,
clearLogs: clearLogs, clearLogs: clearLogs,
startPaused: startPaused,
debugPort: debugPort,
platformArgs: platformArgs platformArgs: platformArgs
); );
......
...@@ -6,6 +6,7 @@ import 'dart:async'; ...@@ -6,6 +6,7 @@ import 'dart:async';
import 'android/device_android.dart'; import 'android/device_android.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'base/common.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'build_configuration.dart'; import 'build_configuration.dart';
import 'ios/device_ios.dart'; import 'ios/device_ios.dart';
...@@ -104,6 +105,8 @@ abstract class Device { ...@@ -104,6 +105,8 @@ abstract class Device {
String route, String route,
bool checked: true, bool checked: true,
bool clearLogs: false, bool clearLogs: false,
bool startPaused: false,
int debugPort: observatoryDefaultPort,
Map<String, dynamic> platformArgs Map<String, dynamic> platformArgs
}); });
......
...@@ -8,6 +8,7 @@ import 'dart:io'; ...@@ -8,6 +8,7 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../build_configuration.dart'; import '../build_configuration.dart';
...@@ -185,9 +186,12 @@ class IOSDevice extends Device { ...@@ -185,9 +186,12 @@ class IOSDevice extends Device {
String route, String route,
bool checked: true, bool checked: true,
bool clearLogs: false, bool clearLogs: false,
bool startPaused: false,
int debugPort: observatoryDefaultPort,
Map<String, dynamic> platformArgs Map<String, dynamic> platformArgs
}) async { }) async {
// TODO(chinmaygarde): Use checked, mainPath, route, clearLogs. // TODO(chinmaygarde): Use checked, mainPath, route, clearLogs.
// TODO(devoncarew): Handle startPaused, debugPort.
printTrace('Building ${app.name} for $id'); printTrace('Building ${app.name} for $id');
// Step 1: Install the precompiled application if necessary // Step 1: Install the precompiled application if necessary
...@@ -431,9 +435,12 @@ class IOSSimulator extends Device { ...@@ -431,9 +435,12 @@ class IOSSimulator extends Device {
String route, String route,
bool checked: true, bool checked: true,
bool clearLogs: false, bool clearLogs: false,
bool startPaused: false,
int debugPort: observatoryDefaultPort,
Map<String, dynamic> platformArgs Map<String, dynamic> platformArgs
}) async { }) async {
// TODO(chinmaygarde): Use checked, mainPath, route. // TODO(chinmaygarde): Use checked, mainPath, route.
// TODO(devoncarew): Handle startPaused, debugPort.
printTrace('Building ${app.name} for $id'); printTrace('Building ${app.name} for $id');
if (clearLogs) if (clearLogs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment