Add --device-timeout flag to device-related commands (#64834)
diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index 7272767..0cde25a 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart
@@ -102,6 +102,7 @@ ); usesTrackWidgetCreation(verboseHelp: verboseHelp); addDdsOptions(verboseHelp: verboseHelp); + usesDeviceTimeoutOption(); hotRunnerFactory ??= HotRunnerFactory(); }
diff --git a/packages/flutter_tools/lib/src/commands/devices.dart b/packages/flutter_tools/lib/src/commands/devices.dart index 53c9eea..b513539 100644 --- a/packages/flutter_tools/lib/src/commands/devices.dart +++ b/packages/flutter_tools/lib/src/commands/devices.dart
@@ -22,8 +22,9 @@ 'timeout', abbr: 't', defaultsTo: null, - help: 'Time in seconds to wait for devices to attach. Longer timeouts may be necessary for networked devices.' + help: '(deprecated) Use --device-timeout instead', ); + usesDeviceTimeoutOption(); } @override @@ -32,20 +33,25 @@ @override final String description = 'List all connected devices.'; - Duration get timeout { - if (argResults['timeout'] == null) { - return null; - } - if (_timeout == null) { + @override + Duration get deviceDiscoveryTimeout { + if (argResults['timeout'] != null) { final int timeoutSeconds = int.tryParse(stringArg('timeout')); if (timeoutSeconds == null) { throwToolExit( 'Could not parse -t/--timeout argument. It must be an integer.'); } - _timeout = Duration(seconds: timeoutSeconds); + return Duration(seconds: timeoutSeconds); } - return _timeout; + return super.deviceDiscoveryTimeout; } - Duration _timeout; + + @override + Future<void> validateCommand() { + if (argResults['timeout'] != null) { + globals.printError('--timeout has been deprecated, use --${FlutterOptions.kDeviceTimeout} instead'); + } + return super.validateCommand(); + } @override Future<FlutterCommandResult> runCommand() async { @@ -56,7 +62,7 @@ exitCode: 1); } - final List<Device> devices = await globals.deviceManager.refreshAllConnectedDevices(timeout: timeout); + final List<Device> devices = await globals.deviceManager.refreshAllConnectedDevices(timeout: deviceDiscoveryTimeout); if (boolArg('machine')) { await printDevicesAsJson(devices); @@ -68,8 +74,8 @@ status.writeln('Run "flutter emulators" to list and start any available device emulators.'); status.writeln(); status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. '); - if (timeout == null) { - status.write('You may also try increasing the time to wait for connected devices with the --timeout flag. '); + if (deviceDiscoveryTimeout == null) { + status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. '); } status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');
diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 0980e68..1f9772e 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart
@@ -146,7 +146,7 @@ @override Future<void> validateCommand() async { if (userIdentifier != null) { - final Device device = await findTargetDevice(); + final Device device = await findTargetDevice(timeout: deviceDiscoveryTimeout); if (device is! AndroidDevice) { throwToolExit('--${FlutterOptions.kDeviceUser} is only supported for Android'); } @@ -161,7 +161,7 @@ throwToolExit(null); } - _device = await findTargetDevice(); + _device = await findTargetDevice(timeout: deviceDiscoveryTimeout); if (device == null) { throwToolExit(null); } @@ -388,9 +388,9 @@ } } -Future<Device> findTargetDevice() async { +Future<Device> findTargetDevice({ @required Duration timeout }) async { final DeviceManager deviceManager = globals.deviceManager; - final List<Device> devices = await deviceManager.findTargetDevices(FlutterProject.current()); + final List<Device> devices = await deviceManager.findTargetDevices(FlutterProject.current(), timeout: timeout); if (deviceManager.hasSpecifiedDeviceId) { if (devices.isEmpty) {
diff --git a/packages/flutter_tools/lib/src/commands/install.dart b/packages/flutter_tools/lib/src/commands/install.dart index 8228cbf..62fd7cd 100644 --- a/packages/flutter_tools/lib/src/commands/install.dart +++ b/packages/flutter_tools/lib/src/commands/install.dart
@@ -16,6 +16,7 @@ InstallCommand() { requiresPubspecYaml(); usesDeviceUserOption(); + usesDeviceTimeoutOption(); argParser.addFlag('uninstall-only', negatable: true, defaultsTo: false,
diff --git a/packages/flutter_tools/lib/src/commands/logs.dart b/packages/flutter_tools/lib/src/commands/logs.dart index 5b9b9cb..5305e14 100644 --- a/packages/flutter_tools/lib/src/commands/logs.dart +++ b/packages/flutter_tools/lib/src/commands/logs.dart
@@ -18,6 +18,7 @@ abbr: 'c', help: 'Clear log history before reading from logs.', ); + usesDeviceTimeoutOption(); } @override
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index fd5b739..b70a1a7 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -75,6 +75,7 @@ usesTrackWidgetCreation(verboseHelp: verboseHelp); addNullSafetyModeOptions(hide: !verboseHelp); usesDeviceUserOption(); + usesDeviceTimeoutOption(); } bool get traceStartup => boolArg('trace-startup');
diff --git a/packages/flutter_tools/lib/src/commands/screenshot.dart b/packages/flutter_tools/lib/src/commands/screenshot.dart index 3c32de7..566affd 100644 --- a/packages/flutter_tools/lib/src/commands/screenshot.dart +++ b/packages/flutter_tools/lib/src/commands/screenshot.dart
@@ -51,6 +51,7 @@ }, defaultsTo: _kDeviceType, ); + usesDeviceTimeoutOption(); } @override
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 2a16f8e..84d0a05 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart
@@ -209,7 +209,12 @@ /// * 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. - Future<List<Device>> findTargetDevices(FlutterProject flutterProject) async { + Future<List<Device>> findTargetDevices(FlutterProject flutterProject, { Duration timeout }) async { + if (timeout != null) { + // Reset the cache with the specified timeout. + await refreshAllConnectedDevices(timeout: timeout); + } + List<Device> devices = await getDevices(); // Always remove web and fuchsia devices from `--all`. This setting
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index e42548b..8fa2413 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -113,6 +113,7 @@ static const String kPerformanceMeasurementFile = 'performance-measurement-file'; static const String kNullSafety = 'sound-null-safety'; static const String kDeviceUser = 'device-user'; + static const String kDeviceTimeout = 'device-timeout'; static const String kAnalyzeSize = 'analyze-size'; static const String kNullAssertions = 'null-assertions'; } @@ -404,6 +405,28 @@ valueHelp: '10'); } + void usesDeviceTimeoutOption() { + argParser.addOption( + FlutterOptions.kDeviceTimeout, + help: 'Time in seconds to wait for devices to attach. Longer timeouts may be necessary for networked devices.', + valueHelp: '10' + ); + } + + Duration get deviceDiscoveryTimeout { + if (_deviceDiscoveryTimeout == null + && argResults.options.contains(FlutterOptions.kDeviceTimeout) + && argResults.wasParsed(FlutterOptions.kDeviceTimeout)) { + final int timeoutSeconds = int.tryParse(stringArg(FlutterOptions.kDeviceTimeout)); + if (timeoutSeconds == null) { + throwToolExit( 'Could not parse --${FlutterOptions.kDeviceTimeout} argument. It must be an integer.'); + } + _deviceDiscoveryTimeout = Duration(seconds: timeoutSeconds); + } + return _deviceDiscoveryTimeout; + } + Duration _deviceDiscoveryTimeout; + void addBuildModeFlags({ bool defaultToRelease = true, bool verboseHelp = false, bool excludeDebug = false }) { // A release build must be the default if a debug build is not possible. assert(defaultToRelease || !excludeDebug); @@ -970,7 +993,7 @@ return null; } final DeviceManager deviceManager = globals.deviceManager; - List<Device> devices = await deviceManager.findTargetDevices(FlutterProject.current()); + List<Device> devices = await deviceManager.findTargetDevices(FlutterProject.current(), timeout: deviceDiscoveryTimeout); if (devices.isEmpty && deviceManager.hasSpecifiedDeviceId) { globals.printStatus(userMessages.flutterNoMatchingDevice(deviceManager.specifiedDeviceId));