Allow filtering devices to only those supported by current project (#31446)
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index 83a651a..e6cfdac 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -535,6 +535,11 @@ await runCheckedAsync(adbCommandForDevice(<String>['pull', remotePath, outputFile.path])); await runCheckedAsync(adbCommandForDevice(<String>['shell', 'rm', remotePath])); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.android.existsSync(); + } } Map<String, String> parseAdbDeviceProperties(String str) {
diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index bf98583..9fca77e 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart
@@ -243,6 +243,7 @@ final bool useHot = getBuildInfo().isDebug; final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: argResults['track-widget-creation'], dillOutputPath: argResults['output-dill'], fileSystemRoots: argResults['filesystem-root'],
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index c7e7b9e..f9fbc24 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -19,6 +19,7 @@ import '../device.dart'; import '../emulator.dart'; import '../globals.dart'; +import '../project.dart'; import '../resident_runner.dart'; import '../run_cold.dart'; import '../run_hot.dart'; @@ -344,9 +345,11 @@ // We change the current working directory for the duration of the `start` command. final Directory cwd = fs.currentDirectory; fs.currentDirectory = fs.directory(projectDirectory); + final FlutterProject flutterProject = await FlutterProject.current(); final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: trackWidgetCreation, dillOutputPath: dillOutputPath, viewFilter: isolateFilter,
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index ba5be91..80771e8 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -13,6 +13,7 @@ import '../device.dart'; import '../globals.dart'; import '../ios/mac.dart'; +import '../project.dart'; import '../resident_runner.dart'; import '../run_cold.dart'; import '../run_hot.dart'; @@ -364,9 +365,11 @@ expFlags = argResults[FlutterOptions.kEnableExperiment]; } final List<FlutterDevice> flutterDevices = <FlutterDevice>[]; + final FlutterProject flutterProject = await FlutterProject.current(); for (Device device in devices) { final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: argResults['track-widget-creation'], dillOutputPath: argResults['output-dill'], fileSystemRoots: argResults['filesystem-root'],
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 29bb3e7..028894e 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart
@@ -19,6 +19,7 @@ import 'ios/simulators.dart'; import 'linux/linux_device.dart'; import 'macos/macos_device.dart'; +import 'project.dart'; import 'tester/flutter_tester.dart'; import 'web/web_device.dart'; import 'windows/windows_device.dart'; @@ -235,6 +236,9 @@ } } + /// Whether the device is supported for the current project directory. + bool isSupportedForProject(FlutterProject flutterProject); + /// Check if a version of the given app is already installed Future<bool> isAppInstalled(ApplicationPackage app);
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart index 9aa1fb5..c7b1ba8 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
@@ -17,6 +17,7 @@ import '../build_info.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../vmservice.dart'; import 'fuchsia_sdk.dart'; @@ -302,6 +303,9 @@ } FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol(String isolateName) => FuchsiaIsolateDiscoveryProtocol(this, isolateName); + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class FuchsiaIsolateDiscoveryProtocol {
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index d469da1..02ede71 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -17,6 +17,7 @@ import '../convert.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import 'code_signing.dart'; import 'ios_workflow.dart'; @@ -401,6 +402,11 @@ Future<void> takeScreenshot(File outputFile) async { await iMobileDevice.takeScreenshot(outputFile); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.ios.existsSync(); + } } /// Decodes a vis-encoded syslog string to a UTF-8 representation.
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index a60ba54..9573dfe 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -19,6 +19,7 @@ import '../convert.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import 'ios_workflow.dart'; import 'mac.dart'; @@ -473,6 +474,11 @@ Future<void> takeScreenshot(File outputFile) { return SimControl.instance.takeScreenshot(id, outputFile.path); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.ios.existsSync(); + } } /// Launches the device log reader process on the host.
diff --git a/packages/flutter_tools/lib/src/linux/linux_device.dart b/packages/flutter_tools/lib/src/linux/linux_device.dart index d98afc4..5c50a94 100644 --- a/packages/flutter_tools/lib/src/linux/linux_device.dart +++ b/packages/flutter_tools/lib/src/linux/linux_device.dart
@@ -108,6 +108,11 @@ @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.linux.existsSync(); + } + // Track the last built mode from startApp. BuildMode _lastBuiltMode; }
diff --git a/packages/flutter_tools/lib/src/macos/macos_device.dart b/packages/flutter_tools/lib/src/macos/macos_device.dart index b3309bb..79cdb6f 100644 --- a/packages/flutter_tools/lib/src/macos/macos_device.dart +++ b/packages/flutter_tools/lib/src/macos/macos_device.dart
@@ -117,6 +117,11 @@ // to uninstall the application. @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.macos.existsSync(); + } } class MacOSDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 641c281..2f132de 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart
@@ -208,8 +208,6 @@ Directory get _ephemeralDirectory => parent.directory.childDirectory('.ios'); Directory get _editableDirectory => parent.directory.childDirectory('ios'); - bool existsSync() => parent.isModule || _editableDirectory.existsSync(); - /// This parent folder of `Runner.xcodeproj`. Directory get hostAppRoot { if (!isModule || _editableDirectory.existsSync()) @@ -264,6 +262,11 @@ /// Xcode workspace shared workspace settings file for the host app. File get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData.childFile('WorkspaceSettings.xcsettings'); + /// Whether the current flutter project has an iOS subproject. + bool existsSync() { + return parent.isModule || _editableDirectory.existsSync(); + } + /// The product bundle identifier of the host app, or null if not set or if /// iOS tooling needed to read it is not installed. String get productBundleIdentifier { @@ -391,8 +394,6 @@ return _ephemeralDirectory; } - bool existsSync() => parent.isModule || _flutterLibGradleRoot.existsSync(); - /// The Gradle root directory of the Android wrapping of Flutter and plugins. /// This is the same as [hostAppGradleRoot] except when the project is /// a Flutter module with an editable host app. @@ -420,6 +421,11 @@ return fs.directory(fs.path.join(hostAppGradleRoot.path, 'app', 'build', 'outputs', 'bundle')); } + /// Whether the current flutter project has an Android sub-project. + bool existsSync() { + return parent.isModule || _editableHostAppDirectory.existsSync(); + } + bool get isUsingGradle { return hostAppGradleRoot.childFile('build.gradle').existsSync(); } @@ -498,7 +504,10 @@ final FlutterProject parent; - bool existsSync() => parent.directory.childDirectory('web').existsSync(); + /// Whether this flutter project has a web sub-project. + bool existsSync() { + return parent.directory.childDirectory('web').existsSync(); + } Future<void> ensureReadyForPlatformSpecificTooling() async { /// Generate index.html in build/web. Eventually we could support @@ -590,4 +599,4 @@ /// The Linux project makefile. File get makeFile => editableHostAppDirectory.childFile('Makefile'); -} \ No newline at end of file +}
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 3325255..8725555 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -52,6 +52,7 @@ /// Create a [FlutterDevice] with optional code generation enabled. static Future<FlutterDevice> create( Device device, { + @required FlutterProject flutterProject, @required bool trackWidgetCreation, String dillOutputPath, List<String> fileSystemRoots, @@ -64,7 +65,6 @@ @required BuildMode buildMode, }) async { ResidentCompiler generator; - final FlutterProject flutterProject = await FlutterProject.current(); if (flutterProject.hasBuilders) { generator = await CodeGeneratingResidentCompiler.create( flutterProject: flutterProject,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 5aae159..4b5706c 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -527,6 +527,13 @@ } devices = devices.where((Device device) => device.isSupported()).toList(); + // If the user has not specified all devices and has multiple connected + // then filter then list by those supported in the current project. If + // this ends up with a single device we can proceed as normal. + if (devices.length > 1 && !deviceManager.hasSpecifiedAllDevices && !deviceManager.hasSpecifiedDeviceId) { + final FlutterProject flutterProject = await FlutterProject.current(); + devices.removeWhere((Device device) => !device.isSupportedForProject(flutterProject)); + } if (devices.isEmpty) { printStatus(userMessages.flutterNoSupportedDevices);
diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart index 14c5d3e..988fbeb 100644 --- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart +++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
@@ -18,6 +18,7 @@ import '../dart/package_map.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import '../version.dart'; @@ -192,6 +193,9 @@ @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class FlutterTesterDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart index fd78729..fd47dfa 100644 --- a/packages/flutter_tools/lib/src/web/web_device.dart +++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -166,6 +166,11 @@ await request.response.addStream(file.openRead()); await request.response.close(); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.web.existsSync(); + } } class WebDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/windows/windows_device.dart b/packages/flutter_tools/lib/src/windows/windows_device.dart index 9843dea..50a96a4 100644 --- a/packages/flutter_tools/lib/src/windows/windows_device.dart +++ b/packages/flutter_tools/lib/src/windows/windows_device.dart
@@ -114,6 +114,11 @@ // to uninstall the application. @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.windows.existsSync(); + } } class WindowsDevices extends PollingDeviceDiscovery {