Unverified Commit 4f8acd84 authored by Michael Klimushyn's avatar Michael Klimushyn Committed by GitHub

Set `FlutterDevice.viewFilter` by CLI flag (#23026)

`FlutterDevice.views` is limited by a filter. Pipe this filter up as an
option for the commands that instantiate `FlutterDevice`s. This is the
first change necessary for the CLI tooling to target specific isolates
(#22009).

More work needs to be done after this patch.
* Isolate names are dynamically generated and change every restart.
* This just filters views, not background isolates (`VMService.isolates`).
parent e4c2c978
......@@ -37,6 +37,7 @@ final String ipv4Loopback = InternetAddress.loopbackIPv4.address;
class AttachCommand extends FlutterCommand {
AttachCommand({bool verboseHelp = false, this.hotRunnerFactory}) {
addBuildModeFlags(defaultToRelease: false);
usesIsolateFilterOption(hide: !verboseHelp);
usesTargetOption();
usesFilesystemOptions(hide: !verboseHelp);
argParser
......@@ -122,6 +123,7 @@ class AttachCommand extends FlutterCommand {
dillOutputPath: argResults['output-dill'],
fileSystemRoots: argResults['filesystem-root'],
fileSystemScheme: argResults['filesystem-scheme'],
viewFilter: argResults['isolate-filter'],
);
flutterDevice.observatoryUris = <Uri>[ observatoryUri ];
final HotRunner hotRunner = hotRunnerFactory.build(
......
......@@ -338,6 +338,7 @@ class AppDomain extends Domain {
String packagesFilePath,
String dillOutputPath,
bool ipv6 = false,
String isolateFilter,
}) async {
if (await device.isLocalEmulator && !options.buildInfo.supportsEmulator) {
throw '${toTitleCase(options.buildInfo.modeName)} mode is not supported for emulators.';
......@@ -351,6 +352,7 @@ class AppDomain extends Domain {
device,
trackWidgetCreation: trackWidgetCreation,
dillOutputPath: dillOutputPath,
viewFilter: isolateFilter,
);
ResidentRunner runner;
......
......@@ -158,6 +158,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
final FlutterDevice flutterDevice = FlutterDevice(
device,
trackWidgetCreation: false,
viewFilter: isolateName,
);
flutterDevice.observatoryUris = observatoryUris;
final HotRunner hotRunner = HotRunner(<FlutterDevice>[flutterDevice],
......@@ -166,7 +167,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
projectRootPath: _fuchsiaProjectPath,
packagesFilePath: _dotPackagesPath);
printStatus('Connecting to $_modName');
await hotRunner.attach(viewFilter: isolateName);
await hotRunner.attach();
} finally {
await Future.wait<void>(forwardedPorts.map<Future<void>>((_PortForwarder pf) => pf.stop()));
}
......
......@@ -19,6 +19,7 @@ import '../run_hot.dart';
import '../runner/flutter_command.dart';
import 'daemon.dart';
// TODO(flutter/flutter#23031): Test this.
abstract class RunCommandBase extends FlutterCommand {
// Used by run and drive commands.
RunCommandBase({ bool verboseHelp = false }) {
......@@ -46,6 +47,7 @@ abstract class RunCommandBase extends FlutterCommand {
usesTargetOption();
usesPortOptions();
usesPubOption();
usesIsolateFilterOption(hide: !verboseHelp);
}
bool get traceStartup => argResults['trace-startup'];
......@@ -351,6 +353,7 @@ class RunCommand extends RunCommandBase {
dillOutputPath: argResults['output-dill'],
fileSystemRoots: argResults['filesystem-root'],
fileSystemScheme: argResults['filesystem-scheme'],
viewFilter: argResults['isolate-filter'],
);
}).toList();
......
......@@ -34,6 +34,7 @@ class FlutterDevice {
this.dillOutputPath,
this.fileSystemRoots,
this.fileSystemScheme,
this.viewFilter,
ResidentCompiler generator,
}) : generator = generator ?? ResidentCompiler(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
......@@ -51,7 +52,7 @@ class FlutterDevice {
List<String> fileSystemRoots;
String fileSystemScheme;
StreamSubscription<String> _loggingSubscription;
String viewFilter;
final String viewFilter;
/// If the [reloadSources] parameter is not null the 'reloadSources' service
/// will be registered.
......@@ -618,14 +619,12 @@ abstract class ResidentRunner {
/// If the [reloadSources] parameter is not null the 'reloadSources' service
/// will be registered
Future<void> connectToServiceProtocol({String viewFilter,
ReloadSources reloadSources, CompileExpression compileExpression}) async {
Future<void> connectToServiceProtocol({ReloadSources reloadSources, CompileExpression compileExpression}) async {
if (!debuggingOptions.debuggingEnabled)
return Future<void>.error('Error the service protocol is not enabled.');
bool viewFound = false;
for (FlutterDevice device in flutterDevices) {
device.viewFilter = viewFilter;
await device._connect(reloadSources: reloadSources,
compileExpression: compileExpression);
await device.getVMs();
......
......@@ -12,6 +12,7 @@ import 'globals.dart';
import 'resident_runner.dart';
import 'tracing.dart';
// TODO(flutter/flutter#23031): Test this.
class ColdRunner extends ResidentRunner {
ColdRunner(
List<FlutterDevice> devices, {
......
......@@ -41,6 +41,7 @@ HotRunnerConfig get hotRunnerConfig => context[HotRunnerConfig];
const bool kHotReloadDefault = true;
// TODO(flutter/flutter#23031): Test this.
class HotRunner extends ResidentRunner {
HotRunner(
List<FlutterDevice> devices, {
......@@ -152,13 +153,10 @@ class HotRunner extends ResidentRunner {
Future<int> attach({
Completer<DebugConnectionInfo> connectionInfoCompleter,
Completer<void> appStartedCompleter,
String viewFilter,
}) async {
_didAttach = true;
try {
await connectToServiceProtocol(viewFilter: viewFilter,
reloadSources: _reloadSourcesService,
compileExpression: _compileExpressionService);
await connectToServiceProtocol(reloadSources: _reloadSourcesService, compileExpression: _compileExpressionService);
} catch (error) {
printError('Error connecting to the service protocol: $error');
return 2;
......@@ -285,6 +283,12 @@ class HotRunner extends ResidentRunner {
// occurred and tighten this message.
printStatus('Try again after fixing the above error(s).', emphasis: true);
}
} else if (lower == 'l') {
final List<FlutterView> views = flutterDevices.expand((FlutterDevice d) => d.views).toList();
printStatus('Connected ${pluralize('view', views.length)}:');
for (FlutterView v in views) {
printStatus('${v.uiIsolate.name} (${v.uiIsolate.id})', indent: 2);
}
}
}
......
......@@ -166,6 +166,14 @@ abstract class FlutterCommand extends Command<void> {
valueHelp: 'x.y.z');
}
void usesIsolateFilterOption({@required bool hide}) {
argParser.addOption('isolate-filter',
defaultsTo: null,
hide: hide,
help: 'Restricts commands to a subset of the available isolates (running instances of Flutter).\n'
'Normally there\'s only one, but when adding Flutter to a pre-existing app it\'s possible to create multiple.');
}
void addBuildModeFlags({bool defaultToRelease = true, bool verboseHelp = false}) {
defaultBuildMode = defaultToRelease ? BuildMode.release : BuildMode.debug;
......
......@@ -102,6 +102,7 @@ const Duration kLongRequestTimeout = Duration(minutes: 1);
/// Used for RPC requests that should never take a long time.
const Duration kShortRequestTimeout = Duration(seconds: 5);
// TODO(flutter/flutter#23031): Test this.
/// A connection to the Dart VM Service.
class VMService {
VMService._(
......
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