diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 9735c4bd1c3..ac7c2927cb5 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -826,21 +826,17 @@ class DeviceDomain extends Domain { } /// Enable device events. - Future enable(Map args) { - final List> calls = >[]; + Future enable(Map args) async { for (final PollingDeviceDiscovery discoverer in _discoverers) { - calls.add(discoverer.startPolling()); + discoverer.startPolling(); } - return Future.wait(calls); } /// Disable device events. Future disable(Map args) async { - final List> calls = >[]; for (final PollingDeviceDiscovery discoverer in _discoverers) { - calls.add(discoverer.stopPolling()); + discoverer.stopPolling(); } - return Future.wait(calls); } /// Forward a host port to a device port. @@ -874,10 +870,11 @@ class DeviceDomain extends Domain { } @override - Future dispose() async { + Future dispose() { for (final PollingDeviceDiscovery discoverer in _discoverers) { - await discoverer.dispose(); + discoverer.dispose(); } + return Future.value(); } /// Return the device matching the deviceId field in the args. diff --git a/packages/flutter_tools/lib/src/commands/logs.dart b/packages/flutter_tools/lib/src/commands/logs.dart index 5305e14c4db..058779ff3c9 100644 --- a/packages/flutter_tools/lib/src/commands/logs.dart +++ b/packages/flutter_tools/lib/src/commands/logs.dart @@ -34,7 +34,7 @@ class LogsCommand extends FlutterCommand { @override Future verifyThenRunCommand(String commandPath) async { - device = await findTargetDevice(); + device = await findTargetDevice(includeUnsupportedDevices: true); if (device == null) { throwToolExit(null); } diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 2e7b2190430..cdc2c70a396 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -77,7 +77,7 @@ class PlatformType { String toString() => value; } -/// A class to get all available devices. +/// A disovery mechanism for flutter-supported development devices. abstract class DeviceManager { /// Constructing DeviceManagers is cheap; they only do expensive work if some @@ -210,6 +210,9 @@ abstract class DeviceManager { /// * If the user did not specify a device id and there is more than one /// device connected, then filter out unsupported devices and prioritize /// ephemeral devices. + /// + /// * If [flutterProject] is null, then assume the project supports all + /// device types. Future> findTargetDevices(FlutterProject flutterProject, { Duration timeout }) async { if (timeout != null) { // Reset the cache with the specified timeout. @@ -310,8 +313,12 @@ abstract class DeviceManager { /// Returns whether the device is supported for the project. /// - /// This exists to allow the check to be overridden for google3 clients. + /// This exists to allow the check to be overridden for google3 clients. If + /// [flutterProject] is null then return true. bool isDeviceSupportedForProject(Device device, FlutterProject flutterProject) { + if (flutterProject == null) { + return true; + } return device.isSupportedForProject(flutterProject); } } @@ -428,7 +435,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery { Future> pollingGetDevices({ Duration timeout }); - Future startPolling() async { + void startPolling() { if (_timer == null) { deviceNotifier ??= ItemListNotifier(); // Make initial population the default, fast polling timeout. @@ -449,18 +456,18 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery { }); } - Future stopPolling() async { + void stopPolling() { _timer?.cancel(); _timer = null; } @override - Future> get devices async { + Future> get devices { return _populateDevices(); } @override - Future> discoverDevices({ Duration timeout }) async { + Future> discoverDevices({ Duration timeout }) { deviceNotifier = null; return _populateDevices(timeout: timeout); } @@ -480,7 +487,7 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery { return deviceNotifier.onRemoved; } - Future dispose() async => await stopPolling(); + void dispose() => stopPolling(); @override String toString() => '$name device discovery'; diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 80085f402ce..1e3ab0fe63f 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1005,13 +1005,18 @@ abstract class FlutterCommand extends Command { /// devices and criteria entered by the user on the command line. /// If no device can be found that meets specified criteria, /// then print an error message and return null. - Future> findAllTargetDevices() async { + Future> findAllTargetDevices({ + bool includeUnsupportedDevices = false, + }) async { if (!globals.doctor.canLaunchAnything) { globals.printError(userMessages.flutterNoDevelopmentDevice); return null; } final DeviceManager deviceManager = globals.deviceManager; - List devices = await deviceManager.findTargetDevices(FlutterProject.current(), timeout: deviceDiscoveryTimeout); + List devices = await deviceManager.findTargetDevices( + includeUnsupportedDevices ? null : FlutterProject.current(), + timeout: deviceDiscoveryTimeout, + ); if (devices.isEmpty && deviceManager.hasSpecifiedDeviceId) { globals.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId)); @@ -1057,8 +1062,13 @@ abstract class FlutterCommand extends Command { /// devices and criteria entered by the user on the command line. /// If a device cannot be found that meets specified criteria, /// then print an error message and return null. - Future findTargetDevice() async { - List deviceList = await findAllTargetDevices(); + /// + /// If [includeUnsupportedDevices] is true, the tool does not filter + /// the list by the current project support list. + Future findTargetDevice({ + bool includeUnsupportedDevices = false, + }) async { + List deviceList = await findAllTargetDevices(includeUnsupportedDevices: includeUnsupportedDevices); if (deviceList == null) { return null; } diff --git a/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart b/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart index af6b98232ad..a7c902a3a3a 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart @@ -79,6 +79,4 @@ void main() { }); } -class MockDeviceManager extends Mock implements DeviceManager { - -} +class MockDeviceManager extends Mock implements DeviceManager {} diff --git a/packages/flutter_tools/test/general.shard/device_test.dart b/packages/flutter_tools/test/general.shard/device_test.dart index 4c59dbe5481..5067cdf1440 100644 --- a/packages/flutter_tools/test/general.shard/device_test.dart +++ b/packages/flutter_tools/test/general.shard/device_test.dart @@ -137,26 +137,26 @@ void main() { }); group('PollingDeviceDiscovery', () { - testUsingContext('startPolling', () async { - await FakeAsync().run((FakeAsync time) async { + testUsingContext('startPolling', () { + FakeAsync().run((FakeAsync time) { final FakePollingDeviceDiscovery pollingDeviceDiscovery = FakePollingDeviceDiscovery(); - await pollingDeviceDiscovery.startPolling(); + pollingDeviceDiscovery.startPolling(); time.elapse(const Duration(milliseconds: 4001)); - time.flushMicrotasks(); + // First check should use the default polling timeout // to quickly populate the list. expect(pollingDeviceDiscovery.lastPollingTimeout, isNull); time.elapse(const Duration(milliseconds: 4001)); - time.flushMicrotasks(); + // Subsequent polling should be much longer. expect(pollingDeviceDiscovery.lastPollingTimeout, const Duration(seconds: 30)); - await pollingDeviceDiscovery.stopPolling(); + pollingDeviceDiscovery.stopPolling(); }); }, overrides: { Artifacts: () => Artifacts.test(), Cache: () => cache, - }, skip: true); // TODO(jonahwilliams): clean up with https://github.com/flutter/flutter/issues/60675 + }); }); group('Filter devices', () { @@ -369,6 +369,20 @@ void main() { Cache: () => cache, }); + testUsingContext('Does not remove an unsupported device if FlutterProject is null', () async { + final List devices = [ + unsupported, + ]; + + final DeviceManager deviceManager = TestDeviceManager(devices); + final List filtered = await deviceManager.findTargetDevices(null); + + expect(filtered, [unsupported]); + }, overrides: { + Artifacts: () => Artifacts.test(), + Cache: () => cache, + }); + testUsingContext('Removes web and fuchsia from --all', () async { final List devices = [ webDevice, @@ -428,9 +442,7 @@ void main() { ]; final MockDeviceDiscovery mockDeviceDiscovery = MockDeviceDiscovery(); when(mockDeviceDiscovery.supportsPlatform).thenReturn(true); - // when(mockDeviceDiscovery.discoverDevices(timeout: timeout)).thenAnswer((_) async => devices); when(mockDeviceDiscovery.devices).thenAnswer((_) async => devices); - // when(mockDeviceDiscovery.discoverDevices(timeout: timeout)).thenAnswer((_) async => devices); final DeviceManager deviceManager = TestDeviceManager([], deviceDiscoveryOverrides: [ mockDeviceDiscovery @@ -457,7 +469,6 @@ void main() { when(mockDeviceDiscovery.supportsPlatform).thenReturn(true); when(mockDeviceDiscovery.discoverDevices(timeout: timeout)).thenAnswer((_) async => devices); when(mockDeviceDiscovery.devices).thenAnswer((_) async => devices); - // when(mockDeviceDiscovery.discoverDevices(timeout: timeout)).thenAnswer((_) async => devices); final DeviceManager deviceManager = TestDeviceManager([], deviceDiscoveryOverrides: [ mockDeviceDiscovery diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart index 461121d6973..83fbb84b383 100644 --- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart @@ -515,7 +515,7 @@ void main() { expect(iosDevices.deviceNotifier.items, isEmpty); expect(eventStream.hasListener, isTrue); - await iosDevices.dispose(); + iosDevices.dispose(); expect(eventStream.hasListener, isFalse); });