Unverified Commit dbc18bbd authored by Victoria Ashworth's avatar Victoria Ashworth Committed by GitHub

Add flag to filter by device connection interface (#124034)

Add flag to filter by device connection interface
parent b2c65acd
...@@ -140,6 +140,7 @@ class AttachCommand extends FlutterCommand { ...@@ -140,6 +140,7 @@ class AttachCommand extends FlutterCommand {
addDevToolsOptions(verboseHelp: verboseHelp); addDevToolsOptions(verboseHelp: verboseHelp);
addServeObservatoryOptions(verboseHelp: verboseHelp); addServeObservatoryOptions(verboseHelp: verboseHelp);
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
} }
final HotRunnerFactory _hotRunnerFactory; final HotRunnerFactory _hotRunnerFactory;
......
...@@ -25,6 +25,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -25,6 +25,7 @@ class DevicesCommand extends FlutterCommand {
hide: !verboseHelp, hide: !verboseHelp,
); );
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
} }
@override @override
...@@ -70,6 +71,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -70,6 +71,7 @@ class DevicesCommand extends FlutterCommand {
logger: globals.logger, logger: globals.logger,
deviceManager: globals.deviceManager, deviceManager: globals.deviceManager,
deviceDiscoveryTimeout: deviceDiscoveryTimeout, deviceDiscoveryTimeout: deviceDiscoveryTimeout,
deviceConnectionInterface: deviceConnectionInterface,
); );
await output.findAndOutputAllTargetDevices( await output.findAndOutputAllTargetDevices(
...@@ -86,18 +88,21 @@ class DevicesCommandOutput { ...@@ -86,18 +88,21 @@ class DevicesCommandOutput {
required Logger logger, required Logger logger,
DeviceManager? deviceManager, DeviceManager? deviceManager,
Duration? deviceDiscoveryTimeout, Duration? deviceDiscoveryTimeout,
DeviceConnectionInterface? deviceConnectionInterface,
}) { }) {
if (platform.isMacOS) { if (platform.isMacOS) {
return DevicesCommandOutputWithExtendedWirelessDeviceDiscovery( return DevicesCommandOutputWithExtendedWirelessDeviceDiscovery(
logger: logger, logger: logger,
deviceManager: deviceManager, deviceManager: deviceManager,
deviceDiscoveryTimeout: deviceDiscoveryTimeout, deviceDiscoveryTimeout: deviceDiscoveryTimeout,
deviceConnectionInterface: deviceConnectionInterface,
); );
} }
return DevicesCommandOutput._private( return DevicesCommandOutput._private(
logger: logger, logger: logger,
deviceManager: deviceManager, deviceManager: deviceManager,
deviceDiscoveryTimeout: deviceDiscoveryTimeout, deviceDiscoveryTimeout: deviceDiscoveryTimeout,
deviceConnectionInterface: deviceConnectionInterface,
); );
} }
...@@ -105,14 +110,27 @@ class DevicesCommandOutput { ...@@ -105,14 +110,27 @@ class DevicesCommandOutput {
required Logger logger, required Logger logger,
required DeviceManager? deviceManager, required DeviceManager? deviceManager,
required this.deviceDiscoveryTimeout, required this.deviceDiscoveryTimeout,
required this.deviceConnectionInterface,
}) : _deviceManager = deviceManager, }) : _deviceManager = deviceManager,
_logger = logger; _logger = logger;
final DeviceManager? _deviceManager; final DeviceManager? _deviceManager;
final Logger _logger; final Logger _logger;
final Duration? deviceDiscoveryTimeout; final Duration? deviceDiscoveryTimeout;
final DeviceConnectionInterface? deviceConnectionInterface;
bool get _includeAttachedDevices =>
deviceConnectionInterface == null ||
deviceConnectionInterface == DeviceConnectionInterface.attached;
bool get _includeWirelessDevices =>
deviceConnectionInterface == null ||
deviceConnectionInterface == DeviceConnectionInterface.wireless;
Future<List<Device>> _getAttachedDevices(DeviceManager deviceManager) async { Future<List<Device>> _getAttachedDevices(DeviceManager deviceManager) async {
if (!_includeAttachedDevices) {
return <Device>[];
}
return deviceManager.getAllDevices( return deviceManager.getAllDevices(
filter: DeviceDiscoveryFilter( filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.attached, deviceConnectionInterface: DeviceConnectionInterface.attached,
...@@ -121,6 +139,9 @@ class DevicesCommandOutput { ...@@ -121,6 +139,9 @@ class DevicesCommandOutput {
} }
Future<List<Device>> _getWirelessDevices(DeviceManager deviceManager) async { Future<List<Device>> _getWirelessDevices(DeviceManager deviceManager) async {
if (!_includeWirelessDevices) {
return <Device>[];
}
return deviceManager.getAllDevices( return deviceManager.getAllDevices(
filter: DeviceDiscoveryFilter( filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.wireless, deviceConnectionInterface: DeviceConnectionInterface.wireless,
...@@ -207,19 +228,22 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom ...@@ -207,19 +228,22 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom
required super.logger, required super.logger,
super.deviceManager, super.deviceManager,
super.deviceDiscoveryTimeout, super.deviceDiscoveryTimeout,
super.deviceConnectionInterface,
}) : super._private(); }) : super._private();
@override @override
Future<void> findAndOutputAllTargetDevices({required bool machine}) async { Future<void> findAndOutputAllTargetDevices({required bool machine}) async {
// When a user defines the timeout, use the super function that does not do // When a user defines the timeout or filters to only attached devices,
// longer wireless device discovery. // use the super function that does not do longer wireless device discovery.
if (deviceDiscoveryTimeout != null) { if (deviceDiscoveryTimeout != null || deviceConnectionInterface == DeviceConnectionInterface.attached) {
return super.findAndOutputAllTargetDevices(machine: machine); return super.findAndOutputAllTargetDevices(machine: machine);
} }
if (machine) { if (machine) {
final List<Device> devices = await _deviceManager?.refreshAllDevices( final List<Device> devices = await _deviceManager?.refreshAllDevices(
filter: DeviceDiscoveryFilter(), filter: DeviceDiscoveryFilter(
deviceConnectionInterface: deviceConnectionInterface,
),
timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout, timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout,
) ?? <Device>[]; ) ?? <Device>[];
await printDevicesAsJson(devices); await printDevicesAsJson(devices);
...@@ -249,7 +273,7 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom ...@@ -249,7 +273,7 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom
} }
// Display waiting message. // Display waiting message.
if (attachedDevices.isEmpty) { if (attachedDevices.isEmpty && _includeAttachedDevices) {
_logger.printStatus(_noAttachedCheckForWireless); _logger.printStatus(_noAttachedCheckForWireless);
} else { } else {
_logger.printStatus(_checkingForWirelessDevicesMessage); _logger.printStatus(_checkingForWirelessDevicesMessage);
...@@ -265,7 +289,7 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom ...@@ -265,7 +289,7 @@ class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCom
waitingStatus.stop(); waitingStatus.stop();
final Terminal terminal = _logger.terminal; final Terminal terminal = _logger.terminal;
if (_logger.isVerbose) { if (_logger.isVerbose && _includeAttachedDevices) {
// Reprint the attach devices. // Reprint the attach devices.
if (attachedDevices.isNotEmpty) { if (attachedDevices.isNotEmpty) {
_logger.printStatus('\n${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n'); _logger.printStatus('\n${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
......
...@@ -19,6 +19,7 @@ class InstallCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts ...@@ -19,6 +19,7 @@ class InstallCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts
requiresPubspecYaml(); requiresPubspecYaml();
usesApplicationBinaryOption(); usesApplicationBinaryOption();
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
usesDeviceUserOption(); usesDeviceUserOption();
usesFlavorOption(); usesFlavorOption();
argParser.addFlag('uninstall-only', argParser.addFlag('uninstall-only',
......
...@@ -19,6 +19,7 @@ class LogsCommand extends FlutterCommand { ...@@ -19,6 +19,7 @@ class LogsCommand extends FlutterCommand {
help: 'Clear log history before reading from logs.', help: 'Clear log history before reading from logs.',
); );
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
} }
@override @override
......
...@@ -177,6 +177,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -177,6 +177,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
addNullSafetyModeOptions(hide: !verboseHelp); addNullSafetyModeOptions(hide: !verboseHelp);
usesDeviceUserOption(); usesDeviceUserOption();
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
addDdsOptions(verboseHelp: verboseHelp); addDdsOptions(verboseHelp: verboseHelp);
addDevToolsOptions(verboseHelp: verboseHelp); addDevToolsOptions(verboseHelp: verboseHelp);
addServeObservatoryOptions(verboseHelp: verboseHelp); addServeObservatoryOptions(verboseHelp: verboseHelp);
......
...@@ -52,6 +52,7 @@ class ScreenshotCommand extends FlutterCommand { ...@@ -52,6 +52,7 @@ class ScreenshotCommand extends FlutterCommand {
defaultsTo: _kDeviceType, defaultsTo: _kDeviceType,
); );
usesDeviceTimeoutOption(); usesDeviceTimeoutOption();
usesDeviceConnectionOption();
} }
final FileSystem fs; final FileSystem fs;
......
...@@ -112,6 +112,7 @@ class FlutterOptions { ...@@ -112,6 +112,7 @@ class FlutterOptions {
static const String kNullSafety = 'sound-null-safety'; static const String kNullSafety = 'sound-null-safety';
static const String kDeviceUser = 'device-user'; static const String kDeviceUser = 'device-user';
static const String kDeviceTimeout = 'device-timeout'; static const String kDeviceTimeout = 'device-timeout';
static const String kDeviceConnection = 'device-connection';
static const String kAnalyzeSize = 'analyze-size'; static const String kAnalyzeSize = 'analyze-size';
static const String kCodeSizeDirectory = 'code-size-directory'; static const String kCodeSizeDirectory = 'code-size-directory';
static const String kNullAssertions = 'null-assertions'; static const String kNullAssertions = 'null-assertions';
...@@ -694,6 +695,19 @@ abstract class FlutterCommand extends Command<void> { ...@@ -694,6 +695,19 @@ abstract class FlutterCommand extends Command<void> {
); );
} }
void usesDeviceConnectionOption() {
argParser.addOption(FlutterOptions.kDeviceConnection,
defaultsTo: 'both',
help: 'Discover devices based on connection type.',
allowed: <String>['attached', 'wireless', 'both'],
allowedHelp: <String, String>{
'both': 'Searches for both attached and wireless devices.',
'attached': 'Only searches for devices connected by USB or built-in (such as simulators/emulators, MacOS/Windows, Chrome)',
'wireless': 'Only searches for devices connected wirelessly. Discovering wireless devices may take longer.'
},
);
}
void usesApplicationBinaryOption() { void usesApplicationBinaryOption() {
argParser.addOption( argParser.addOption(
FlutterOptions.kUseApplicationBinary, FlutterOptions.kUseApplicationBinary,
...@@ -722,10 +736,24 @@ abstract class FlutterCommand extends Command<void> { ...@@ -722,10 +736,24 @@ abstract class FlutterCommand extends Command<void> {
return null; return null;
}(); }();
DeviceConnectionInterface? get deviceConnectionInterface {
if ((argResults?.options.contains(FlutterOptions.kDeviceConnection) ?? false)
&& (argResults?.wasParsed(FlutterOptions.kDeviceConnection) ?? false)) {
final String? connectionType = stringArg(FlutterOptions.kDeviceConnection);
if (connectionType == 'attached') {
return DeviceConnectionInterface.attached;
} else if (connectionType == 'wireless') {
return DeviceConnectionInterface.wireless;
}
}
return null;
}
late final TargetDevices _targetDevices = TargetDevices( late final TargetDevices _targetDevices = TargetDevices(
platform: globals.platform, platform: globals.platform,
deviceManager: globals.deviceManager!, deviceManager: globals.deviceManager!,
logger: globals.logger, logger: globals.logger,
deviceConnectionInterface: deviceConnectionInterface,
); );
void addBuildModeFlags({ void addBuildModeFlags({
......
...@@ -31,31 +31,46 @@ class TargetDevices { ...@@ -31,31 +31,46 @@ class TargetDevices {
required Platform platform, required Platform platform,
required DeviceManager deviceManager, required DeviceManager deviceManager,
required Logger logger, required Logger logger,
DeviceConnectionInterface? deviceConnectionInterface,
}) { }) {
if (platform.isMacOS) { if (platform.isMacOS) {
return TargetDevicesWithExtendedWirelessDeviceDiscovery( return TargetDevicesWithExtendedWirelessDeviceDiscovery(
deviceManager: deviceManager, deviceManager: deviceManager,
logger: logger, logger: logger,
deviceConnectionInterface: deviceConnectionInterface,
); );
} }
return TargetDevices._private( return TargetDevices._private(
deviceManager: deviceManager, deviceManager: deviceManager,
logger: logger, logger: logger,
deviceConnectionInterface: deviceConnectionInterface,
); );
} }
TargetDevices._private({ TargetDevices._private({
required DeviceManager deviceManager, required DeviceManager deviceManager,
required Logger logger, required Logger logger,
required this.deviceConnectionInterface,
}) : _deviceManager = deviceManager, }) : _deviceManager = deviceManager,
_logger = logger; _logger = logger;
final DeviceManager _deviceManager; final DeviceManager _deviceManager;
final Logger _logger; final Logger _logger;
final DeviceConnectionInterface? deviceConnectionInterface;
bool get _includeAttachedDevices =>
deviceConnectionInterface == null ||
deviceConnectionInterface == DeviceConnectionInterface.attached;
bool get _includeWirelessDevices =>
deviceConnectionInterface == null ||
deviceConnectionInterface == DeviceConnectionInterface.wireless;
Future<List<Device>> _getAttachedDevices({ Future<List<Device>> _getAttachedDevices({
DeviceDiscoverySupportFilter? supportFilter, DeviceDiscoverySupportFilter? supportFilter,
}) async { }) async {
if (!_includeAttachedDevices) {
return <Device>[];
}
return _deviceManager.getDevices( return _deviceManager.getDevices(
filter: DeviceDiscoveryFilter( filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.attached, deviceConnectionInterface: DeviceConnectionInterface.attached,
...@@ -67,6 +82,9 @@ class TargetDevices { ...@@ -67,6 +82,9 @@ class TargetDevices {
Future<List<Device>> _getWirelessDevices({ Future<List<Device>> _getWirelessDevices({
DeviceDiscoverySupportFilter? supportFilter, DeviceDiscoverySupportFilter? supportFilter,
}) async { }) async {
if (!_includeWirelessDevices) {
return <Device>[];
}
return _deviceManager.getDevices( return _deviceManager.getDevices(
filter: DeviceDiscoveryFilter( filter: DeviceDiscoveryFilter(
deviceConnectionInterface: DeviceConnectionInterface.wireless, deviceConnectionInterface: DeviceConnectionInterface.wireless,
...@@ -85,6 +103,7 @@ class TargetDevices { ...@@ -85,6 +103,7 @@ class TargetDevices {
supportFilter: _deviceManager.deviceSupportFilter( supportFilter: _deviceManager.deviceSupportFilter(
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject, includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
), ),
deviceConnectionInterface: deviceConnectionInterface,
), ),
); );
} }
...@@ -166,7 +185,11 @@ class TargetDevices { ...@@ -166,7 +185,11 @@ class TargetDevices {
/// unsupported devices found. /// unsupported devices found.
Future<List<Device>?> _handleNoDevices() async { Future<List<Device>?> _handleNoDevices() async {
// Get connected devices from cache, including unsupported ones. // Get connected devices from cache, including unsupported ones.
final List<Device> unsupportedDevices = await _deviceManager.getAllDevices(); final List<Device> unsupportedDevices = await _deviceManager.getAllDevices(
filter: DeviceDiscoveryFilter(
deviceConnectionInterface: deviceConnectionInterface,
)
);
if (_deviceManager.hasSpecifiedDeviceId) { if (_deviceManager.hasSpecifiedDeviceId) {
_logger.printStatus( _logger.printStatus(
...@@ -344,6 +367,7 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices { ...@@ -344,6 +367,7 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices {
TargetDevicesWithExtendedWirelessDeviceDiscovery({ TargetDevicesWithExtendedWirelessDeviceDiscovery({
required super.deviceManager, required super.deviceManager,
required super.logger, required super.logger,
super.deviceConnectionInterface,
}) : super._private(); }) : super._private();
Future<void>? _wirelessDevicesRefresh; Future<void>? _wirelessDevicesRefresh;
...@@ -358,7 +382,7 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices { ...@@ -358,7 +382,7 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices {
void startExtendedWirelessDeviceDiscovery({ void startExtendedWirelessDeviceDiscovery({
Duration? deviceDiscoveryTimeout, Duration? deviceDiscoveryTimeout,
}) { }) {
if (deviceDiscoveryTimeout == null) { if (deviceDiscoveryTimeout == null && _includeWirelessDevices) {
_wirelessDevicesRefresh ??= _deviceManager.refreshExtendedWirelessDeviceDiscoverers( _wirelessDevicesRefresh ??= _deviceManager.refreshExtendedWirelessDeviceDiscoverers(
timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout, timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout,
); );
...@@ -369,6 +393,9 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices { ...@@ -369,6 +393,9 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices {
Future<List<Device>> _getRefreshedWirelessDevices({ Future<List<Device>> _getRefreshedWirelessDevices({
bool includeDevicesUnsupportedByProject = false, bool includeDevicesUnsupportedByProject = false,
}) async { }) async {
if (!_includeWirelessDevices) {
return <Device>[];
}
startExtendedWirelessDeviceDiscovery(); startExtendedWirelessDeviceDiscovery();
return () async { return () async {
await _wirelessDevicesRefresh; await _wirelessDevicesRefresh;
...@@ -428,9 +455,10 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices { ...@@ -428,9 +455,10 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices {
return null; return null;
} }
// When a user defines the timeout, use the super function that does not do // When a user defines the timeout or filters to only attached devices,
// longer wireless device discovery and does not wait for devices to connect. // use the super function that does not do longer wireless device
if (deviceDiscoveryTimeout != null) { // discovery and does not wait for devices to connect.
if (deviceDiscoveryTimeout != null || deviceConnectionInterface == DeviceConnectionInterface.attached) {
return super.findAllTargetDevices( return super.findAllTargetDevices(
deviceDiscoveryTimeout: deviceDiscoveryTimeout, deviceDiscoveryTimeout: deviceDiscoveryTimeout,
includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject, includeDevicesUnsupportedByProject: includeDevicesUnsupportedByProject,
...@@ -497,7 +525,11 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices { ...@@ -497,7 +525,11 @@ class TargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices {
List<Device> attachedDevices, List<Device> attachedDevices,
Future<List<Device>> futureWirelessDevices, Future<List<Device>> futureWirelessDevices,
) async { ) async {
if (_includeAttachedDevices) {
_logger.printStatus(_noAttachedCheckForWireless); _logger.printStatus(_noAttachedCheckForWireless);
} else {
_logger.printStatus(_checkingForWirelessDevicesMessage);
}
final List<Device> wirelessDevices = await futureWirelessDevices; final List<Device> wirelessDevices = await futureWirelessDevices;
final List<Device> allDevices = attachedDevices + wirelessDevices; final List<Device> allDevices = attachedDevices + wirelessDevices;
......
...@@ -116,7 +116,8 @@ If you expected your device to be detected, please run "flutter doctor" to diagn ...@@ -116,7 +116,8 @@ If you expected your device to be detected, please run "flutter doctor" to diagn
Platform: () => platform, Platform: () => platform,
}); });
testUsingContext('Outputs parsable JSON with --machine flag', () async { group('with --machine flag', () {
testUsingContext('Outputs parsable JSON', () async {
final DevicesCommand command = DevicesCommand(); final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine']); await createTestCommandRunner(command).run(<String>['devices', '--machine']);
expect( expect(
...@@ -135,6 +136,44 @@ If you expected your device to be detected, please run "flutter doctor" to diagn ...@@ -135,6 +136,44 @@ If you expected your device to be detected, please run "flutter doctor" to diagn
Platform: () => platform, Platform: () => platform,
}); });
group('when deviceConnectionInterface', () {
testUsingContext('filtered to attached', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine', '--device-connection', 'attached']);
expect(
json.decode(testLogger.statusText),
<Map<String, Object>>[
fakeDevices[0].json,
fakeDevices[1].json,
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
testUsingContext('filtered to wireless', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine', '--device-connection', 'wireless']);
expect(
json.decode(testLogger.statusText),
<Map<String, Object>>[
fakeDevices[2].json,
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
});
});
testUsingContext('available devices and diagnostics', () async { testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand(); final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']); await createTestCommandRunner(command).run(<String>['devices']);
...@@ -155,6 +194,41 @@ wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2 ...@@ -155,6 +194,41 @@ wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform, Platform: () => platform,
}); });
group('when deviceConnectionInterface', () {
testUsingContext('filtered to attached', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--device-connection', 'attached']);
expect(testLogger.statusText, '''
2 connected devices:
ephemeral (mobile) • ephemeral • android-arm • Test SDK (1.2.3) (emulator)
webby (mobile) • webby • web-javascript • Web SDK (1.2.4) (emulator)
• Cannot connect to device ABC
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
testUsingContext('filtered to wireless', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--device-connection', 'wireless']);
expect(testLogger.statusText, '''
1 wirelessly connected device:
wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2.3) (emulator)
• Cannot connect to device ABC
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
});
}); });
group('when includes only attached devices', () { group('when includes only attached devices', () {
...@@ -225,7 +299,8 @@ wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2 ...@@ -225,7 +299,8 @@ wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2
Platform: () => platform, Platform: () => platform,
}); });
testUsingContext('no error when no connected devices', () async { group('when no connected devices', () {
testUsingContext('no error', () async {
final DevicesCommand command = DevicesCommand(); final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']); await createTestCommandRunner(command).run(<String>['devices']);
expect( expect(
...@@ -249,6 +324,43 @@ If you expected your device to be detected, please run "flutter doctor" to diagn ...@@ -249,6 +324,43 @@ If you expected your device to be detected, please run "flutter doctor" to diagn
Platform: () => platform, Platform: () => platform,
}); });
group('when deviceConnectionInterface', () {
testUsingContext('filtered to attached', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--device-connection', 'attached']);
expect(testLogger.statusText, '''
No devices detected.
Run "flutter emulators" to list and start any available device emulators.
If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. You may also try increasing the time to wait for connected devices with the --device-timeout flag. Visit https://flutter.dev/setup/ for troubleshooting tips.
''');
}, overrides: <Type, Generator>{
DeviceManager: () => NoDevicesManager(),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
testUsingContext('filtered to wireless', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--device-connection', 'wireless']);
expect(testLogger.statusText, '''
Checking for wireless devices...
No devices detected.
Run "flutter emulators" to list and start any available device emulators.
If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. You may also try increasing the time to wait for connected devices with the --device-timeout flag. Visit https://flutter.dev/setup/ for troubleshooting tips.
''');
}, overrides: <Type, Generator>{
DeviceManager: () => NoDevicesManager(),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
});
});
group('when includes both attached and wireless devices', () { group('when includes both attached and wireless devices', () {
List<FakeDeviceJsonData>? deviceList; List<FakeDeviceJsonData>? deviceList;
setUp(() { setUp(() {
...@@ -273,7 +385,8 @@ If you expected your device to be detected, please run "flutter doctor" to diagn ...@@ -273,7 +385,8 @@ If you expected your device to be detected, please run "flutter doctor" to diagn
Platform: () => platform, Platform: () => platform,
}); });
testUsingContext('Outputs parsable JSON with --machine flag', () async { group('with --machine flag', () {
testUsingContext('Outputs parsable JSON', () async {
final DevicesCommand command = DevicesCommand(); final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine']); await createTestCommandRunner(command).run(<String>['devices', '--machine']);
expect( expect(
...@@ -293,6 +406,45 @@ If you expected your device to be detected, please run "flutter doctor" to diagn ...@@ -293,6 +406,45 @@ If you expected your device to be detected, please run "flutter doctor" to diagn
Platform: () => platform, Platform: () => platform,
}); });
group('when deviceConnectionInterface', () {
testUsingContext('filtered to attached', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine', '--device-connection', 'attached']);
expect(
json.decode(testLogger.statusText),
<Map<String, Object>>[
fakeDevices[0].json,
fakeDevices[1].json,
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
testUsingContext('filtered to wireless', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--machine', '--device-connection', 'wireless']);
expect(
json.decode(testLogger.statusText),
<Map<String, Object>>[
fakeDevices[2].json,
fakeDevices[3].json,
],
);
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Cache: () => cache,
Artifacts: () => Artifacts.test(),
Platform: () => platform,
});
});
});
testUsingContext('available devices and diagnostics', () async { testUsingContext('available devices and diagnostics', () async {
final DevicesCommand command = DevicesCommand(); final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices']); await createTestCommandRunner(command).run(<String>['devices']);
...@@ -401,6 +553,25 @@ wireless ios (mobile) • wireless-ios • ios • iOS 16 (simul ...@@ -401,6 +553,25 @@ wireless ios (mobile) • wireless-ios • ios • iOS 16 (simul
Platform: () => platform, Platform: () => platform,
Logger: () => fakeLogger, Logger: () => fakeLogger,
}); });
testUsingContext('when deviceConnectionInterface filtered to wireless', () async {
final DevicesCommand command = DevicesCommand();
await createTestCommandRunner(command).run(<String>['devices', '--device-connection', 'wireless']);
expect(testLogger.statusText, '''
Checking for wireless devices...
2 wirelessly connected devices:
wireless android (mobile) • wireless-android • android-arm • Test SDK (1.2.3) (emulator)
wireless ios (mobile) • wireless-ios • ios • iOS 16 (simulator)
• Cannot connect to device ABC
''');
}, overrides: <Type, Generator>{
DeviceManager: () => _FakeDeviceManager(devices: deviceList),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
}); });
}); });
......
...@@ -217,6 +217,48 @@ If you would like your app to run on android, consider running `flutter create . ...@@ -217,6 +217,48 @@ If you would like your app to run on android, consider running `flutter create .
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0); expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1); expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
}); });
group('when deviceConnectionInterface does not match', () {
testUsingContext('filter of wireless', () async {
deviceManager.androidDiscoverer.deviceList = <Device>[attachedAndroidDevice1];
final TargetDevices targetDevices = TargetDevices(
platform: platform,
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.wireless,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
No supported devices connected.
'''));
expect(devices, isNull);
expect(deviceManager.androidDiscoverer.devicesCalled, 2);
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
});
testUsingContext('filter of attached', () async {
deviceManager.androidDiscoverer.deviceList = <Device>[wirelessAndroidDevice1];
final TargetDevices targetDevices = TargetDevices(
platform: platform,
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.attached,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
No supported devices connected.
'''));
expect(devices, isNull);
expect(deviceManager.androidDiscoverer.devicesCalled, 2);
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
});
});
}); });
group('with hasSpecifiedDeviceId', () { group('with hasSpecifiedDeviceId', () {
...@@ -272,6 +314,58 @@ target-device (mobile) • xxx • android • Android 10 (unsupported) ...@@ -272,6 +314,58 @@ target-device (mobile) • xxx • android • Android 10 (unsupported)
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0); expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1); expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
}); });
group('when deviceConnectionInterface does not match', () {
testUsingContext('filter of wireless', () async {
final FakeDevice device1 = FakeDevice(deviceName: 'not-a-match');
final FakeDevice device2 = FakeDevice.wireless(deviceName: 'not-a-match-2');
deviceManager.androidDiscoverer.deviceList = <Device>[exactMatchAndroidDevice, device1, device2];
final TargetDevices targetDevices = TargetDevices(
platform: platform,
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.wireless,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
No supported devices found with name or id matching 'target-device'.
The following devices were found:
not-a-match-2 (mobile) • xxx • android • Android 10
'''));
expect(devices, isNull);
expect(deviceManager.androidDiscoverer.devicesCalled, 3);
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
});
testUsingContext('filter of attached', () async {
final FakeDevice device1 = FakeDevice(deviceName: 'not-a-match');
final FakeDevice device2 = FakeDevice.wireless(deviceName: 'not-a-match-2');
deviceManager.androidDiscoverer.deviceList = <Device>[exactMatchWirelessAndroidDevice, device1, device2];
final TargetDevices targetDevices = TargetDevices(
platform: platform,
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.attached,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
No supported devices found with name or id matching 'target-device'.
The following devices were found:
not-a-match (mobile) • xxx • android • Android 10
'''));
expect(devices, isNull);
expect(deviceManager.androidDiscoverer.devicesCalled, 3);
expect(deviceManager.androidDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.androidDiscoverer.numberOfTimesPolled, 1);
});
});
}); });
group('with hasSpecifiedAllDevices', () { group('with hasSpecifiedAllDevices', () {
...@@ -944,6 +1038,28 @@ Unable to locate a development device; please run 'flutter doctor' for informati ...@@ -944,6 +1038,28 @@ Unable to locate a development device; please run 'flutter doctor' for informati
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 1); expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 1);
}); });
testUsingContext('ensure no refresh when deviceConnectionInterface is attached', () async {
final BufferLogger logger = BufferLogger.test();
final TestDeviceManager deviceManager = TestDeviceManager(
logger: logger,
platform: platform,
);
deviceManager.iosDiscoverer.deviceList = <Device>[attachedIOSDevice1];
final TargetDevicesWithExtendedWirelessDeviceDiscovery targetDevices = TargetDevicesWithExtendedWirelessDeviceDiscovery(
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.attached,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals(''));
expect(devices, <Device>[attachedIOSDevice1]);
expect(deviceManager.iosDiscoverer.devicesCalled, 1);
expect(deviceManager.iosDiscoverer.discoverDevicesCalled, 0);
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 1);
});
testUsingContext('ensure unsupported for projects are included when includeDevicesUnsupportedByProject is true', () async { testUsingContext('ensure unsupported for projects are included when includeDevicesUnsupportedByProject is true', () async {
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final TestDeviceManager deviceManager = TestDeviceManager( final TestDeviceManager deviceManager = TestDeviceManager(
...@@ -1055,6 +1171,30 @@ No supported devices connected. ...@@ -1055,6 +1171,30 @@ No supported devices connected.
expect(deviceManager.iosDiscoverer.discoverDevicesCalled, 1); expect(deviceManager.iosDiscoverer.discoverDevicesCalled, 1);
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 2); expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 2);
}); });
group('when deviceConnectionInterface does not match', () {
testUsingContext('filter of wireless', () async {
deviceManager.iosDiscoverer.deviceList = <Device>[attachedIOSDevice1];
deviceManager.iosDiscoverer.refreshDeviceList = <Device>[attachedIOSDevice1];
final TestTargetDevicesWithExtendedWirelessDeviceDiscovery targetDevices = TestTargetDevicesWithExtendedWirelessDeviceDiscovery(
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.wireless,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
Checking for wireless devices...
No supported devices connected.
'''));
expect(devices, isNull);
expect(deviceManager.iosDiscoverer.devicesCalled, 2);
expect(deviceManager.iosDiscoverer.discoverDevicesCalled, 1);
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 1);
});
});
}); });
group('with hasSpecifiedDeviceId', () { group('with hasSpecifiedDeviceId', () {
...@@ -1121,6 +1261,35 @@ target-device (mobile) • xxx • ios • iOS 16 (unsupported) ...@@ -1121,6 +1261,35 @@ target-device (mobile) • xxx • ios • iOS 16 (unsupported)
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 2); expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 2);
expect(deviceManager.iosDiscoverer.xcdevice.waitedForDeviceToConnect, isFalse); expect(deviceManager.iosDiscoverer.xcdevice.waitedForDeviceToConnect, isFalse);
}); });
group('when deviceConnectionInterface does not match', () {
testUsingContext('filter of wireless', () async {
final FakeIOSDevice device1 = FakeIOSDevice.notConnectedWireless(deviceName: 'not-a-match');
final FakeIOSDevice device1Connected = FakeIOSDevice.connectedWireless(deviceName: 'not-a-match');
deviceManager.iosDiscoverer.deviceList = <Device>[exactMatchAttachedIOSDevice, device1];
deviceManager.iosDiscoverer.refreshDeviceList = <Device>[exactMatchAttachedIOSDevice, device1Connected];
final TestTargetDevicesWithExtendedWirelessDeviceDiscovery targetDevices = TestTargetDevicesWithExtendedWirelessDeviceDiscovery(
deviceManager: deviceManager,
logger: logger,
deviceConnectionInterface: DeviceConnectionInterface.wireless,
);
final List<Device>? devices = await targetDevices.findAllTargetDevices();
expect(logger.statusText, equals('''
Checking for wireless devices...
No supported devices found with name or id matching 'target-device'.
The following devices were found:
not-a-match (mobile) • xxx • ios • iOS 16
'''));
expect(devices, isNull);
expect(deviceManager.iosDiscoverer.devicesCalled, 3);
expect(deviceManager.iosDiscoverer.discoverDevicesCalled, 1);
expect(deviceManager.iosDiscoverer.numberOfTimesPolled, 2);
});
});
}); });
group('with hasSpecifiedAllDevices', () { group('with hasSpecifiedAllDevices', () {
...@@ -2223,6 +2392,7 @@ class TestTargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices ...@@ -2223,6 +2392,7 @@ class TestTargetDevicesWithExtendedWirelessDeviceDiscovery extends TargetDevices
TestTargetDevicesWithExtendedWirelessDeviceDiscovery({ TestTargetDevicesWithExtendedWirelessDeviceDiscovery({
required super.deviceManager, required super.deviceManager,
required super.logger, required super.logger,
super.deviceConnectionInterface,
}) : _deviceSelection = TestTargetDeviceSelection(logger); }) : _deviceSelection = TestTargetDeviceSelection(logger);
final TestTargetDeviceSelection _deviceSelection; final TestTargetDeviceSelection _deviceSelection;
......
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